Merge branch 'supernova'

This commit is contained in:
Thierry Crozat 2018-01-23 21:53:11 +00:00
commit 2db8fbcb9d
28 changed files with 14502 additions and 0 deletions

View File

@ -0,0 +1,196 @@
#include "create_supernova.h"
#include "gametext.h"
#include "file.h"
#include "po_parser.h"
// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
#ifdef main
#undef main
#endif // main
// List of languages to look for. To add new languages you only need to change the array below
// and add the supporting files:
// - 640x480 bitmap picture for the newpaper named 'img1-##.pbm' and 'img2-##.pbm'
// in pbm binary format (you can use gimp to generate those)
// - strings in a po file named 'strings-##.po' that uses CP850 encoding
const char *lang[] = {
"en",
NULL
};
void writeImage(File& outputFile, const char *name, const char* language) {
File imgFile;
char fileName[16];
sprintf(fileName, "%s-%s.pbm", name, language);
if (!imgFile.open(fileName, kFileReadMode)) {
printf("Cannot find image '%s' for language '%s'. This image will be skipped.\n", name, language);
return;
}
char str[256];
// Read header (and check we have a binary PBM file)
imgFile.readString(str, 256);
if (strcmp(str, "P4") != 0) {
imgFile.close();
printf("File '%s' doesn't seem to be a binary pbm file! This image will be skipped.\n", fileName);
return;
}
// Skip comments and then read and check size
do {
imgFile.readString(str, 256);
} while (str[0] == '#');
int w = 0, h = 0;
if (sscanf(str, "%d %d", &w, &h) != 2 || w != 640 || h != 480) {
imgFile.close();
printf("Binary pbm file '%s' doesn't have the expected size (expected: 640x480, read: %dx%d). This image will be skipped.\n", fileName, w, h);
return;
}
// Write block header in output file (4 bytes).
// We convert the image name to upper case.
for (int i = 0 ; i < 4 ; ++i) {
if (name[i] >= 97 && name[i] <= 122)
outputFile.writeByte(name[i] - 32);
else
outputFile.writeByte(name[i]);
}
// And write the language code on 4 bytes as well (padded with 0 if needed).
int languageLength = strlen(language);
for (int i = 0 ; i < 4 ; ++i) {
if (i < languageLength)
outputFile.writeByte(language[i]);
else
outputFile.writeByte(0);
}
// Write block size (640*480 / 8)
outputFile.writeLong(38400);
// Write all the bytes. We should have 38400 bytes (640 * 480 / 8)
// However we need to invert the bits has the engine expects 1 for the background and 0 for the text (black)
// but pbm uses 0 for white and 1 for black.
for (int i = 0 ; i < 38400 ; ++i) {
byte b = imgFile.readByte();
outputFile.writeByte(~b);
}
imgFile.close();
}
void writeGermanStrings(File& outputFile) {
// Write header and language
outputFile.write("TEXT", 4);
outputFile.write("de\0\0", 4);
// Reserve the size for the block size, but we will write it at the end once we know what it is.
uint32 blockSizePos = outputFile.pos();
uint32 blockSize = 0;
outputFile.writeLong(blockSize);
// Write all the strings
const char **s = &gameText[0];
while (*s) {
outputFile.writeString(*s);
blockSize += strlen(*s) + 1;
++s;
}
// Now write the block size and then go back to the end of the file.
outputFile.seek(blockSizePos, SEEK_SET);
outputFile.writeLong(blockSize);
outputFile.seek(0, SEEK_END);
}
void writeStrings(File& outputFile, const char* language) {
char fileName[16];
sprintf(fileName, "strings-%s.po", language);
PoMessageList* poList = parsePoFile(fileName);
if (!poList) {
printf("Cannot find strings file for language '%s'.\n", language);
return;
}
// Write block header
outputFile.write("TEXT", 4);
// And write the language code on 4 bytes as well (padded with 0 if needed).
int languageLength = strlen(language);
for (int i = 0 ; i < 4 ; ++i) {
if (i < languageLength)
outputFile.writeByte(language[i]);
else
outputFile.writeByte(0);
}
// Reserve the size for the block size, but we will write it at the end once we know what it is.
uint32 blockSizePos = outputFile.pos();
uint32 blockSize = 0;
outputFile.writeLong(blockSize);
// Write all the strings.
// If a string is not translated we use the German one.
const char **s = &gameText[0];
while (*s) {
const char* translation = poList->findTranslation(*s);
if (translation) {
outputFile.writeString(translation);
blockSize += strlen(translation) + 1;
} else {
outputFile.writeString(*s);
blockSize += strlen(*s) + 1;
}
++s;
}
delete poList;
// Now write the block size and then go back to the end of the file.
outputFile.seek(blockSizePos, SEEK_SET);
outputFile.writeLong(blockSize);
outputFile.seek(0, SEEK_END);
}
/**
* Main method
*/
int main(int argc, char *argv[]) {
File outputFile;
if (!outputFile.open("supernova.dat", kFileWriteMode)) {
printf("Cannot create file 'supernova.dat' in current directory.\n");
exit(0);
}
// The generated file is of the form:
// 3 bytes: 'MSN'
// 1 byte: version
// -- data blocks
// 4 bytes: header 'IMG1' and 'IMG2' for newspaper images (for file 1 and file 2 respectively),
// 'TEXT' for strings
// 4 bytes: language code ('en\0', 'de\0'- see common/language.cpp)
// 4 bytes: block size n (uint32)
// n bytes: data
// ---
// Header
outputFile.write("MSN", 3);
outputFile.writeByte(VERSION);
// German strings
writeGermanStrings(outputFile);
// Other languages
const char **l = &lang[0];
while(*l) {
writeImage(outputFile, "img1", *l);
writeImage(outputFile, "img2", *l);
writeStrings(outputFile, *l);
++l;
}
outputFile.close();
return 0;
}

View File

@ -0,0 +1,33 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* This is a utility for generating a data file for the supernova engine.
* It contains strings extracted from the original executable as well
* as translations and is required for the engine to work properly.
*/
#ifndef CREATE_SUPERNOVA_H
#define CREATE_SUPERNOVA_H
#define VERSION 1
#endif // CREATE_SUPERNOVA_H

View File

@ -0,0 +1,72 @@
#include "file.h"
bool File::open(const char *filename, AccessMode mode) {
f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb");
return (f != NULL);
}
void File::close() {
fclose(f);
f = NULL;
}
int File::seek(int32 offset, int whence) {
return fseek(f, offset, whence);
}
long File::read(void *buffer, int len) {
return fread(buffer, 1, len, f);
}
void File::write(const void *buffer, int len) {
fwrite(buffer, 1, len, f);
}
byte File::readByte() {
byte v;
read(&v, sizeof(byte));
return v;
}
uint16 File::readWord() {
uint16 v;
read(&v, sizeof(uint16));
return FROM_LE_16(v);
}
uint32 File::readLong() {
uint32 v;
read(&v, sizeof(uint32));
return FROM_LE_32(v);
}
void File::readString(char* string, int bufferLength) {
int i = 0;
while (i < bufferLength - 1 && fread(string + i, 1, 1, f) == 1) {
if (string[i] == '\n' || string[i] == 0)
break;
++ i;
}
string[i] = 0;
}
void File::writeByte(byte v) {
write(&v, sizeof(byte));
}
void File::writeWord(uint16 v) {
uint16 vTemp = TO_LE_16(v);
write(&vTemp, sizeof(uint16));
}
void File::writeLong(uint32 v) {
uint32 vTemp = TO_LE_32(v);
write(&vTemp, sizeof(uint32));
}
void File::writeString(const char *s) {
write(s, strlen(s) + 1);
}
uint32 File::pos() {
return ftell(f);
}

View File

@ -0,0 +1,59 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* This is a utility for generating a data file for the supernova engine.
* It contains strings extracted from the original executable as well
* as translations and is required for the engine to work properly.
*/
#ifndef FILE_H
#define FILE_H
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/endian.h"
enum AccessMode {
kFileReadMode = 1,
kFileWriteMode = 2
};
class File {
private:
FILE *f;
public:
bool open(const char *filename, AccessMode mode = kFileReadMode);
void close();
int seek(int32 offset, int whence = SEEK_SET);
uint32 pos();
long read(void *buffer, int len);
void write(const void *buffer, int len);
byte readByte();
uint16 readWord();
uint32 readLong();
void readString(char*, int bufferLength);
void writeByte(byte v);
void writeWord(uint16 v);
void writeLong(uint32 v);
void writeString(const char *s);
};
#endif // FILE_H

View File

@ -0,0 +1,823 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* This is a utility for generating a data file for the supernova engine.
* It contains strings extracted from the original executable as well
* as translations and is required for the engine to work properly.
*/
#ifndef GAMETEXT_H
#define GAMETEXT_H
#include <stddef.h>
// This file contains the strings in German and is encoded using CP850 encoding.
// Other language should be provided as po files also using the CP850 encoding.
// TODO: add the strings from the engine here, add an Id string in comment.
// And in the engine add a StringId enum with all the Ids = index in this array.
const char *gameText[] = {
// 0
"Gehe", // kStringCommandGo
"Schau", // kStringCommandLook
"Nimm", // kStringCommandTake
"\231ffne", // kStringCommandOpen
"Schlie\341e", // kStringCommandClose
// 5
"Dr\201cke", // kStringCommandPress
"Ziehe", // kStringCommandPull
"Benutze", // kStringCommandUse
"Rede", // kStringCommandTalk
"Gib", // kStringCommandGive
// 10
"Gehe zu ", // kStringStatusCommandGo
"Schau ", // kStringStatusCommandLook
"Nimm ", // kStringStatusCommandTake
"\231ffne ", // kStringStatusCommandOpen
"Schlie\341e ", // kStringStatusCommandClose
// 15
"Dr\201cke ", // kStringStatusCommandPress
"Ziehe ", // kStringStatusCommandPull
"Benutze ", // kStringStatusCommandUse
"Rede mit ", // kStringStatusCommandTalk
"Gib ", // kStringStatusCommandGive
// 20
"V2.02", // kStringTitleVersion
"Teil 1:", // kStringTitle1
"Das Schicksal", // kStringTitle2
"des Horst Hummel", // kStringTitle3
"^(C) 1994 Thomas und Steffen Dingel#", // kStringIntro1
// 25
"Story und Grafik:^ Thomas Dingel#", // kStringIntro2
"Programmierung:^ Steffen Dingel#", // kStringIntro3
"Musik:^ Bernd Hoffmann#", // kStringIntro4
"Getestet von ...#", // kStringIntro5
"^Matthias Neef#", // kStringIntro6
// 30
"^Sascha Otterbach#", // kStringIntro7
"^Thomas Mazzoni#", // kStringIntro8
"^Matthias Klein#", // kStringIntro9
"^Gerrit Rothmaier#", // kStringIntro10
"^Thomas Hassler#", // kStringIntro11
// 35
"^Rene Koch#", // kStringIntro12
"\233", // kStringIntro13
"Hmm, er scheint kaputt zu sein.", // kStringBroken
"Es ist nichts Besonderes daran.", // kStringDefaultDescription
"Das mu\341t du erst nehmen.", // kStringTakeMessage
// 40
"Keycard", // kStringKeycard
"Die Keycard f\224r deine Schr\204nke.", // kStringKeycardDescription
"Taschenmesser", // kStringKnife
"Es ist nicht mehr das sch\204rfste.", // kStringKnifeDescription
"Armbanduhr", // kStringWatch
// 45
"Discman", // kStringDiscman
"Es ist eine \"Mad Monkeys\"-CD darin.", // kStringDiscmanDescription
"Luke", // kStringHatch
"Knopf", // kStringButton
"Er geh\224rt zu der gro\341en Luke.", // kStringHatchButtonDescription
// 50
"Leiter", // kStringLadder
"Ausgang", // kStringExit
"Sie f\201hrt ins Cockpit.", // kStringCockpitHatchDescription
"Sie f\201hrt zur K\201che.", // kStringKitchenHatchDescription
"Sie f\201hrt zu den Tiefschlafkammern.", // kStringStasisHatchDescription
// 55
"Dies ist eine der Tiefschlafkammern.", // kStringStasisHatchDescription2
"Schlitz", // kStringSlot
"Es ist ein Keycard-Leser.", // kStringSlotDescription
"Gang", // kStringCorridor
"Computer", // kStringComputer
// 60
"ZWEIUNDVIERZIG", // kStringComputerPassword
"Instrumente", // kStringInstruments
"Hmm, sieht ziemlich kompliziert aus.", // kStringInstrumentsDescription1
"Monitor", // kStringMonitor
"Dieser Monitor sagt dir nichts.", // kStringMonitorDescription
// 65
"Bild", // kStringImage
"Herb!", // kStringGenericDescription1
"Toll!", // kStringGenericDescription2
"Genial!", // kStringGenericDescription3
"Es scheint noch nicht fertig zu sein.", // kStringGenericDescription4
// 70
"Magnete", // kStringMagnete
"Damit werden Sachen auf|dem Tisch festgehalten.", // kStringMagneteDescription
"Stift", // kStringPen
"Ein Kugelschreiber.", // kStringPenDescription
"Schrank", // kStringShelf
// 75
"Fach", // kStringCompartment
"Steckdose", // kStringSocket
"Toilette", // kStringToilet
"Pistole", // kStringPistol
"Es ist keine Munition drin.", // kStringPistolDescription
// 80
"B\201cher", // kStringBooks
"Lauter wissenschaftliche B\201cher.", // kStringBooksDescription
"Kabelrolle", // kStringSpool
"Da sind mindestens zwanzig Meter drauf.", // kStringSpoolDescription
"Buch", // kStringBook
// 85
"Unterw\204sche", // kStringUnderwear
"Ich habe keine Lust, in|der Unterw\204sche des|Commanders rumzuw\201hlen.", // kStringUnderwearDescription
"Kleider", // kStringClothes
"Krimskram", // kStringJunk
"Es ist nichts brauchbares dabei.", // kStringJunkDescription
// 90
"Ordner", // kStringFolders
"Darauf steht \"Dienstanweisungen|zur Mission Supernova\".|Es steht nichts wichtiges drin.", // kStringFoldersDescription
"Poster", // kStringPoster
"Ein Poster von \"Big Boss\".", // kStringPosterDescription1
"Ein Poster von \"Rock Desaster\".", // kStringPosterDescription2
// 95
"Box", // kStringSpeaker
"Schallplatte", // kStringRecord
"Die Platte ist von \"Big Boss\".", // kStringRecordDescription
"Schallplattenst\204nder", // kStringRecordStand
"Du hast jetzt keine Zeit, in|der Plattensammlung rumzust\224bern.", // kStringRecordStandDescription
// 100
"Plattenspieler", // kStringTurntable
"Sieht aus, als k\204me|er aus dem Museum.", // kStringTurntableDescription
"Leitung", // kStringWire
"Stecker", // kStringPlug
"Manche Leute haben schon|einen komischen Geschmack.", // kStringImageDescription1
// 105
"Zeichenger\204te", // kStringDrawingInstruments
"Auf dem Zettel sind lauter|unverst\204ndliche Skizzen und Berechnungen.|(Jedenfalls f\201r dich unverst\204ndlich.)", // kStringDrawingInstrumentsDescription
"Schachspiel", // kStringChessGame
"Es macht wohl Spa\341, an|der Decke Schach zu spielen.", // kStringChessGameDescription1
"Tennisschl\204ger", // kStringTennisRacket
// 110
"Fliegt Boris Becker auch mit?", // kStringTennisRacketDescription
"Tennisball", // kStringTennisBall
"Dein Magnetschachspiel. Schach war|schon immer deine Leidenschaft.", // kStringChessGameDescription2
"Bett", // kStringBed
"Das ist dein Bett. Toll, nicht wahr?", // kStringBedDescription
// 115
"Das ist eins deiner drei F\204cher.", // kStringCompartmentDescription
"Alben", // kStringAlbums
"Deine Briefmarkensammlung.", // kStringAlbumsDescription
"Seil", // kStringRope
"Es ist ungef\204hr 10 m lang und 4 cm dick.", // kStringRopeDescription
// 120
"Das ist dein Schrank.", // kStringShelfDescription
"Es sind Standard-Weltraum-Klamotten.", // kStringClothesDescription
"Str\201mpfe", // kStringSocks
"Es ist|\"Per Anhalter durch die Galaxis\"|von Douglas Adams.", // kStringBookHitchhiker
"Klo", // kStringBathroom
// 125
"Ein Klo mit Saugmechanismus.", // kStringBathroomDescription
"Dusche", // kStringShower
"Das ist eine Luke !!!", // kStringHatchDescription1
"Dies ist eine Luke !!!", // kStringHatchDescription2
"Helm", // kStringHelmet
// 130
"Es ist der Helm zum Raumanzug.", // kStringHelmetDescription
"Raumanzug", // kStringSuit
"Der einzige Raumanzug, den die|anderen hiergelassen haben ...", // kStringSuitDescription
"Versorgung", // kStringLifeSupport
"Es ist der Versorgungsteil zum Raumanzug.", // kStringLifeSupportDescription
// 135
"Schrott", // kStringScrap
"Da ist eine L\201sterklemme dran, die|noch ganz brauchbar aussieht.|Ich nehme sie mit.", // kStringScrapDescription1
"L\201sterklemme", // kStringTerminalStrip
"Junge, Junge! Die Explosion hat ein|ganz sch\224nes Durcheinander angerichtet.", // kStringScrapDescription2
"Reaktor", // kStringReactor
// 140
"Das war einmal der Reaktor.", // kStringReactorDescription
"D\201se", // kStringNozzle
"blauer K\201rbis", // kStringPumpkin
"Keine Ahnung, was das ist.", // kStringPumpkinDescription
"Landef\204hre", // kStringLandingModule
// 145
"Sie war eigentlich f\201r Bodenuntersuchungen|auf Arsano 3 gedacht.", // kStringLandingModuleDescription
"Sie f\201hrt nach drau\341en.", // kStringHatchDescription3
"Generator", // kStringGenerator
"Er versorgt das Raumschiff mit Strom.", // kStringGeneratorDescription
"Ein St\201ck Schrott.", // kStringScrapDescription3
// 150
"Es ist ein Sicherheitsknopf.|Er kann nur mit einem spitzen|Gegenstand gedr\201ckt werden.", // kSafetyButtonDescription
"Tastatur", // kStringKeyboard
"langes Kabel mit Stecker", // kStringGeneratorWire
"leere Kabelrolle", // kStringEmptySpool
"Keycard des Commanders", // kStringKeycard2
// 155
"Hey, das ist die Keycard des Commanders!|Er mu\341 sie bei dem \201berst\201rzten|Aufbruch verloren haben.", // kStringKeycard2Description
"Klappe", // kStringTrap
"Spannungmessger\204t", // kStringVoltmeter
"Klemme", // kStringClip
"Sie f\201hrt vom Generator zum Spannungmessger\204t.", // kStringWireDescription
// 160
"Stein", // kStringStone
"Loch", // kStringCaveOpening
"Es scheint eine H\224hle zu sein.", // kStringCaveOpeningDescription
"Hier bist du gerade hergekommen.", // kStringExitDescription
"H\224hle", // kStringCave
// 165
"Schild", // kStringSign
"Diese Schrift kannst du nicht lesen.", // kStringSignDescription
"Eingang", // kStringEntrance
"Stern", // kStringStar
"Raumschiff", // kStringSpaceshift
// 170
"Portier", // kStringPorter
"Du siehst doch selbst, wie er aussieht.", // kStringPorterDescription
"T\201r", // kStringDoor
"Kaugummi", // kStringChewingGum
"Gummib\204rchen", // kStringGummyBears
// 175
"Schokokugel", // kStringChocolateBall
"\232berraschungsei", // kStringEgg
"Lakritz", // kStringLiquorice
"Tablette", // kStringPill
"Die Plastikh\201lle zeigt einen|Mund mit einer Sprechblase. Was|darin steht, kannst du nicht lesen.", // kStringPillDescription
// 180
"Automat", // kStringVendingMachine
"Sieht aus wie ein Kaugummiautomat.", // kStringVendingMachineDescription
"Die Toiletten sind denen|auf der Erde sehr \204hnlich.", // kStringToiletDescription
"Treppe", // kStringStaircase
"M\201nzen", // kStringCoins
// 185
"Es sind seltsame|K\224pfe darauf abgebildet.", // kStringCoinsDescription
"Tablettenh\201lle", // kStringTabletPackage
"Darauf steht:\"Wenn Sie diese|Schrift jetzt lesen k\224nnen,|hat die Tablette gewirkt.\"", // kStringTabletPackageDescription
"Stuhl", // kStringChair
"Schuhe", // kStringShoes
// 190
"Wie ist der denn mit|Schuhen hier reingekommen?", // kStringShoesDescription
"Froschgesicht", // kStringFrogFace
"Gekritzel", // kStringScrible
"\"Mr Spock was here\"", // kStringScribleDescription
"Brieftasche", // kStringWallet
// 195
"Speisekarte", // kStringMenu
"\"Heute empfehlen wir:|Fonua Opra mit Ulk.\"", // kStringMenuDescription
"Tasse", // kStringCup
"Sie enth\204lt eine gr\201nliche Fl\201ssigkeit.", // kStringCupDescription
"10-Buckazoid-Schein", // kStringBill
// 200
"Nicht gerade sehr viel Geld.", // kStringBillDescription
"Keycard von Roger", // kStringKeycard3
"Anzeige", // kStringAnnouncement
"Hmm, seltsame Anzeigen.", // kStringAnnouncementDescription
"Roger W.", // kStringRoger
// 205
"Ufo", // kStringUfo
"Der Eingang scheint offen zu sein.", // kStringUfoDescription
"Tablett", // kStringTray
"Es ist irgendein Fra\341 und|etwas zu Trinken darauf.", // kStringTrayDescription
"Stange", // kStringLamp
// 210
"Es scheint eine Lampe zu sein.", // kStringLampDescription
"Augen", // kStringEyes
"Es ist nur ein Bild.", // kStringEyesDescription
"Sieht etwas anders aus als auf der Erde.", // kStringSocketDescription
"Metallblock", // kStringMetalBlock
// 215
"Er ist ziemlich schwer.", // kStringMetalBlockDescription
"Roboter", // kStringRobot
"Den hast du erledigt.", // kStringRobotDescription
"Tisch", // kStringTable
"Ein kleiner Metalltisch.", // kStringTableDescription
// 220
"Zellent\201r", // kStringCellDoor
"Hier warst du eingesperrt.", // kStringCellDoorDescription
"Laptop", // kStringLaptop
"Armbanduhr", // kStringWristwatch
"S\204ule", // kStringPillar
// 225
"Auf einem Schild an der T\201r steht \"Dr. Alab Hansi\".", // kStringDoorDescription1
"Auf einem Schild an der T\201r steht \"Saval Lun\".", // kStringDoorDescription2
"Auf einem Schild an der T\201r steht \"Prof. Dr. Ugnul Tschabb\".", // kStringDoorDescription3
"Auf einem Schild an der T\201r steht \"Alga Hurz Li\".", // kStringDoorDescription4
"Diese T\201r w\201rde ich lieber|nicht \224ffnen. Nach dem Schild zu|urteilen, ist jemand in dem Raum.", // kStringDontEnter
// 230
"Axacussaner", // kStringAxacussan
"Du m\201\341test ihn irgendwie ablenken.", // kStringAxacussanDescription
"Komisches Bild.", // kStringImageDescription2
"Karte", // kStringMastercard
"Darauf steht: \"Generalkarte\".", // kStringMastercardDescription
// 235
"Lampe", // kStringLamp2
"Seltsam!", // kStringGenericDescription5
"Geld", // kStringMoney
"Es sind 500 Xa.", // kStringMoneyDescription1
"Schlie\341fach", // kStringLocker
// 240
"Es hat ein elektronisches Zahlenschlo\341.", // kStringLockerDescription
"Brief", // kStringLetter
"W\201rfel", // kStringCube
"Sonderbar!", // kStringGenericDescription6
"Affenstark!", // kStringGenericDescription7
// 245
"Komisches Ding", // kStringStrangeThing
"Wundersam", // kStringGenericDescription8
"Es ist ein Axacussanerkopf auf dem Bild.", // kStringImageDescription3
"Pflanze", // kStringPlant
"Figur", // kStringStatue
// 250
"Stark!", // kStringStatueDescription
"Sie ist den Pflanzen auf der Erde sehr \204hnlich.", // kStringPlantDescription
"Er funktioniert nicht.", // kStringComputerDescription
"Graffiti", // kStringGraffiti
"Seltsamer B\201roschmuck!", // kStringGraffitiDescription
// 255
"Es sind 350 Xa.", // kStringMoneyDescription2
"Dschungel", // kStringJungle
"Lauter B\204ume.", // kStringJungleDescription
"^ E#N#D#E ...########", // kStringOutro1
"# ... des ersten Teils!########", // kStringOutro2
// 260
"#########", // kStringOutro3
"^Aber:#", // kStringOutro4
"Das Abenteuer geht weiter, ...##", // kStringOutro5
"... wenn Sie sich f\201r 30,- DM registrieren lassen!##", // kStringOutro6
"(Falls Sie das nicht schon l\204ngst getan haben.)##", // kStringOutro7
// 265
"In^ Teil 2 - Der Doppelg\204nger^ erwarten Sie:##", // kStringOutro8
"Knifflige Puzzles,##", // kStringOutro9
"noch mehr Grafik und Sound,##", // kStringOutro10
"ein perfekt geplanter Museumseinbruch,##", // kStringOutro11
"das Virtual-Reality-Spiel \"Indiana Joe\"##", // kStringOutro12
// 270
"und vieles mehr!##", // kStringOutro13
"\233", // kStringOutro14
"Leitung mit Stecker", // kStringWireAndPlug
"Leitung mit L\201sterklemme", // kStringWireAndClip
"langes Kabel mit Stecker", // kStringWireAndPlug2
// 275
"Darauf steht:|\"Treffpunkt Galactica\".", // kStringSignDescription2
"M\201nze", // kStringCoin
"Darauf steht:|\"Zutritt nur f\201r Personal\".", // kStringDoorDescription5
"Darauf steht:|\"Toilette\".", // kStringDoorDescription6
"Es ist die Keycard des Commanders.", // kStringKeycard2Description2
// 280
"Kabelrolle mit L\201sterklemme", // kSringSpoolAndClip
"Zwei Tage nach dem Start|im Cockpit der \"Supernova\" ...", // kStringIntroCutscene1
"Entferung von der Sonne: 1 500 000 km.|Gehen Sie auf 8000 hpm, Captain!", // kStringIntroCutscene2
"Ok, Sir.", // kStringIntroCutscene3
"Geschwindigkeit:", // kStringIntroCutscene4
// 285
"Zweitausend hpm", // kStringIntroCutscene5
"Dreitausend", // kStringIntroCutscene6
"Viertausend", // kStringIntroCutscene7
"F\201nftausend", // kStringIntroCutscene8
"Sechstausend", // kStringIntroCutscene9
// 290
"Siebentausend", // kStringIntroCutscene10
"Achttau...", // kStringIntroCutscene11
"Was war das?", // kStringIntroCutscene12
"Keine Ahnung, Sir.", // kStringIntroCutscene13
"Ingenieur an Commander, bitte kommen!", // kStringIntroCutscene14
// 295
"Was ist los?", // kStringIntroCutscene15
"Wir haben einen Druckabfall im Hauptantriebssystem, Sir.|Einen Moment, ich schaue sofort nach, woran es liegt.", // kStringIntroCutscene16
"Schei\341e, der Ionenantrieb ist explodiert!|Die Teile sind \201ber den ganzen|Maschinenraum verstreut.", // kStringIntroCutscene17
"Ach, du meine G\201te!|Gibt es irgendeine M\224glichkeit,|den Schaden schnell zu beheben?", // kStringIntroCutscene18
"Nein, Sir. Es sieht schlecht aus.", // kStringIntroCutscene19
// 300
"Hmm, die Erde zu alarmieren, w\201rde zu lange dauern.", // kStringIntroCutscene20
"Ich darf kein Risiko eingehen.|Captain, geben Sie sofort Alarm!", // kStringIntroCutscene21
"Commander an alle! Achtung, Achtung!|Begeben Sie sich sofort zum Notraumschiff!", // kStringIntroCutscene22
"Ich wiederhole:|Begeben Sie sich sofort zum Notraumschiff!", // kStringIntroCutscene23
"Captain, bereiten Sie alles f\201r den Start vor!|Wir m\201ssen zur\201ck zur Erde!", // kStringIntroCutscene24
// 305
"Eine Stunde sp\204ter ...", // kStringIntroCutscene25
"Die Besatzung hat die \"Supernova\" verlassen.", // kStringIntroCutscene26
"Das Schiff wird zwar in acht Jahren sein Ziel|erreichen, allerdings ohne Mannschaft.", // kStringIntroCutscene27
"Das ist das kl\204gliche Ende|der Mission Supernova.", // kStringIntroCutscene28
"Sie k\224nnen jetzt ihren Computer ausschalten.", // kStringIntroCutscene29
// 310
"Halt!", // kStringIntroCutscene30
"Warten Sie!", // kStringIntroCutscene31
"Es regt sich etwas im Schiff.", // kStringIntroCutscene32
"Uuuuaaaahhhhh", // kStringIntroCutscene33
"Huch, ich bin ja gefesselt!|Wo bin ich?", // kStringIntroCutscene34
// 315
"Ach so, das sind ja die Sicherheitsgurte.|Ich arbeite ja jetzt in diesem Raumschiff hier.", // kStringIntroCutscene35
"Was? Schon zwei Uhr! Wieso|hat mich denn noch keiner|aus dem Bett geschmissen?", // kStringIntroCutscene36
"Ich werde mal nachsehen.", // kStringIntroCutscene37
"Autsch!", // kStringIntroCutscene38
"Schei\341etagenbett!", // kStringIntroCutscene39
// 320
"Erst mal den Lichtschalter finden.", // kStringIntroCutscene40
"Hmm, gar nicht so einfach|bei Schwerelosigkeit.", // kStringIntroCutscene41
"Ah, hier ist er.", // kStringIntroCutscene42
"In der K\201che warst du schon|oft genug, im Moment hast|du keinen Appetit.", // kStringShipHall1
"Flugziel erreicht", // kStringShipSleepCabin1
// 325
"Energie ersch\224pft", // kStringShipSleepCabin2
"Tiefschlafprozess abgebrochen", // kStringShipSleepCabin3
"Schlafdauer in Tagen:", // kStringShipSleepCabin4
"Bitte legen Sie sich in die angezeigte Schlafkammer.", // kStringShipSleepCabin5
"Bitte Passwort eingeben:", // kStringShipSleepCabin6
// 330
"Schlafdauer in Tagen:", // kStringShipSleepCabin7
"Bitte legen Sie sich in die angezeigte Schlafkammer.", // kStringShipSleepCabin8
"Falsches Passwort", // kStringShipSleepCabin9
"Es w\201rde wenig bringen,|sich in eine Schlafkammer zu legen,|die nicht eingeschaltet ist.", // kStringShipSleepCabin10
"Dazu mu\341t du erst den Raumanzug ausziehen.", // kStringShipSleepCabin11
// 335
"Was war das?", // kStringShipSleepCabin12
"Achtung", // kStringShipSleepCabin13
"Du wachst mit brummendem Sch\204del auf|und merkst, da\341 du nur getr\204umt hast.", // kStringShipSleepCabin14
"Beim Aufprall des Raumschiffs|mu\341t du mit dem Kopf aufgeschlagen|und bewu\341tlos geworden sein.", // kStringShipSleepCabin15
"Was steht dir jetzt wohl wirklich bevor?", // kStringShipSleepCabin16
// 340
"Geschwindigkeit: ", // kStringShipCockpit1
"8000 hpm", // kStringShipCockpit2
"0 hpm", // kStringShipCockpit3
"Ziel: Arsano 3", // kStringShipCockpit4
"Entfernung: ", // kStringShipCockpit5
//345
" Lichtjahre", // kStringShipCockpit6
"Dauer der Reise bei momentaner Geschwindigkeit:", // kStringShipCockpit7
" Tage", // kStringShipCockpit8
"Vergi\341 nicht, du bist nur der|Schiffskoch und hast keine Ahnung,|wie man ein Raumschiff fliegt.", // kStringShipCockpit9
"Achtung: Triebwerke funktionsunf\204hig", // kStringShipCockpit10
//350
"Energievorrat ersch\224pft", // kStringShipCockpit11
"Notstromversorgung aktiv", // kStringShipCockpit12
"Was?! Keiner im Cockpit!|Die sind wohl verr\201ckt!", // kStringShipCockpit13
"Du hast die Platte schon aufgelegt.", // kStringShipCabinL3_1
"Es ist doch gar keine Platte aufgelegt.", // kStringShipCabinL3_2
//355
"Die Platte scheint einen Sprung zu haben.", // kStringShipCabinL3_3
"Schneid doch besser ein|l\204ngeres St\201ck Kabel ab!", // kStringShipCabinL3_4
"Das ist befestigt.", // kStringShipCabinL3_5
"Zu niedriger Luftdruck soll ungesund sein.", // kStringShipAirlock1
"Er zeigt Null an.", // kStringShipAirlock2
//360
"Er zeigt Normaldruck an.", // kStringShipAirlock3
"Komisch, es ist nur|noch ein Raumanzug da.", // kStringShipAirlock4
"Du mu\341t erst hingehen.", // kStringShipHold1
"Das Kabel ist im Weg.", // kStringCable1
"Das Kabel ist schon ganz|richtig an dieser Stelle.", // kStringCable2
//365
"Womit denn?", // kStringCable3
"Die Leitung ist zu kurz.", // kStringCable4
"Was ist denn das f\201r ein Chaos?|Und au\341erdem fehlt das Notraumschiff!|Jetzt wird mir einiges klar.|Die anderen sind gefl\201chtet,|und ich habe es verpennt.", // kStringShipHold2
"Es ist nicht spitz genug.", // kStringShipHold3
"Du wirst aus den Anzeigen nicht schlau.", // kStringShipHold4
//370
"La\341 lieber die Finger davon!", // kStringShipHold5
"An dem Kabel ist doch gar kein Stecker.", // kStringShipHold6
"Du solltest die Luke vielleicht erst \224ffnen.", // kStringShipHold7
"Das Seil ist im Weg.", // kStringShipHold8
"Das ist geschlossen.", // kStringShipHold9
//375
"Das geht nicht.|Die Luke ist mindestens|5 Meter \201ber dem Boden.", // kStringShipHold10
"Was n\201tzt dir der Anschlu\341|ohne eine Stromquelle?!", // kStringShipHold11
"Die Spannung ist auf Null abgesunken.", // kStringShipHold12
"Es zeigt volle Spannung an.", // kStringShipHold13
"Du mu\341t die Luke erst \224ffnen.", // kStringShipHold14
//380
"Das Seil ist hier schon ganz richtig.", // kStringShipHold15
"Das Kabel ist zu kurz.", // kStringShipHold16
"Die Raumschiffe sind alle verschlossen.", // kStringArsanoMeetup1
"Unsinn!", // kStringArsanoMeetup2
"Komisch! Auf einmal kannst du|das Schild lesen! Darauf steht:|\"Treffpunkt Galactica\".", // kStringArsanoMeetup3
//385
"Durch deinen Helm kannst|du nicht sprechen.", // kStringArsanoEntrance1
"Wo soll ich die Schuhe ablegen?", // kStringArsanoEntrance2
"Was, das wissen Sie nicht?", // kStringArsanoEntrance3
"Sie befinden sich im Restaurant|\"Treffpunkt Galactica\".", // kStringArsanoEntrance4
"Wir sind bei den interessantesten|Ereignissen in der Galaxis|immer zur Stelle.", // kStringArsanoEntrance5
//390
"Wenn Sie meinen.", // kStringArsanoEntrance6
"In der Toilette gibt es|Schlie\341f\204cher f\201r Schuhe.", // kStringArsanoEntrance7
"Wenn Sie das Lokal betreten|wollen, m\201ssen Sie erst|ihre Schuhe ausziehen.", // kStringArsanoEntrance8
"Wollen Sie, da\341 ich Sie rau\341schmei\341e?", // kStringArsanoEntrance9
"Hhius otgfh Dgfdrkjlh Fokj gf.", // kStringArsanoEntrance10
//395
"Halt!", // kStringArsanoEntrance11
"Uhwdejkt!", // kStringArsanoEntrance12
"Sie m\201ssen erst ihre Schuhe ausziehen, Sie Trottel!", // kStringArsanoEntrance13
"Was f\204llt ihnen ein!|Sie k\224nnen doch ein Lokal|nicht mit Schuhen betreten!", // kStringArsanoEntrance14
"Fragen Sie nicht so doof!", // kStringArsanoEntrance15
// 400
"Das w\201rde ich an ihrer|Stelle nicht versuchen!", // kStringArsanoEntrance16
"Du ziehst deine Schuhe|aus und legst sie in|eins der Schlie\341f\204cher.", // kStringArsanoEntrance17
"Du ziehst deine Schuhe wieder an.", // kStringArsanoEntrance18
"Du durchsuchst die Klos nach|anderen brauchbaren Sachen,|findest aber nichts.", // kStringArsanoEntrance19
"Bevor du aufs Klo gehst,|solltest du besser deinen|Raumanzug ausziehen.", // kStringArsanoEntrance20
// 405
"Du gehst seit sieben Jahren das|erste Mal wieder aufs Klo!", // kStringArsanoEntrance21
"In einem der Schlie\341f\204cher,|die sich auch im Raum befinden,|findest du einige M\201nzen.", // kStringArsanoEntrance22
"Mach doch zuerst das Fach leer!", // kStringArsanoEntrance23
"Komisch! Auf einmal kannst du|das Schild lesen! Darauf steht:|\"Zutritt nur f\201r Personal\".", // kStringArsanoEntrance24
"Komisch! Auf einmal kannst|du das Schild lesen!|Darauf steht:\"Toilette\".", // kStringArsanoEntrance25
// 410
"Du ziehst den Raumanzug wieder an.", // kStringArsanoEntrance26
"Nicht so gewaltt\204tig!", // kStringArsanoEntrance27
"Wo bin ich hier?", // kStringArsanoDialog1
"Sch\224nes Wetter heute, nicht wahr?", // kStringArsanoDialog2
"W\201rden Sie mich bitte durchlassen.", // kStringArsanoDialog3
// 415
"Hey Alter, la\341 mich durch!", // kStringArsanoDialog4
"Was haben Sie gesagt?", // kStringArsanoDialog5
"Sprechen Sie bitte etwas deutlicher!", // kStringArsanoDialog6
"Wieso das denn nicht?", // kStringArsanoDialog7
"Wo soll ich die Schuhe ablegen?", // kStringArsanoDialog8
// 420
"Schwachsinn! Ich gehe jetzt nach oben!", // kStringArsanoDialog9
"|", // kStringDialogSeparator
"K\224nnten Sie mir ein Gericht empfehlen?", // kStringDialogArsanoRoger1
"Wie lange dauert es denn noch bis zur Supernova?", // kStringDialogArsanoRoger2
"Sie kommen mir irgendwie bekannt vor.", // kStringDialogArsanoRoger3
// 425
"Was wollen Sie von mir?", // kStringDialogArsanoMeetup3_1
"Hilfe!!", // kStringDialogArsanoMeetup3_2
"Warum sprechen Sie meine Sprache?", // kStringDialogArsanoMeetup3_3
"Ja, ich bin einverstanden.", // kStringDialogArsanoMeetup3_4
"Nein, lieber bleibe ich hier, als mit Ihnen zu fliegen.", // kStringDialogArsanoMeetup3_5
// 430
"Darf ich hier Platz nehmen?", // kStringArsanoRoger1
"Klar!", // kStringArsanoRoger2
"Hey, Witzkeks, la\341 die Brieftasche da liegen!", // kStringArsanoRoger3
"Das ist nicht deine.", // kStringArsanoRoger4
"Roger ist im Moment nicht ansprechbar.", // kStringArsanoRoger5
// 435
"Bestellen Sie lieber nichts!", // kStringArsanoRoger6
"Ich habe vor zwei Stunden mein Essen|bestellt und immer noch nichts bekommen.", // kStringArsanoRoger7
"Noch mindestens zwei Stunden.", // kStringArsanoRoger8
"Haben Sie keine Idee, womit wir uns|bis dahin die Zeit vertreiben k\224nnen?", // kStringArsanoRoger9
"Hmm ... im Moment f\204llt mir nichts ein, aber vielleicht|hat der Spieler des Adventures ja eine Idee.", // kStringArsanoRoger10
// 440
"Nein, Sie m\201ssen sich irren.|Ich kenne Sie jedenfalls nicht.", // kStringArsanoRoger11
"Aber ihre Kleidung habe ich irgendwo schon mal gesehen.", // kStringArsanoRoger12
"Ja? Komisch.", // kStringArsanoRoger13
"Jetzt wei\341 ich's. Sie sind Roger W. !", // kStringArsanoRoger14
"Pssst, nicht so laut, sonst will|gleich jeder ein Autogramm von mir.", // kStringArsanoRoger15
// 445
"Ich habe extra eine Maske auf, damit|ich nicht von jedem angelabert werde.", // kStringArsanoRoger16
"\216h ... ach so.", // kStringArsanoRoger17
"Wann kommt denn das n\204chste SQ-Abenteuer raus?", // kStringArsanoRoger18
"SQ 127 m\201\341te in einem Monat erscheinen.", // kStringArsanoRoger19
"Was, Teil 127 ??", // kStringArsanoRoger20
// 450
"Bei uns ist gerade Teil 8 erschienen.", // kStringArsanoRoger21
"Hmm ... von welchem Planeten sind Sie denn?", // kStringArsanoRoger22
"Von der Erde.", // kStringArsanoRoger23
"Erde? Nie geh\224rt.", // kStringArsanoRoger24
"Wahrscheinlich irgendein Kaff, wo Neuerungen|erst hundert Jahre sp\204ter hingelangen.", // kStringArsanoRoger25
// 455
"\216h ... kann sein.", // kStringArsanoRoger26
"Aber eins m\201ssen Sie mir erkl\204ren!", // kStringArsanoRoger27
"Wieso sehen Sie mir so verdammt \204hnlich, wenn|Sie nicht von Xenon stammen, wie ich?", // kStringArsanoRoger28
"Keine Ahnung. Bis jetzt dachte ich immer, Sie w\204ren ein|von Programmierern auf der Erde erfundenes Computersprite.", // kStringArsanoRoger29
"Was? Lachhaft!", // kStringArsanoRoger30
// 460
"Wie erkl\204ren Sie sich dann,|da\341 ich ihnen gegen\201bersitze?", // kStringArsanoRoger31
"Ja, das ist in der Tat seltsam.", // kStringArsanoRoger32
"Halt, jetzt wei\341 ich es. Sie sind von der Konkurrenz,|von \"Georgefilm Games\" und wollen mich verunsichern.", // kStringArsanoRoger33
"Nein, ich bin nur ein Ahnungsloser Koch von der Erde.", // kStringArsanoRoger34
"Na gut, ich glaube Ihnen. Lassen wir jetzt|dieses Thema, langsam wird es mir zu bunt!", // kStringArsanoRoger35
// 465
"Eine Partie Schach! Das ist eine gute Idee.", // kStringArsanoRoger36
"Schach? Was ist das denn?", // kStringArsanoRoger37
"Schach ist ein interessantes Spiel.|Ich werde es Ihnen erkl\204ren.", // kStringArsanoRoger38
"Knapp zwei Stunden sp\204ter ...", // kStringArsanoRoger39
"Roger W. steht kurz vor dem Schachmatt|und gr\201belt nach einem Ausweg.", // kStringArsanoRoger40
// 470
"Du tippst auf den Tasten herum,|aber es passiert nichts.", // kStringArsanoGlider1
"Alle Raumschiffe haben|den Planeten verlassen.", // kStringArsanoMeetup2_1
"Alle Raumschiffe haben den Planeten|verlassen, bis auf eins ...", // kStringArsanoMeetup2_2
"Was wollen Sie denn schon wieder?", // kStringArsanoMeetup2_3
"Nein.", // kStringArsanoMeetup2_4
// 475
"Haben Sie zuf\204llig meine Brieftasche gesehen?|Ich mu\341 Sie irgendwo verloren haben.", // kStringArsanoMeetup2_5
"Ohne die Brieftasche kann ich nicht|starten, weil meine Keycard darin ist.", // kStringArsanoMeetup2_6
"Oh! Vielen Dank.", // kStringArsanoMeetup2_7
"Wo ist denn Ihr Raumschiff?|Soll ich Sie ein St\201ck mitnehmen?", // kStringArsanoMeetup2_8
"Wo wollen Sie denn hin?", // kStringArsanoMeetup2_9
// 480
"Ok, steigen Sie ein!", // kStringArsanoMeetup2_10
"Wie Sie wollen.", // kStringArsanoMeetup2_11
"Huch, du lebst ja noch!", // kStringArsanoMeetup2_12
"Das w\201rde ich jetzt nicht tun, schlie\341lich|steht Roger W. neben seinem Schiff.", // kStringArsanoMeetup2_13
"Ich glaube, er wacht auf.", // kStringArsanoMeetup3_1
// 485
"Ja, sieht so aus.", // kStringArsanoMeetup3_2
"Sie befinden sich im Raumschiff \"Dexxa\".", // kStringArsanoMeetup3_3
"Wir kommen vom Planeten Axacuss und|sind aus dem gleichen Grund hier wie Sie,|n\204mlich zur Erforschung der Supernova.", // kStringArsanoMeetup3_4
"Sie k\224nnen beruhigt sein, wir wollen Ihnen nur helfen.", // kStringArsanoMeetup3_5
"Und wieso hat der Typ im Raumanzug|eben auf mich geschossen?", // kStringArsanoMeetup3_6
// 490
"Das war eine Schreckreaktion.", // kStringArsanoMeetup3_7
"Schlie\341lich ist es f\201r uns das erste Mal,|da\341 wir auf eine fremde Intelligenz treffen.", // kStringArsanoMeetup3_8
"Wie wir festgestellt haben, ist|Ihr Raumschiff v\224llig zerst\224rt.", // kStringArsanoMeetup3_9
"Wahrscheinlich k\224nnen Sie nicht|mehr auf ihren Heimatplaneten zur\201ck.", // kStringArsanoMeetup3_10
"Wir bieten Ihnen an, Sie|mit nach Axacuss zu nehmen.", // kStringArsanoMeetup3_11
// 495
"Sind Sie sich da wirklich sicher?", // kStringArsanoMeetup3_12
"Wenn ich es mir genau \201berlege,|fliege ich doch lieber mit.", // kStringArsanoMeetup3_13
"Gut, wir nehmen Sie unter der|Bedingung mit, da\341 wir Sie jetzt|sofort in Tiefschlaf versetzen d\201rfen.", // kStringArsanoMeetup3_14
"Diese Art des Reisens ist Ihnen|ja scheinbar nicht unbekannt.", // kStringArsanoMeetup3_15
"Sie werden in vier Jahren nach der|Landung der \"Dexxa\" wieder aufgeweckt.", // kStringArsanoMeetup3_16
// 500
"Sind Sie damit einverstanden?", // kStringArsanoMeetup3_17
"Gut, haben Sie noch irgendwelche Fragen?", // kStringArsanoMeetup3_18
"Keine Panik!", // kStringArsanoMeetup3_19
"Wir tun Ihnen nichts.", // kStringArsanoMeetup3_20
"Wir sprechen nicht ihre Sprache,|sondern Sie sprechen unsere.", // kStringArsanoMeetup3_21
// 505
"Nach einer Gehirnanalyse konnten|wir Ihr Gehirn an unsere Sprache anpassen.", // kStringArsanoMeetup3_22
"Was? Sie haben in mein Gehirn eingegriffen?", // kStringArsanoMeetup3_23
"Keine Angst, wir haben sonst nichts ver\204ndert.", // kStringArsanoMeetup3_24
"Ohne diesen Eingriff w\204ren|Sie verloren gewesen.", // kStringArsanoMeetup3_25
"Ich habe keine weiteren Fragen mehr.", // kStringArsanoMeetup3_26
// 510
"Gut, dann versetzen wir Sie jetzt in Tiefschlaf.", // kStringArsanoMeetup3_27
"Gute Nacht!", // kStringArsanoMeetup3_28
"Du wachst auf und findest dich in|einem geschlossenen Raum wieder.", // kStringAxacussCell_1
"Du dr\201ckst den Knopf,|aber nichts passiert.", // kStringAxacussCell_2
"Das ist befestigt.", // kStringAxacussCell_3
// 515
"Bei deinem Fluchtversuch hat|dich der Roboter erschossen.", // kStringAxacussCell_4
"Du i\341t etwas, aber|es schmeckt scheu\341lich.", // kStringAxacussCell_5
"Ok.", // kStringOk
"Ach, Ihnen geh\224rt die. Ich habe sie eben im Sand gefunden.", // kStringDialogArsanoMeetup2_1
"Nein, tut mir leid.", // kStringDialogArsanoMeetup2_2
// 520
"Nein, danke. Ich bleibe lieber hier.", // kStringDialogArsanoMeetup2_3
"Ja, das w\204re gut.", // kStringDialogArsanoMeetup2_4
"Zur Erde.", // kStringDialogArsanoMeetup2_5
"Zum Pr\204sident der Galaxis.", // kStringDialogArsanoMeetup2_6
"Nach Xenon.", // kStringDialogArsanoMeetup2_7
// 525
"Mir egal, setzen Sie mich irgendwo ab!", // kStringDialogArsanoMeetup2_8
"Ich habe gerade Ihre Brieftasche gefunden!", // kStringDialogArsanoMeetup2_9
"Sie lag da dr\201ben hinter einem Felsen.", // kStringDialogArsanoMeetup2_10
"Ich wollte nur wissen, ob Sie die Brieftasche wiederhaben.", // kStringDialogArsanoMeetup2_11
"\216h ... nein, mein Name ist M\201ller.", // kStringDialogAxacussCorridor5_1
// 530
"Oh, ich habe mich im Gang vertan.", // kStringDialogAxacussCorridor5_2
"W\201rden Sie mich bitte zum Fahrstuhl lassen?", // kStringDialogAxacussCorridor5_3
"Ich gehe wieder.", // kStringDialogAxacussCorridor5_4
"Dann gehe ich eben wieder.", // kStringDialogAxacussCorridor5_5
"Ach, halten Sie's Maul, ich gehe trotzdem!", // kStringDialogAxacussCorridor5_6
// 535
"Wenn Sie mich durchlassen gebe ich Ihnen %d Xa.", // kStringDialogAxacussCorridor5_7
"Hallo!", // kStringDialogX1
"Guten Tag!", // kStringDialogX2
"Ich bin's, Horst Hummel.", // kStringDialogX3
"Sie schon wieder?", // kStringAxacussCorridor5_1
// 540
"Halt! Sie sind doch dieser Hummel.|Bleiben Sie sofort stehen!", // kStringAxacussCorridor5_2
"Sehr witzig!", // kStringAxacussCorridor5_3
"Kann auch sein, auf jeden Fall|sind Sie der Nicht-Axacussaner.", // kStringAxacussCorridor5_4
"Nein!", // kStringAxacussCorridor5_5
"Das m\201\341te schon ein bi\341chen mehr sein.", // kStringAxacussCorridor5_6
// 545
"Ok, dann machen Sie da\341 Sie wegkommen!", // kStringAxacussCorridor5_7
"Du stellst dich hinter die S\204ule.", // kStringAxacussBcorridor_1
"Welche Zahlenkombination willst|du eingeben?", // kStringAxacussOffice1_1
"Hmm, das haut nicht ganz hin,|aber irgendwie mu\341 die Zahl|mit dem Code zusammenh\204ngen.", // kStringAxacussOffice1_2
"Das war die falsche Kombination.", // kStringAxacussOffice1_3
// 550
"Streng geheim", // kStringAxacussOffice1_4
"418-98", // kStringAxacussOffice1_5
"Sehr geehrter Dr. Hansi,", // kStringAxacussOffice1_6
"Ich mu\341 Ihren Roboterexperten ein Lob aussprechen. Die", // kStringAxacussOffice1_7
"Imitation von Horst Hummel ist perfekt gelungen, wie ich", // kStringAxacussOffice1_8
// 555
"heute bei der \232bertragung des Interviews feststellen", // kStringAxacussOffice1_9
"konnte. Dem Aufschwung Ihrer Firma durch die Werbe-", // kStringAxacussOffice1_10
"kampagne mit dem falschen Horst Hummel d\201rfte ja jetzt", // kStringAxacussOffice1_11
"nichts mehr im Wege stehen.", // kStringAxacussOffice1_12
"PS: Herzlichen zum Geburtstag!", // kStringAxacussOffice1_13
// 560
"Hochachtungsvoll", // kStringAxacussOffice1_14
"Commander Sumoti", // kStringAxacussOffice1_15
"Nicht zu fassen!", // kStringAxacussOffice1_16
"Hey, hinter dem Bild ist Geld|versteckt. Ich nehme es mit.", // kStringAxacussOffice3_1
"Jetzt verschwinden Sie endlich!", // kStringAxacussElevator_1
// 565
"Huch, ich habe mich vertan.", // kStringAxacussElevator_2
"Nachdem du zwei Stunden im|Dschungel herumgeirrt bist,|findest du ein Geb\204ude.", // kStringAxacussElevator_3
"Du h\204ttest besser vorher|den Stecker rausgezogen.", // kStringShock
"Der Axacussaner hat dich erwischt.", // kStringShot
"Das ist schon geschlossen.", // kStringCloseLocker_1
// 570
"Irgendwie ist ein Raumhelm|beim Essen unpraktisch.", // kStringIsHelmetOff_1
"Schmeckt ganz gut.", // kStringGenericInteract_1
"Da war irgendetwas drin,|aber jetzt hast du es|mit runtergeschluckt.", // kStringGenericInteract_2
"Du hast es doch schon ge\224ffnet.", // kStringGenericInteract_3
"In dem Ei ist eine Tablette|in einer Plastikh\201lle.", // kStringGenericInteract_4
// 575
"Du i\341t die Tablette und merkst,|da\341 sich irgendetwas ver\204ndert hat.", // kStringGenericInteract_5
"Komisch! Auf einmal kannst du die Schrift lesen!|Darauf steht:\"Wenn Sie diese Schrift jetzt|lesen k\224nnen, hat die Tablette gewirkt.\"", // kStringGenericInteract_6
"Das mu\341t du erst nehmen.", // kStringGenericInteract_7
"Sie ist leer.", // kStringGenericInteract_8
"Du findest 10 Buckazoids und eine Keycard.", // kStringGenericInteract_9
// 580
"Es ist eine Art elektronische Zeitung.", // kStringGenericInteract_10
"Halt, hier ist ein interessanter Artikel.", // kStringGenericInteract_11
"Hmm, irgendwie komme|ich mir verarscht vor.", // kStringGenericInteract_12
" an ", // kPhrasalVerbParticleGiveTo
" mit ", // kPhrasalVerbParticleUseWith
// 585
"Es ist eine Uhr mit extra|lautem Wecker. Sie hat einen|Knopf zum Verstellen der Alarmzeit.|Uhrzeit: %s Alarmzeit: %s", // kStringGenericInteract_13
"Neue Alarmzeit (hh:mm) :", // kStringGenericInteract_14
"Die Luft hier ist atembar,|du ziehst den Anzug aus.", // kStringGenericInteract_15
"Hier drinnen brauchtst du deinen Anzug nicht.", // kStringGenericInteract_16
"Du mu\341t erst den Helm abnehmen.", // kStringGenericInteract_17
// 590
"Du mu\341t erst den Versorgungsteil abnehmen.", // kStringGenericInteract_18
"Du ziehst den Raumanzug aus.", // kStringGenericInteract_19
"Du ziehst den Raumanzug an.", // kStringGenericInteract_20
"Die Luft hier ist atembar,|du ziehst den Anzug aus.", // kStringGenericInteract_21
"Hier drinnen brauchtst du deinen Anzug nicht.", // kStringGenericInteract_22
// 595
"Den Helm h\204ttest du|besser angelassen!", // kStringGenericInteract_23
"Du ziehst den Helm ab.", // kStringGenericInteract_24
"Du ziehst den Helm auf.", // kStringGenericInteract_25
"Du mu\341t erst den Anzug anziehen.", // kStringGenericInteract_26
"Den Versorgungsteil h\204ttest du|besser nicht abgenommen!", // kStringGenericInteract_27
// 600
"Du nimmst den Versorgungsteil ab.", // kStringGenericInteract_28
"Du ziehst den Versorgungsteil an.", // kStringGenericInteract_29
"Die Leitung ist hier unn\201tz.", // kStringGenericInteract_30
"Stark, das ist ja die Fortsetzung zum \"Anhalter\":|\"Das Restaurant am Ende des Universums\".", // kStringGenericInteract_31
"Moment mal, es ist ein Lesezeichen drin,|auf dem \"Zweiundvierzig\" steht.", // kStringGenericInteract_32
// 605
"Das tr\204gst du doch bei dir.", // kStringGenericInteract_33
"Du bist doch schon da.", // kStringGenericInteract_34
"Das hast du doch schon.", // kStringGenericInteract_35
"Das brauchst du nicht.", // kStringGenericInteract_36
"Das kannst du nicht nehmen.", // kStringGenericInteract_37
// 610
"Das l\204\341t sich nicht \224ffnen.", // kStringGenericInteract_38
"Das ist schon offen.", // kStringGenericInteract_39
"Das ist verschlossen.", // kStringGenericInteract_40
"Das l\204\341t sich nicht schlie\341en.", // kStringGenericInteract_41
"Behalt es lieber!", // kStringGenericInteract_42
// 615
"Das geht nicht.", // kStringGenericInteract_43
"Gespr\204ch beenden", // kStringConversationEnd
"Du hast das komische Gef\201hl,|da\341 drau\341en etwas passiert,|und eilst zum Restaurant.", // kStringSupernova1
"Da! Die Supernova!", // kStringSupernova2
"Zwei Minuten sp\204ter ...", // kStringSupernova3
// 620
"Hey, was machen Sie in meinem Raumschiff?!", // kStringSupernova4
"Geben Sie mir sofort meine Brieftasche wieder!", // kStringSupernova5
"Versuchen Sie das ja nicht nochmal!", // kStringSupernova6
"Und jetzt raus mit Ihnen!", // kStringSupernova7
"Zehn Minuten sp\204ter ...", // kStringSupernova8
// 625
"Textgeschwindigkeit:", // kStringTextSpeed
"Was war das f\201r ein Ger\204usch?", // kStringGuardNoticed1
"Ich werde mal nachsehen.", // kStringGuardNoticed2
"Guten Tag, hier ist Horst Hummel.", // kStringTelomat1
"Hier ist %s. K\224nnen Sie mal gerade kommen?", // kStringTelomat2
// 630
"Es ist sehr wichtig.", // kStringTelomat3
"Vom Mars.", // kStringTelomat4
"Vom Klo.", // kStringTelomat5
"Das werde ich kaum erz\204hlen.", // kStringTelomat6
"1 B\201romanager", // kStringTelomat7
// 635
"2 Telomat", // kStringTelomat8
"3 ProText", // kStringTelomat9
"4 Calculata", // kStringTelomat10
"Bitte w\204hlen", // kStringTelomat11
"Geben Sie den gew\201nschten Namen ein:", // kStringTelomat12
// 640
"(Vor- und Nachname)", // kStringTelomat13
"Name unbekannt", // kStringTelomat14
"Verbindung unm\224glich", // kStringTelomat15
"Verbindung wird hergestellt", // kStringTelomat16
"%s am Apparat.", // kStringTelomat17
// 645
"Huch, Sie h\224ren sich aber|nicht gut an. Ich komme sofort.", // kStringTelomat18
"Horst Hummel! Von wo rufen Sie an?", // kStringTelomat19
"Hmm, keine Antwort.", // kStringTelomat20
"Passwort:", // kStringTelomat21
"Deine Armbanduhr piepst,|die Alarmzeit ist erreicht.", // kStringAlarm
NULL
};
#endif // GAMETEXT_H

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
MODULE := devtools/create_supernova
MODULE_OBJS := \
file.o \
po_parser.o \
create_supernova.o
# Set the name of the executable
TOOL_EXECUTABLE := create_supernova
# Include common rules
include $(srcdir)/rules.mk

View File

@ -0,0 +1,221 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "po_parser.h"
PoMessageList::PoMessageList() : _list(NULL), _size(0), _allocated(0) {
}
PoMessageList::~PoMessageList() {
for (int i = 0; i < _size; ++i)
delete _list[i];
delete[] _list;
}
int PoMessageList::compareString(const char* left, const char* right) {
if (left == NULL && right == NULL)
return 0;
if (left == NULL)
return -1;
if (right == NULL)
return 1;
return strcmp(left, right);
}
int PoMessageList::compareMessage(const char *msgLeft, const char *contextLeft, const char *msgRight, const char *contextRight) {
int compare = compareString(msgLeft, msgRight);
if (compare != 0)
return compare;
return compareString(contextLeft, contextRight);
}
void PoMessageList::insert(const char *translation, const char *msg, const char *context) {
if (msg == NULL || *msg == '\0' || translation == NULL || *translation == '\0')
return;
// binary-search for the insertion index
int leftIndex = 0;
int rightIndex = _size - 1;
while (rightIndex >= leftIndex) {
int midIndex = (leftIndex + rightIndex) / 2;
int compareResult = compareMessage(msg, context, _list[midIndex]->msgid, _list[midIndex]->msgctxt);
if (compareResult == 0)
return; // The message is already in this list
else if (compareResult < 0)
rightIndex = midIndex - 1;
else
leftIndex = midIndex + 1;
}
// We now have rightIndex = leftIndex - 1 and we need to insert the new message
// between the two (i.a. at leftIndex).
if (_size + 1 > _allocated) {
_allocated += 100;
PoMessage **newList = new PoMessage*[_allocated];
for (int i = 0; i < leftIndex; ++i)
newList[i] = _list[i];
for (int i = leftIndex; i < _size; ++i)
newList[i + 1] = _list[i];
delete[] _list;
_list = newList;
} else {
for (int i = _size - 1; i >= leftIndex; --i)
_list[i + 1] = _list[i];
}
_list[leftIndex] = new PoMessage(translation, msg, context);
++_size;
}
const char *PoMessageList::findTranslation(const char *msg, const char *context) {
if (msg == NULL || *msg == '\0')
NULL;
// binary-search for the message
int leftIndex = 0;
int rightIndex = _size - 1;
while (rightIndex >= leftIndex) {
int midIndex = (leftIndex + rightIndex) / 2;
int compareResult = compareMessage(msg, context, _list[midIndex]->msgid, _list[midIndex]->msgctxt);
if (compareResult == 0)
return _list[midIndex]->msgstr;
else if (compareResult < 0)
rightIndex = midIndex - 1;
else
leftIndex = midIndex + 1;
}
return NULL;
}
PoMessageList *parsePoFile(const char *file) {
FILE *inFile = fopen(file, "r");
if (!inFile)
return NULL;
char msgidBuf[1024], msgctxtBuf[1024], msgstrBuf[1024];
char line[1024], *currentBuf = msgstrBuf;
PoMessageList *list = new PoMessageList();
// Initialize the message attributes.
bool fuzzy = false;
bool fuzzy_next = false;
// Parse the file line by line.
// The msgstr is always the last line of an entry (i.e. msgid and msgctxt always
// precede the corresponding msgstr).
msgidBuf[0] = msgstrBuf[0] = msgctxtBuf[0] = '\0';
while (!feof(inFile) && fgets(line, 1024, inFile)) {
if (line[0] == '#' && line[1] == ',') {
// Handle message attributes.
if (strstr(line, "fuzzy")) {
fuzzy_next = true;
continue;
}
}
// Skip empty and comment line
if (*line == '\n' || *line == '#')
continue;
if (strncmp(line, "msgid", 5) == 0) {
if (currentBuf == msgstrBuf) {
// add previous entry
if (*msgstrBuf != '\0' && !fuzzy)
list->insert(msgstrBuf, msgidBuf, msgctxtBuf);
msgidBuf[0] = msgstrBuf[0] = msgctxtBuf[0] = '\0';
// Reset the attribute flags.
fuzzy = fuzzy_next;
fuzzy_next = false;
}
strcpy(msgidBuf, stripLine(line));
currentBuf = msgidBuf;
} else if (strncmp(line, "msgctxt", 7) == 0) {
if (currentBuf == msgstrBuf) {
// add previous entry
if (*msgstrBuf != '\0' && !fuzzy)
list->insert(msgstrBuf, msgidBuf, msgctxtBuf);
msgidBuf[0] = msgstrBuf[0] = msgctxtBuf[0] = '\0';
// Reset the attribute flags
fuzzy = fuzzy_next;
fuzzy_next = false;
}
strcpy(msgctxtBuf, stripLine(line));
currentBuf = msgctxtBuf;
} else if (strncmp(line, "msgstr", 6) == 0) {
strcpy(msgstrBuf, stripLine(line));
currentBuf = msgstrBuf;
} else {
// concatenate the string at the end of the current buffer
if (currentBuf)
strcat(currentBuf, stripLine(line));
}
}
if (currentBuf == msgstrBuf) {
// add last entry
if (*msgstrBuf != '\0' && !fuzzy)
list->insert(msgstrBuf, msgidBuf, msgctxtBuf);
}
fclose(inFile);
return list;
}
char *stripLine(char *const line) {
// This function modifies line in place and return it.
// Keep only the text between the first two unprotected quotes.
// It also look for literal special characters (e.g. preceded by '\n', '\\', '\"', '\'', '\t')
// and replace them by the special character so that strcmp() can match them at run time.
// Look for the first quote
char const *src = line;
while (*src != '\0' && *src++ != '"') {}
// shift characters until we reach the end of the string or an unprotected quote
char *dst = line;
while (*src != '\0' && *src != '"') {
char c = *src++;
if (c == '\\') {
switch (c = *src++) {
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
case '\"': c = '\"'; break;
case '\'': c = '\''; break;
case '\\': c = '\\'; break;
default:
// Just skip
fprintf(stderr, "Unsupported special character \"\\%c\" in string. Please contact ScummVM developers.\n", c);
continue;
}
}
*dst++ = c;
}
*dst = '\0';
return line;
}
char *parseLine(const char *line, const char *field) {
// This function allocate and return a new char*.
// It will return a NULL pointer if the field is not found.
// It is used to parse the header of the po files to find the language name
// and the charset.
const char *str = strstr(line, field);
if (str == NULL)
return NULL;
str += strlen(field);
// Skip spaces
while (*str != '\0' && isspace(*str)) {
++str;
}
// Find string length (stop at the first '\n')
int len = 0;
while (str[len] != '\0' && str[len] != '\n') {
++len;
}
if (len == 0)
return NULL;
// Create result string
char *result = new char[len + 1];
strncpy(result, str, len);
result[len] = '\0';
return result;
}

View File

@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* This is a utility for generating a data file for the supernova engine.
* It contains strings extracted from the original executable as well
* as translations and is required for the engine to work properly.
*/
#ifndef PO_PARSER_H
#define PO_PARSER_H
struct PoMessage {
char *msgstr;
char *msgid;
char *msgctxt;
PoMessage(const char *translation, const char *message, const char *context = NULL) :
msgstr(NULL), msgid(NULL), msgctxt(NULL)
{
if (translation != NULL && *translation != '\0') {
msgstr = new char[1 + strlen(translation)];
strcpy(msgstr, translation);
}
if (message != NULL && *message != '\0') {
msgid = new char[1 + strlen(message)];
strcpy(msgid, message);
}
if (context != NULL && *context != '\0') {
msgctxt = new char[1 + strlen(context)];
strcpy(msgctxt, context);
}
}
~PoMessage() {
delete[] msgstr;
delete[] msgid;
delete[] msgctxt;
}
};
class PoMessageList {
public:
PoMessageList();
~PoMessageList();
void insert(const char *translation, const char *msg, const char *context = NULL);
const char *findTranslation(const char *msg, const char *context = NULL);
private:
int compareString(const char *left, const char *right);
int compareMessage(const char *msgLeft, const char *contextLeft, const char *msgRight, const char *contextRight);
PoMessage **_list;
int _size;
int _allocated;
};
PoMessageList *parsePoFile(const char *file);
char *stripLine(char *);
char *parseLine(const char *line, const char *field);
#endif /* PO_PARSER_H */

File diff suppressed because it is too large Load Diff

Binary file not shown.

72
engines/supernova/NOTES Normal file
View File

@ -0,0 +1,72 @@
Audio
-----------
There may be several sound effects in one file.
This list shows them and their offsets.
46:
0 - Voice "Halt!"
2510 -
4020 -
47:
0 - Voice "Mission Supernova"
24010 - Voice "Yeaahh.."
48:
0 -
2510 -
10520 - electric shock
13530 - (playing turntable)
50:
0 -
12786 -
51:
53: Death sound
54:
0 - Alarm
8010 -
24020 - Door sound
30030 - Door open
31040 - Door close
Engine
----------
MouseFields
[0;256[ - Viewport
[256;512[ - Command Row
[512;768[ - Inventory
[768;769] - Inventory Arrows
Dimensions
Viewport: (0,0) (320, 150)
Command Row: (0, 150) (320, 159)
Inventory: (0, 161) (270, 200)
Inventory Arrows: (271, 161) (279, 200)
Exit Maps: (283, 163) (317, 197)
timer2 == animation timer
Text
-------
AE - 216 ae - 204
OE - 231 oe - 224
UE - 232 ue - 201
SZ - 341
Ingame Bugs
------------
In Cabin_R3 (starting room) you can take the discman from your locker without
opening it first.
Improvements
-------------
Incidate in inventory (?) what parts of your space suit you are wearing

View File

@ -0,0 +1,2 @@
engines/supernova/supernova.cpp

View File

@ -0,0 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
add_engine supernova "Mission Supernova" no

View File

@ -0,0 +1,114 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "gui/debugger.h"
#include "supernova/supernova.h"
#include "supernova/state.h"
#include "supernova/console.h"
namespace Supernova {
Console::Console(SupernovaEngine *vm, GameManager *gm)
{
registerCmd("render", WRAP_METHOD(Console, cmdRenderImage));
registerCmd("play", WRAP_METHOD(Console, cmdPlaySound));
registerCmd("music", WRAP_METHOD(Console, cmdMusic));
registerCmd("list", WRAP_METHOD(Console, cmdList));
registerCmd("inventory", WRAP_METHOD(Console, cmdInventory));
registerCmd("giveall", WRAP_METHOD(Console, cmdGiveAll));
_vm = vm;
_gm = gm;
}
bool Console::cmdRenderImage(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Usage: render [filenumber] [section]\n");
return true;
}
int image = atoi(argv[1]);
if (_vm->setCurrentImage(image))
_vm->renderImage(atoi(argv[2]));
else
debugPrintf("Image %d is invalid!", image);
return true;
}
bool Console::cmdPlaySound(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: play [0-%d]\n", kAudioNumSamples - 1);
return true;
}
int sample = Common::String(argv[1]).asUint64();
_vm->playSound(static_cast<AudioIndex>(sample));
return true;
}
bool Console::cmdMusic(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: music [49/52]\n");
return true;
}
_vm->playSoundMod(atoi(argv[1]));
return true;
}
bool Console::cmdList(int argc, const char **argv) {
// Objects in room and sections
return true;
}
bool Console::cmdInventory(int argc, const char **argv) {
if (argc != 2 || argc != 3) {
debugPrintf("Usage: inventory [list][add/remove [object]]");
return true;
}
// TODO
return true;
}
bool Console::cmdGiveAll(int argc, const char **argv) {
_gm->takeObject(*_gm->_rooms[INTRO]->getObject(0));
_gm->takeObject(*_gm->_rooms[INTRO]->getObject(1));
_gm->takeObject(*_gm->_rooms[INTRO]->getObject(2));
_gm->takeObject(*_gm->_rooms[GENERATOR]->getObject(2)); // Commander Keycard
_gm->takeObject(*_gm->_rooms[GENERATOR]->getObject(0)); // Power Cord with Plug
_gm->takeObject(*_gm->_rooms[CABIN_L1]->getObject(5)); // Pen
_gm->takeObject(*_gm->_rooms[CABIN_R3]->getObject(0)); // Chess Board
_gm->takeObject(*_gm->_rooms[CABIN_R3]->getObject(9)); // Rope
_gm->takeObject(*_gm->_rooms[AIRLOCK]->getObject(4)); // Helmet
_gm->takeObject(*_gm->_rooms[AIRLOCK]->getObject(5)); // Space Suit
_gm->takeObject(*_gm->_rooms[AIRLOCK]->getObject(6)); // Supply
return true;
}
}

View File

@ -0,0 +1,55 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SUPERNOVA_CONSOLE_H
#define SUPERNOVA_CONSOLE_H
#include "gui/debugger.h"
namespace Supernova {
class SupernovaEngine;
class GameManager;
enum {
kDebugGeneral = 1 << 0
};
class Console : public GUI::Debugger {
public:
Console(Supernova::SupernovaEngine *vm, Supernova::GameManager *gm);
virtual ~Console() {}
bool cmdRenderImage(int argc, const char **argv);
bool cmdPlaySound(int argc, const char **argv);
bool cmdMusic(int argc, const char **argv);
bool cmdList(int argc, const char **argv);
bool cmdInventory(int argc, const char **argv);
bool cmdGiveAll(int argc, const char **argv);
private:
SupernovaEngine *_vm;
GameManager *_gm;
};
}
#endif

View File

@ -0,0 +1,220 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "base/plugins.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/system.h"
#include "graphics/thumbnail.h"
#include "engines/advancedDetector.h"
#include "supernova/supernova.h"
static const PlainGameDescriptor supernovaGames[] = {
{"msn1", "Mission Supernova 1"},
{"msn2", "Mission Supernova 2"},
{NULL, NULL}
};
namespace Supernova {
static const ADGameDescription gameDescriptions[] = {
// Mission Supernova 1
{
"msn1",
NULL,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
{
"msn1",
NULL,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
// Mission Supernova 2
{
"msn2",
NULL,
AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
AD_TABLE_END_MARKER
};
}
class SupernovaMetaEngine: public AdvancedMetaEngine {
public:
SupernovaMetaEngine() : AdvancedMetaEngine(Supernova::gameDescriptions, sizeof(ADGameDescription), supernovaGames) {
// _singleId = "supernova";
}
virtual const char *getName() const {
return "Supernova Engine";
}
virtual const char *getOriginalCopyright() const {
return "Mission Supernova (c) 1994 Thomas and Steffen Dingel";
}
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
virtual SaveStateList listSaves(const char *target) const;
virtual void removeSaveState(const char *target, int slot) const;
virtual int getMaximumSaveSlot() const {
return 99;
}
virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
bool SupernovaMetaEngine::hasFeature(MetaEngineFeature f) const {
switch (f) {
case kSupportsLoadingDuringStartup:
// fallthrough
case kSupportsListSaves:
// fallthrough
case kSupportsDeleteSave:
// fallthrough
case kSavesSupportMetaInfo:
// fallthrough
case kSavesSupportThumbnail:
// fallthrough
case kSavesSupportCreationDate:
// fallthrough
case kSavesSupportPlayTime:
return true;
default:
return false;
}
}
bool SupernovaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc) {
*engine = new Supernova::SupernovaEngine(syst);
}
return desc != NULL;
}
SaveStateList SupernovaMetaEngine::listSaves(const char *target) const {
Common::StringArray filenames;
Common::String pattern("msn_save.###");
filenames = g_system->getSavefileManager()->listSavefiles(pattern);
SaveStateList saveFileList;
for (Common::StringArray::const_iterator file = filenames.begin();
file != filenames.end(); ++file) {
int saveSlot = atoi(file->c_str() + file->size() - 3);
if (saveSlot >= 0 && saveSlot <= getMaximumSaveSlot()) {
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(*file);
if (savefile) {
uint saveHeader = savefile->readUint32LE();
if (saveHeader == SAVEGAME_HEADER) {
byte saveVersion = savefile->readByte();
if (saveVersion <= SAVEGAME_VERSION) {
int saveFileDescSize = savefile->readSint16LE();
char* saveFileDesc = new char[saveFileDescSize];
savefile->read(saveFileDesc, saveFileDescSize);
saveFileList.push_back(SaveStateDescriptor(saveSlot, saveFileDesc));
delete [] saveFileDesc;
}
}
delete savefile;
}
}
}
Common::sort(saveFileList.begin(), saveFileList.end(), SaveStateDescriptorSlotComparator());
return saveFileList;
}
void SupernovaMetaEngine::removeSaveState(const char *target, int slot) const {
Common::String filename = Common::String::format("msn_save.%03d", slot);
g_system->getSavefileManager()->removeSavefile(filename);
}
SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String fileName = Common::String::format("msn_save.%03d", slot);
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(fileName);
if (savefile) {
uint saveHeader = savefile->readUint32LE();
if (saveHeader != SAVEGAME_HEADER) {
delete savefile;
return SaveStateDescriptor();
}
byte saveVersion = savefile->readByte();
if (saveVersion > SAVEGAME_VERSION){
delete savefile;
return SaveStateDescriptor();
}
int descriptionSize = savefile->readSint16LE();
char* description = new char[descriptionSize];
savefile->read(description, descriptionSize);
SaveStateDescriptor desc(slot, description);
delete [] description;
uint32 saveDate = savefile->readUint32LE();
int day = (saveDate >> 24) & 0xFF;
int month = (saveDate >> 16) & 0xFF;
int year = saveDate & 0xFFFF;
desc.setSaveDate(year, month, day);
uint16 saveTime = savefile->readUint16LE();
int hour = (saveTime >> 8) & 0xFF;
int minutes = saveTime & 0xFF;
desc.setSaveTime(hour, minutes);
uint32 playTime =savefile->readUint32LE();
desc.setPlayTime(playTime * 1000);
if (Graphics::checkThumbnailHeader(*savefile)) {
Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*savefile);
desc.setThumbnail(thumbnail);
}
delete savefile;
return desc;
}
return SaveStateDescriptor();
}
#if PLUGIN_ENABLED_DYNAMIC(SUPERNOVA)
REGISTER_PLUGIN_DYNAMIC(SUPERNOVA, PLUGIN_TYPE_ENGINE, SupernovaMetaEngine);
#else
REGISTER_PLUGIN_STATIC(SUPERNOVA, PLUGIN_TYPE_ENGINE, SupernovaMetaEngine);
#endif

View File

@ -0,0 +1,256 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/algorithm.h"
#include "common/file.h"
#include "common/stream.h"
#include "common/system.h"
#include "common/config-manager.h"
#include "graphics/palette.h"
#include "graphics/surface.h"
#include "graphics.h"
#include "msn_def.h"
#include "supernova.h"
namespace Supernova {
MSNImageDecoder::MSNImageDecoder() {
_palette = nullptr;
_encodedImage = nullptr;
_filenumber = -1;
_pitch = 0;
_numSections = 0;
_numClickFields = 0;
}
MSNImageDecoder::~MSNImageDecoder() {
destroy();
}
bool MSNImageDecoder::init(int filenumber) {
Common::File file;
if (!file.open(Common::String::format("msn_data.%03d", filenumber))) {
warning("Image data file msn_data.%03d could not be read!", filenumber);
return false;
}
_filenumber = filenumber;
loadStream(file);
return true;
}
bool MSNImageDecoder::loadFromEngineDataFile() {
Common::String name;
if (_filenumber == 1)
name = "IMG1";
else if (_filenumber == 2)
name = "IMG2";
else
return false;
Common::String cur_lang = ConfMan.get("language");
// Note: we don't print any warning or errors here if we cannot find the file
// or the format is not as expected. We will get those warning when reading the
// strings anyway (actually the engine will even refuse to start).
Common::File f;
if (!f.open(SUPERNOVA_DAT))
return false;
char id[5], lang[5];
id[4] = lang[4] = '\0';
f.read(id, 3);
if (strncmp(id, "MSN", 3) != 0)
return false;
int version = f.readByte();
if (version != SUPERNOVA_DAT_VERSION)
return false;
while (!f.eos()) {
f.read(id, 4);
f.read(lang, 4);
uint32 size = f.readUint32LE();
if (f.eos())
break;
if (name == id && cur_lang == lang) {
return f.read(_encodedImage, size) == size;
} else
f.skip(size);
}
return false;
}
bool MSNImageDecoder::loadStream(Common::SeekableReadStream &stream) {
destroy();
uint size = 0;
size = (stream.readUint16LE() + 0xF) >> 4;
size |= (stream.readUint16LE() & 0xF) << 12;
size += 0x70; // zus_paragraph
size *= 16; // a paragraph is 16 bytes
_encodedImage = new byte[size];
_palette = new byte[717];
g_system->getPaletteManager()->grabPalette(_palette, 16, 239);
byte pal_diff;
byte flag = stream.readByte();
if (flag == 0) {
pal_diff = 0;
_palette[141] = 0xE0;
_palette[142] = 0xE0;
_palette[143] = 0xE0;
} else {
pal_diff = 1;
for (int i = flag * 3; i != 0; --i) {
_palette[717 - i] = stream.readByte() << 2;
}
}
_numSections = stream.readByte();
for (uint i = 0; i < kMaxSections; ++i) {
_section[i].addressHigh = 0xff;
_section[i].addressLow = 0xffff;
_section[i].x2 = 0;
_section[i].next = 0;
}
for (int i = 0; i < _numSections; ++i) {
_section[i].x1 = stream.readUint16LE();
_section[i].x2 = stream.readUint16LE();
_section[i].y1 = stream.readByte();
_section[i].y2 = stream.readByte();
_section[i].next = stream.readByte();
_section[i].addressLow = stream.readUint16LE();
_section[i].addressHigh = stream.readByte();
}
_numClickFields = stream.readByte();
for (int i = 0; i < _numClickFields; ++i) {
_clickField[i].x1 = stream.readUint16LE();
_clickField[i].x2 = stream.readUint16LE();
_clickField[i].y1 = stream.readByte();
_clickField[i].y2 = stream.readByte();
_clickField[i].next = stream.readByte();
}
for (int i = _numClickFields; i < kMaxClickFields; ++i) {
_clickField[i].x1 = 0;
_clickField[i].x2 = 0;
_clickField[i].y1 = 0;
_clickField[i].y2 = 0;
_clickField[i].next = 0;
}
// Newspaper images may be in the engine data file. So first try to read
// it from there.
if (!loadFromEngineDataFile()) {
// Load the image from the stream
byte zwCodes[256] = {0};
byte numRepeat = stream.readByte();
byte numZw = stream.readByte();
stream.read(zwCodes, numZw);
numZw += numRepeat;
byte input = 0;
uint i = 0;
while (stream.read(&input, 1)) {
if (input < numRepeat) {
++input;
byte value = stream.readByte();
for (--value; input > 0; --input) {
_encodedImage[i++] = value;
}
} else if (input < numZw) {
input = zwCodes[input - numRepeat];
--input;
_encodedImage[i++] = input;
_encodedImage[i++] = input;
} else {
input -= pal_diff;
_encodedImage[i++] = input;
}
}
}
loadSections();
return true;
}
bool MSNImageDecoder::loadSections() {
bool isNewspaper = _filenumber == 1 || _filenumber == 2;
int imageWidth = isNewspaper ? 640 : 320;
int imageHeight = isNewspaper ? 480 : 200;
_pitch = imageWidth;
for (int section = 0; section < _numSections; ++section) {
Graphics::Surface *surface = new Graphics::Surface;
_sectionSurfaces.push_back(surface);
if (isNewspaper) {
surface->create(imageWidth, imageHeight, g_system->getScreenFormat());
byte *surfacePixels = static_cast<byte *>(surface->getPixels());
for (int i = 0; i < imageWidth * imageHeight / 8; ++i) {
*surfacePixels++ = (_encodedImage[i] & 0x80) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x40) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x20) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x10) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x08) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x04) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x02) ? kColorWhite63 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x01) ? kColorWhite63 : kColorBlack;
}
} else {
uint32 offset = (_section[section].addressHigh << 16) + _section[section].addressLow;
if (offset == kInvalidAddress || _section[section].x2 == 0) {
return false;
}
int width = _section[section].x2 - _section[section].x1 + 1;
int height = _section[section].y2 - _section[section].y1 + 1;
surface->create(width, height, g_system->getScreenFormat());
byte *surfacePixels = static_cast<byte *>(surface->getPixels());
Common::copy(_encodedImage + offset, _encodedImage + offset + width * height, surfacePixels);
}
}
return true;
}
void MSNImageDecoder::destroy() {
if (_palette) {
delete[] _palette;
_palette = NULL;
}
if (_encodedImage) {
delete[] _encodedImage;
_encodedImage = NULL;
}
for (Common::Array<Graphics::Surface *>::iterator it = _sectionSurfaces.begin();
it != _sectionSurfaces.end(); ++it) {
(*it)->free();
}
}
}

View File

@ -0,0 +1,87 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SUPERNOVA_GRAPHICS_H
#define SUPERNOVA_GRAPHICS_H
#include "common/scummsys.h"
#include "image/image_decoder.h"
namespace Common {
class SeekableReadStream;
}
namespace Graphics {
struct Surface;
}
namespace Supernova {
class MSNImageDecoder : public Image::ImageDecoder {
public:
MSNImageDecoder();
virtual ~MSNImageDecoder();
virtual void destroy();
virtual bool loadStream(Common::SeekableReadStream &stream);
virtual const Graphics::Surface *getSurface() const { return _sectionSurfaces[0]; }
virtual const byte *getPalette() const { return _palette; }
bool init(int filenumber);
static const int kMaxSections = 50;
static const int kMaxClickFields = 80;
static const uint32 kInvalidAddress = 0x00FFFFFF;
int _filenumber;
int _pitch;
int _numSections;
int _numClickFields;
Common::Array<Graphics::Surface *> _sectionSurfaces;
byte *_palette;
byte *_encodedImage;
struct Section {
int16 x1;
int16 x2;
byte y1;
byte y2;
byte next;
uint16 addressLow;
byte addressHigh;
} _section[kMaxSections];
struct ClickField {
int16 x1;
int16 x2;
byte y1;
byte y2;
byte next;
} _clickField[kMaxClickFields];
private:
bool loadFromEngineDataFile();
bool loadSections();
};
}
#endif

View File

@ -0,0 +1,20 @@
MODULE := engines/supernova
MODULE_OBJS := \
console.o \
detection.o \
graphics.o \
supernova.o \
rooms.o \
state.o
MODULE_DIRS += \
engines/supernova
# This module can be built as a plugin
ifeq ($(ENABLE_SUPERNOVA), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk

643
engines/supernova/msn_def.h Normal file
View File

@ -0,0 +1,643 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SUPERNOVA_MSN_DEF_H
#define SUPERNOVA_MSN_DEF_H
namespace Supernova {
const int kScreenWidth = 320;
const int kScreenHeight = 200;
const int kFontWidth = 5;
const int kFontHeight = 8;
const int kTextSpeed[] = {19, 14, 10, 7, 4};
const int kMsecPerTick = 55;
const int kMaxSection = 40;
const int kMaxDialog = 2;
const int kMaxObject = 25;
const int kMaxCarry = 30;
const int kSleepAutosaveSlot = 999;
const byte kShownFalse = 0;
const byte kShownTrue = 1;
enum MessagePosition {
kMessageNormal,
kMessageLeft,
kMessageRight,
kMessageCenter,
kMessageTop
};
enum AudioIndex {
kAudioFoundLocation, // 44|0
kAudioCrash, // 45|0
kAudioVoiceHalt, // 46|0
kAudioGunShot, // 46|2510
kAudioSmash, // 46|4020
kAudioVoiceSupernova, // 47|0
kAudioVoiceYeah, // 47|24010
kAudioRobotShock, // 48|0
kAudioRobotBreaks, // 48|2510
kAudioShock, // 48|10520
kAudioTurntable, // 48|13530
kAudioSiren, // 50|0
kAudioSnoring, // 50|12786
kAudioRocks, // 51|0
kAudioDeath, // 53|0
kAudioAlarm, // 54|0
kAudioSuccess, // 54|8010
kAudioSlideDoor, // 54|24020
kAudioDoorOpen, // 54|30030
kAudioDoorClose, // 54|31040
kAudioNumSamples
};
enum MusicIndex {
kMusicIntro = 52,
kMusicOutro = 49
};
struct AudioInfo {
int _filenumber;
int _offsetStart;
int _offsetEnd;
};
const int kColorBlack = 0;
const int kColorWhite25 = 1;
const int kColorWhite35 = 2;
const int kColorWhite44 = 3;
const int kColorWhite99 = 4;
const int kColorDarkGreen = 5;
const int kColorGreen = 6;
const int kColorDarkRed = 7;
const int kColorRed = 8;
const int kColorDarkBlue = 9;
const int kColorBlue = 10;
const int kColorWhite63 = 11;
const int kColorLightBlue = 12;
const int kColorLightGreen = 13;
const int kColorLightYellow = 14;
const int kColorLightRed = 15;
const int kColorCursorTransparent = kColorWhite25;
const byte mouseNormal[64] = {
0xff,0x3f,0xff,0x1f,0xff,0x0f,0xff,0x07,
0xff,0x03,0xff,0x01,0xff,0x00,0x7f,0x00,
0x3f,0x00,0x1f,0x00,0x0f,0x00,0x0f,0x00,
0xff,0x00,0x7f,0x18,0x7f,0x38,0x7f,0xfc,
0x00,0x00,0x00,0x40,0x00,0x60,0x00,0x70,
0x00,0x78,0x00,0x7c,0x00,0x7e,0x00,0x7f,
0x80,0x7f,0xc0,0x7f,0xe0,0x7f,0x00,0x7e,
0x00,0x66,0x00,0x43,0x00,0x03,0x00,0x00
};
const byte mouseWait[64] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
0x01,0x80,0x01,0x80,0x11,0x88,0x31,0x8c,
0x31,0x8c,0x11,0x88,0x01,0x80,0x01,0x80,
0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0x7f,0xf4,0x2f,0xf4,0x2f,
0x14,0x28,0x24,0x24,0x44,0x22,0x84,0x21,
0x84,0x21,0xc4,0x23,0xe4,0x27,0x74,0x2e,
0x34,0x2c,0x14,0x28,0xfe,0x7f,0x00,0x00
};
const byte font[][5] = {
{0x00,0x00,0x00,0xff,0x00},
{0x5f,0xff,0x00,0x00,0x00},
{0x03,0x00,0x03,0xff,0x00},
{0x14,0x7f,0x14,0x7f,0x14},
{0x24,0x2a,0x7f,0x2a,0x12},
{0x61,0x10,0x08,0x04,0x43},
{0x38,0x4e,0x59,0x26,0x50},
{0x03,0xff,0x00,0x00,0x00},
{0x3e,0x41,0xff,0x00,0x00},
{0x41,0x3e,0xff,0x00,0x00},
{0x10,0x54,0x38,0x54,0x10},
{0x10,0x10,0x7c,0x10,0x10},
{0x80,0x40,0xff,0x00,0x00},
{0x10,0x10,0x10,0x10,0x10},
{0x40,0xff,0x00,0x00,0x00},
{0x60,0x10,0x08,0x04,0x03},
{0x3e,0x41,0x41,0x41,0x3e}, /* digits */
{0x04,0x02,0x7f,0xff,0x00},
{0x42,0x61,0x51,0x49,0x46},
{0x22,0x41,0x49,0x49,0x36},
{0x18,0x14,0x12,0x7f,0x10},
{0x27,0x45,0x45,0x45,0x39},
{0x3e,0x49,0x49,0x49,0x32},
{0x01,0x61,0x19,0x07,0x01},
{0x36,0x49,0x49,0x49,0x36},
{0x26,0x49,0x49,0x49,0x3e},
{0x44,0xff,0x00,0x00,0x00},
{0x80,0x44,0xff,0x00,0x00},
{0x10,0x28,0x44,0xff,0x00},
{0x28,0x28,0x28,0x28,0x28},
{0x44,0x28,0x10,0xff,0x00},
{0x02,0x01,0x51,0x09,0x06},
{0x3e,0x41,0x5d,0x5d,0x1e},
{0x7c,0x12,0x11,0x12,0x7c}, /* uppercase letters*/
{0x7f,0x49,0x49,0x49,0x36},
{0x3e,0x41,0x41,0x41,0x22},
{0x7f,0x41,0x41,0x22,0x1c},
{0x7f,0x49,0x49,0x49,0xff},
{0x7f,0x09,0x09,0x09,0xff},
{0x3e,0x41,0x41,0x49,0x3a},
{0x7f,0x08,0x08,0x08,0x7f},
{0x41,0x7f,0x41,0xff,0x00},
{0x20,0x40,0x40,0x3f,0xff},
{0x7f,0x08,0x14,0x22,0x41},
{0x7f,0x40,0x40,0x40,0xff},
{0x7f,0x02,0x04,0x02,0x7f},
{0x7f,0x02,0x0c,0x10,0x7f},
{0x3e,0x41,0x41,0x41,0x3e},
{0x7f,0x09,0x09,0x09,0x06},
{0x3e,0x41,0x51,0x21,0x5e},
{0x7f,0x09,0x19,0x29,0x46},
{0x26,0x49,0x49,0x49,0x32},
{0x01,0x01,0x7f,0x01,0x01},
{0x3f,0x40,0x40,0x40,0x3f},
{0x07,0x18,0x60,0x18,0x07},
{0x1f,0x60,0x18,0x60,0x1f},
{0x63,0x14,0x08,0x14,0x63},
{0x03,0x04,0x78,0x04,0x03},
{0x61,0x51,0x49,0x45,0x43},
{0x7f,0x41,0x41,0xff,0x00},
{0x03,0x04,0x08,0x10,0x60},
{0x41,0x41,0x7f,0xff,0x00},
{0x02,0x01,0x02,0xff,0x00},
{0x80,0x80,0x80,0x80,0x80},
{0x01,0x02,0xff,0x00,0x00},
{0x38,0x44,0x44,0x44,0x7c}, /* lowercase letters */
{0x7f,0x44,0x44,0x44,0x38},
{0x38,0x44,0x44,0x44,0x44},
{0x38,0x44,0x44,0x44,0x7f},
{0x38,0x54,0x54,0x54,0x58},
{0x04,0x7e,0x05,0x01,0xff},
{0x98,0xa4,0xa4,0xa4,0x7c},
{0x7f,0x04,0x04,0x04,0x78},
{0x7d,0xff,0x00,0x00,0x00},
{0x80,0x80,0x7d,0xff,0x00},
{0x7f,0x10,0x28,0x44,0xff},
{0x7f,0xff,0x00,0x00,0x00},
{0x7c,0x04,0x7c,0x04,0x78},
{0x7c,0x04,0x04,0x04,0x78},
{0x38,0x44,0x44,0x44,0x38},
{0xfc,0x24,0x24,0x24,0x18},
{0x18,0x24,0x24,0x24,0xfc},
{0x7c,0x08,0x04,0x04,0xff},
{0x48,0x54,0x54,0x54,0x24},
{0x04,0x3e,0x44,0x40,0xff},
{0x7c,0x40,0x40,0x40,0x3c},
{0x0c,0x30,0x40,0x30,0x0c},
{0x3c,0x40,0x3c,0x40,0x3c},
{0x44,0x28,0x10,0x28,0x44},
{0x9c,0xa0,0xa0,0xa0,0x7c},
{0x44,0x64,0x54,0x4c,0x44},
{0x08,0x36,0x41,0xff,0x00},
{0x77,0xff,0x00,0x00,0x00},
{0x41,0x36,0x08,0xff,0x00},
{0x02,0x01,0x02,0x01,0xff},
{0xff,0x00,0x00,0x00,0x00},
{0xfe,0x49,0x49,0x4e,0x30}, /* sharp S */
{0x7c,0x41,0x40,0x41,0x3c}, /* umlauts */
{0x04,0x06,0x7f,0x06,0x04}, /* arrows */
{0x20,0x60,0xfe,0x60,0x20},
{0x38,0x45,0x44,0x45,0x7c}, /* umlauts */
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x79,0x14,0x12,0x14,0x79},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x38,0x45,0x44,0x45,0x38},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x3d,0x42,0x42,0x42,0x3d},
{0x3d,0x40,0x40,0x40,0x3d},
};
// Default palette
const byte initVGAPalette[768] = {
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x58, 0x58, 0x58, 0x70, 0x70, 0x70, 0xfc, 0xfc, 0xfc, 0x00, 0xd0, 0x00,
0x00, 0xfc, 0x00, 0xd8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xb0, 0xa0, 0xa0, 0xa0,
0x50, 0xc8, 0xfc, 0x28, 0xfc, 0x28, 0xf0, 0xf0, 0x00, 0xfc, 0x28, 0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14,
0x20, 0x20, 0x20, 0x2c, 0x2c, 0x2c, 0x38, 0x38, 0x38, 0x44, 0x44, 0x44, 0x50, 0x50, 0x50, 0x60, 0x60, 0x60,
0x70, 0x70, 0x70, 0x80, 0x80, 0x80, 0x90, 0x90, 0x90, 0xa0, 0xa0, 0xa0, 0xb4, 0xb4, 0xb4, 0xc8, 0xc8, 0xc8,
0xe0, 0xe0, 0xe0, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc,
0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00,
0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00,
0x00, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc,
0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc,
0xfc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c,
0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c,
0x7c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc,
0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc,
0xfc, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4,
0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4,
0xb4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc,
0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70,
0x70, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00,
0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00,
0x00, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70,
0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70,
0x70, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38,
0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38,
0x38, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70,
0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70,
0x70, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50,
0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50,
0x50, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70,
0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40,
0x40, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00,
0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00,
0x00, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40,
0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40,
0x40, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20,
0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20,
0x20, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40,
0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40,
0x40, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c,
0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c,
0x2c, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40,
0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
enum ObjectType {
NULLTYPE = 0,
TAKE = 1,
OPENABLE = 2,
OPENED = 4,
CLOSED = 8,
EXIT = 16,
PRESS = 32,
COMBINABLE = 64,
CARRIED = 128,
UNNECESSARY = 256,
WORN = 512,
TALK = 1024,
OCCUPIED = 2048,
CAUGHT = 4096
};
typedef uint16 ObjectTypes;
enum Action {
ACTION_WALK,
ACTION_LOOK,
ACTION_TAKE,
ACTION_OPEN,
ACTION_CLOSE,
ACTION_PRESS,
ACTION_PULL,
ACTION_USE,
ACTION_TALK,
ACTION_GIVE
};
enum RoomID {
INTRO,CORRIDOR,HALL,SLEEP,COCKPIT,AIRLOCK,
HOLD,LANDINGMODULE,GENERATOR,OUTSIDE,
CABIN_R1,CABIN_R2,CABIN_R3,CABIN_L1,CABIN_L2,CABIN_L3,BATHROOM,
ROCKS,CAVE,MEETUP,ENTRANCE,REST,ROGER,GLIDER,MEETUP2,MEETUP3,
CELL,CORRIDOR1,CORRIDOR2,CORRIDOR3,CORRIDOR4,CORRIDOR5,CORRIDOR6,CORRIDOR7,CORRIDOR8,CORRIDOR9,
BCORRIDOR,GUARD,GUARD3,OFFICE_L1,OFFICE_L2,OFFICE_R1,OFFICE_R2,OFFICE_L,
ELEVATOR,STATION,SIGN,OUTRO,NUMROOMS,NULLROOM
};
enum ObjectID {
INVALIDOBJECT = -1,
NULLOBJECT = 0,
KEYCARD,KNIFE,WATCH,
SOCKET,
BUTTON,HATCH1,
BUTTON1,BUTTON2,MANOMETER,SUIT,HELMET,LIFESUPPORT,
SCRAP_LK,OUTERHATCH_TOP,GENERATOR_TOP,TERMINALSTRIP,LANDINGMOD_OUTERHATCH,
HOLD_WIRE,
LANDINGMOD_BUTTON,LANDINGMOD_SOCKET,LANDINGMOD_WIRE,LANDINGMOD_HATCH,LANDINGMOD_MONITOR,
KEYBOARD,
KEYCARD2,OUTERHATCH,GENERATOR_WIRE,TRAP,SHORT_WIRE,CLIP,
VOLTMETER,LADDER,GENERATOR_ROPE,
KITCHEN_HATCH,SLEEP_SLOT,
MONITOR,INSTRUMENTS,
COMPUTER,CABINS,CABIN,
SLOT_K1,SLOT_K2,SLOT_K3,SLOT_K4,
SHELF1,SHELF2,SHELF3,SHELF4,
ROPE,BOOK,DISCMAN,CHESS,
SLOT_KL1,SLOT_KL2,SLOT_KL3,SLOT_KL4,
SHELF_L1,SHELF_L2,SHELF_L3,SHELF_L4,
PISTOL,BOOK2,SPOOL,
RECORD,TURNTABLE,TURNTABLE_BUTTON,WIRE,WIRE2,PLUG,
PEN,
BATHROOM_DOOR,BATHROOM_EXIT,SHOWER,TOILET,
STONE,
SPACESHIPS,SPACESHIP,STAR,DOOR,MEETUP_SIGN,
PORTER,BATHROOM_BUTTON,BATHROOM_SIGN,KITCHEN_SIGN,CAR_SLOT,
ARSANO_BATHROOM,COINS,SCHNUCK,EGG,PILL,PILL_HULL,STAIRCASE,
MEETUP_EXIT,
ROGER_W,WALLET,KEYCARD_R,CUP,
GLIDER_BUTTON1,GLIDER_BUTTON2,GLIDER_BUTTON3,GLIDER_BUTTON4,GLIDER_SLOT,GLIDER_BUTTONS,
GLIDER_DISPLAY,GLIDER_INSTRUMENTS,GLIDER_KEYCARD,
UFO,
CELL_BUTTON,CELL_TABLE,CELL_WIRE,TRAY,CELL_DOOR,MAGNET,
NEWSPAPER,TABLE,
PILLAR1,PILLAR2,DOOR1,DOOR2,DOOR3,DOOR4,
GUARDIAN,LAMP,
MASTERKEYCARD,PAINTING,MONEY,LOCKER,LETTER,
JUNGLE,STATION_SLOT,STATION_SIGN
};
enum StringID {
kNoString = -1,
// 0
kStringCommandGo = 0, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose,
kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive,
kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose,
kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive,
kStringTitleVersion, kStringTitle1, kStringTitle2, kStringTitle3, kStringIntro1,
kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, kStringIntro6,
kStringIntro7, kStringIntro8, kStringIntro9, kStringIntro10, kStringIntro11,
kStringIntro12, kStringIntro13, kStringBroken, kStringDefaultDescription, kStringTakeMessage,
kStringKeycard, kStringKeycardDescription, kStringKnife, kStringKnifeDescription, kStringWatch,
kStringDiscman, kStringDiscmanDescription, kStringHatch, kStringButton, kStringHatchButtonDescription,
// 50
kStringLadder, kStringExit, kStringCockpitHatchDescription, kStringKitchenHatchDescription, kStringStasisHatchDescription,
kStringStasisHatchDescription2, kStringSlot, kStringSlotDescription, kStringCorridor, kStringComputer,
kStringComputerPassword, kStringInstruments, kStringInstrumentsDescription1, kStringMonitor, kStringMonitorDescription,
kStringImage, kStringGenericDescription1, kStringGenericDescription2, kStringGenericDescription3, kStringGenericDescription4,
kStringMagnete, kStringMagneteDescription, kStringPen, kStringPenDescription, kStringShelf,
kStringCompartment, kStringSocket, kStringToilet, kStringPistol, kStringPistolDescription,
kStringBooks, kStringBooksDescription, kStringSpool, kStringSpoolDescription, kStringBook,
kStringUnderwear, kStringUnderwearDescription, kStringClothes, kStringJunk, kStringJunkDescription,
kStringFolders, kStringFoldersDescription, kStringPoster, kStringPosterDescription1, kStringPosterDescription2,
kStringSpeaker, kStringRecord, kStringRecordDescription, kStringRecordStand, kStringRecordStandDescription,
// 100
kStringTurntable, kStringTurntableDescription, kStringWire, kStringPlug, kStringImageDescription1,
kStringDrawingInstruments, kStringDrawingInstrumentsDescription, kStringChessGame, kStringChessGameDescription1, kStringTennisRacket,
kStringTennisRacketDescription, kStringTennisBall, kStringChessGameDescription2, kStringBed, kStringBedDescription,
kStringCompartmentDescription, kStringAlbums, kStringAlbumsDescription, kStringRope, kStringRopeDescription,
kStringShelfDescription, kStringClothesDescription, kStringSocks, kStringBookHitchhiker, kStringBathroom,
kStringBathroomDescription, kStringShower, kStringHatchDescription1, kStringHatchDescription2, kStringHelmet,
kStringHelmetDescription, kStringSuit, kStringSuitDescription, kStringLifeSupport, kStringLifeSupportDescription,
kStringScrap, kStringScrapDescription1, kStringTerminalStrip, kStringScrapDescription2, kStringReactor,
kStringReactorDescription, kStringNozzle, kStringPumpkin, kStringPumpkinDescription, kStringLandingModule,
kStringLandingModuleDescription, kStringHatchDescription3, kStringGenerator, kStringGeneratorDescription, kStringScrapDescription3,
// 150
kSafetyButtonDescription, kStringKeyboard, kStringGeneratorWire, kStringEmptySpool, kStringKeycard2,
kStringKeycard2Description, kStringTrap, kStringVoltmeter, kStringClip, kStringWireDescription,
kStringStone, kStringCaveOpening, kStringCaveOpeningDescription, kStringExitDescription, kStringCave,
kStringSign, kStringSignDescription, kStringEntrance, kStringStar, kStringSpaceshift,
kStringPorter, kStringPorterDescription, kStringDoor, kStringChewingGum, kStringGummyBears,
kStringChocolateBall, kStringEgg, kStringLiquorice, kStringPill, kStringPillDescription,
kStringVendingMachine, kStringVendingMachineDescription, kStringToiletDescription, kStringStaircase, kStringCoins,
kStringCoinsDescription, kStringTabletPackage, kStringTabletPackageDescription, kStringChair, kStringShoes,
kStringShoesDescription, kStringFrogFace, kStringScrible, kStringScribleDescription, kStringWallet,
kStringMenu, kStringMenuDescription, kStringCup, kStringCupDescription, kStringBill,
// 200
kStringBillDescription, kStringKeycard3, kStringAnnouncement, kStringAnnouncementDescription, kStringRoger,
kStringUfo, kStringUfoDescription, kStringTray, kStringTrayDescription, kStringLamp,
kStringLampDescription, kStringEyes, kStringEyesDescription, kStringSocketDescription, kStringMetalBlock,
kStringMetalBlockDescription, kStringRobot, kStringRobotDescription, kStringTable, kStringTableDescription,
kStringCellDoor, kStringCellDoorDescription, kStringLaptop, kStringWristwatch, kStringPillar,
kStringDoorDescription1, kStringDoorDescription2, kStringDoorDescription3, kStringDoorDescription4, kStringDontEnter,
kStringAxacussan, kStringAxacussanDescription, kStringImageDescription2, kStringMastercard, kStringMastercardDescription,
kStringLamp2, kStringGenericDescription5, kStringMoney, kStringMoneyDescription1, kStringLocker,
kStringLockerDescription, kStringLetter, kStringCube, kStringGenericDescription6, kStringGenericDescription7,
kStringStrangeThing, kStringGenericDescription8, kStringImageDescription3, kStringPlant, kStringStatue,
// 250
kStringStatueDescription, kStringPlantDescription, kStringComputerDescription, kStringGraffiti, kStringGraffitiDescription,
kStringMoneyDescription2, kStringJungle, kStringJungleDescription, kStringOutro1, kStringOutro2,
kStringOutro3, kStringOutro4, kStringOutro5, kStringOutro6, kStringOutro7,
kStringOutro8, kStringOutro9, kStringOutro10, kStringOutro11, kStringOutro12,
kStringOutro13, kStringOutro14, kStringWireAndPlug, kStringWireAndClip, kStringWireAndPlug2,
// 275
kStringSignDescription2, kStringCoin, kStringDoorDescription5, kStringDoorDescription6, kStringKeycard2Description2,
kSringSpoolAndClip, kStringIntroCutscene1, kStringIntroCutscene2, kStringIntroCutscene3, kStringIntroCutscene4,
kStringIntroCutscene5, kStringIntroCutscene6, kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9,
kStringIntroCutscene10, kStringIntroCutscene11, kStringIntroCutscene12, kStringIntroCutscene13, kStringIntroCutscene14,
kStringIntroCutscene15, kStringIntroCutscene16, kStringIntroCutscene17, kStringIntroCutscene18, kStringIntroCutscene19,
// 300
kStringIntroCutscene20, kStringIntroCutscene21, kStringIntroCutscene22, kStringIntroCutscene23, kStringIntroCutscene24,
kStringIntroCutscene25, kStringIntroCutscene26, kStringIntroCutscene27, kStringIntroCutscene28, kStringIntroCutscene29,
kStringIntroCutscene30, kStringIntroCutscene31, kStringIntroCutscene32, kStringIntroCutscene33, kStringIntroCutscene34,
kStringIntroCutscene35, kStringIntroCutscene36, kStringIntroCutscene37, kStringIntroCutscene38, kStringIntroCutscene39,
kStringIntroCutscene40, kStringIntroCutscene41, kStringIntroCutscene42, kStringShipHall1, kStringShipSleepCabin1,
//325
kStringShipSleepCabin2, kStringShipSleepCabin3, kStringShipSleepCabin4, kStringShipSleepCabin5, kStringShipSleepCabin6,
kStringShipSleepCabin7, kStringShipSleepCabin8, kStringShipSleepCabin9, kStringShipSleepCabin10, kStringShipSleepCabin11,
kStringShipSleepCabin12, kStringShipSleepCabin13, kStringShipSleepCabin14, kStringShipSleepCabin15, kStringShipSleepCabin16,
kStringShipCockpit1, kStringShipCockpit2, kStringShipCockpit3, kStringShipCockpit4, kStringShipCockpit5,
kStringShipCockpit6, kStringShipCockpit7, kStringShipCockpit8, kStringShipCockpit9, kStringShipCockpit10,
// 350
kStringShipCockpit11, kStringShipCockpit12, kStringShipCockpit13, kStringShipCabinL3_1, kStringShipCabinL3_2,
kStringShipCabinL3_3, kStringShipCabinL3_4, kStringShipCabinL3_5, kStringShipAirlock1, kStringShipAirlock2,
kStringShipAirlock3, kStringShipAirlock4, kStringShipHold1, kStringCable1, kStringCable2,
kStringCable3, kStringCable4, kStringShipHold2, kStringShipHold3, kStringShipHold4,
kStringShipHold5, kStringShipHold6, kStringShipHold7, kStringShipHold8, kStringShipHold9,
// 375
kStringShipHold10, kStringShipHold11, kStringShipHold12, kStringShipHold13, kStringShipHold14,
kStringShipHold15, kStringShipHold16, kStringArsanoMeetup1, kStringArsanoMeetup2, kStringArsanoMeetup3,
kStringArsanoEntrance1, kStringArsanoEntrance2, kStringArsanoEntrance3, kStringArsanoEntrance4, kStringArsanoEntrance5,
kStringArsanoEntrance6, kStringArsanoEntrance7, kStringArsanoEntrance8, kStringArsanoEntrance9, kStringArsanoEntrance10,
kStringArsanoEntrance11, kStringArsanoEntrance12, kStringArsanoEntrance13, kStringArsanoEntrance14, kStringArsanoEntrance15,
// 400
kStringArsanoEntrance16, kStringArsanoEntrance17, kStringArsanoEntrance18, kStringArsanoEntrance19, kStringArsanoEntrance20,
kStringArsanoEntrance21, kStringArsanoEntrance22, kStringArsanoEntrance23, kStringArsanoEntrance24, kStringArsanoEntrance25,
kStringArsanoEntrance26, kStringArsanoEntrance27, kStringArsanoDialog1, kStringArsanoDialog2, kStringArsanoDialog3,
kStringArsanoDialog4, kStringArsanoDialog5, kStringArsanoDialog6, kStringArsanoDialog7, kStringArsanoDialog8,
kStringArsanoDialog9, kStringDialogSeparator, kStringDialogArsanoRoger1, kStringDialogArsanoRoger2, kStringDialogArsanoRoger3,
// 425
kStringDialogArsanoMeetup3_1, kStringDialogArsanoMeetup3_2, kStringDialogArsanoMeetup3_3, kStringDialogArsanoMeetup3_4, kStringDialogArsanoMeetup3_5,
kStringArsanoRoger1, kStringArsanoRoger2, kStringArsanoRoger3, kStringArsanoRoger4, kStringArsanoRoger5,
kStringArsanoRoger6, kStringArsanoRoger7, kStringArsanoRoger8, kStringArsanoRoger9, kStringArsanoRoger10,
kStringArsanoRoger11, kStringArsanoRoger12, kStringArsanoRoger13, kStringArsanoRoger14, kStringArsanoRoger15,
kStringArsanoRoger16, kStringArsanoRoger17, kStringArsanoRoger18, kStringArsanoRoger19, kStringArsanoRoger20,
// 450
kStringArsanoRoger21, kStringArsanoRoger22, kStringArsanoRoger23, kStringArsanoRoger24, kStringArsanoRoger25,
kStringArsanoRoger26, kStringArsanoRoger27, kStringArsanoRoger28, kStringArsanoRoger29, kStringArsanoRoger30,
kStringArsanoRoger31, kStringArsanoRoger32, kStringArsanoRoger33, kStringArsanoRoger34, kStringArsanoRoger35,
kStringArsanoRoger36, kStringArsanoRoger37, kStringArsanoRoger38, kStringArsanoRoger39, kStringArsanoRoger40,
kStringArsanoGlider1, kStringArsanoMeetup2_1, kStringArsanoMeetup2_2, kStringArsanoMeetup2_3, kStringArsanoMeetup2_4,
// 475
kStringArsanoMeetup2_5, kStringArsanoMeetup2_6, kStringArsanoMeetup2_7, kStringArsanoMeetup2_8, kStringArsanoMeetup2_9,
kStringArsanoMeetup2_10, kStringArsanoMeetup2_11, kStringArsanoMeetup2_12, kStringArsanoMeetup2_13, kStringArsanoMeetup3_1,
kStringArsanoMeetup3_2, kStringArsanoMeetup3_3, kStringArsanoMeetup3_4, kStringArsanoMeetup3_5, kStringArsanoMeetup3_6,
kStringArsanoMeetup3_7, kStringArsanoMeetup3_8, kStringArsanoMeetup3_9, kStringArsanoMeetup3_10, kStringArsanoMeetup3_11,
kStringArsanoMeetup3_12, kStringArsanoMeetup3_13, kStringArsanoMeetup3_14, kStringArsanoMeetup3_15, kStringArsanoMeetup3_16,
// 500
kStringArsanoMeetup3_17, kStringArsanoMeetup3_18, kStringArsanoMeetup3_19, kStringArsanoMeetup3_20, kStringArsanoMeetup3_21,
kStringArsanoMeetup3_22, kStringArsanoMeetup3_23, kStringArsanoMeetup3_24, kStringArsanoMeetup3_25, kStringArsanoMeetup3_26,
kStringArsanoMeetup3_27, kStringArsanoMeetup3_28, kStringAxacussCell_1, kStringAxacussCell_2, kStringAxacussCell_3,
kStringAxacussCell_4, kStringAxacussCell_5, kStringOk, kStringDialogArsanoMeetup2_1, kStringDialogArsanoMeetup2_2,
kStringDialogArsanoMeetup2_3, kStringDialogArsanoMeetup2_4, kStringDialogArsanoMeetup2_5, kStringDialogArsanoMeetup2_6, kStringDialogArsanoMeetup2_7,
// 525
kStringDialogArsanoMeetup2_8, kStringDialogArsanoMeetup2_9, kStringDialogArsanoMeetup2_10, kStringDialogArsanoMeetup2_11, kStringDialogAxacussCorridor5_1,
kStringDialogAxacussCorridor5_2, kStringDialogAxacussCorridor5_3, kStringDialogAxacussCorridor5_4, kStringDialogAxacussCorridor5_5, kStringDialogAxacussCorridor5_6,
kStringDialogAxacussCorridor5_7, kStringDialogX1, kStringDialogX2, kStringDialogX3, kStringAxacussCorridor5_1,
kStringAxacussCorridor5_2, kStringAxacussCorridor5_3, kStringAxacussCorridor5_4, kStringAxacussCorridor5_5, kStringAxacussCorridor5_6,
kStringAxacussCorridor5_7, kStringAxacussBcorridor_1, kStringAxacussOffice1_1, kStringAxacussOffice1_2, kStringAxacussOffice1_3,
// 550
kStringAxacussOffice1_4, kStringAxacussOffice1_5, kStringAxacussOffice1_6, kStringAxacussOffice1_7, kStringAxacussOffice1_8,
kStringAxacussOffice1_9, kStringAxacussOffice1_10, kStringAxacussOffice1_11, kStringAxacussOffice1_12, kStringAxacussOffice1_13,
kStringAxacussOffice1_14, kStringAxacussOffice1_15, kStringAxacussOffice1_16, kStringAxacussOffice3_1, kStringAxacussElevator_1,
kStringAxacussElevator_2, kStringAxacussElevator_3, kStringShock, kStringShot, kStringCloseLocker_1,
kStringIsHelmetOff_1, kStringGenericInteract_1, kStringGenericInteract_2, kStringGenericInteract_3, kStringGenericInteract_4,
// 575
kStringGenericInteract_5, kStringGenericInteract_6, kStringGenericInteract_7, kStringGenericInteract_8, kStringGenericInteract_9,
kStringGenericInteract_10, kStringGenericInteract_11, kStringGenericInteract_12, kPhrasalVerbParticleGiveTo, kPhrasalVerbParticleUseWith,
kStringGenericInteract_13, kStringGenericInteract_14, kStringGenericInteract_15, kStringGenericInteract_16, kStringGenericInteract_17,
kStringGenericInteract_18, kStringGenericInteract_19, kStringGenericInteract_20, kStringGenericInteract_21, kStringGenericInteract_22,
kStringGenericInteract_23, kStringGenericInteract_24, kStringGenericInteract_25, kStringGenericInteract_26, kStringGenericInteract_27,
// 600
kStringGenericInteract_28, kStringGenericInteract_29, kStringGenericInteract_30, kStringGenericInteract_31, kStringGenericInteract_32,
kStringGenericInteract_33, kStringGenericInteract_34, kStringGenericInteract_35, kStringGenericInteract_36, kStringGenericInteract_37,
kStringGenericInteract_38, kStringGenericInteract_39, kStringGenericInteract_40, kStringGenericInteract_41, kStringGenericInteract_42,
kStringGenericInteract_43, kStringConversationEnd, kStringSupernova1, kStringSupernova2, kStringSupernova3,
kStringSupernova4, kStringSupernova5, kStringSupernova6, kStringSupernova7, kStringSupernova8,
// 625
kStringTextSpeed, kStringGuardNoticed1, kStringGuardNoticed2, kStringTelomat1, kStringTelomat2,
kStringTelomat3, kStringTelomat4, kStringTelomat5, kStringTelomat6, kStringTelomat7,
kStringTelomat8, kStringTelomat9, kStringTelomat10, kStringTelomat11, kStringTelomat12,
kStringTelomat13, kStringTelomat14, kStringTelomat15, kStringTelomat16, kStringTelomat17,
kStringTelomat18, kStringTelomat19, kStringTelomat20, kStringTelomat21, kStringAlarm,
// Add two placeholder strings at the end for variable text
kStringPlaceholder1, kStringPlaceholder2,
// String for money in inventory
kStringInventoryMoney
};
ObjectType operator|(ObjectType a, ObjectType b);
ObjectType operator&(ObjectType a, ObjectType b);
ObjectType operator^(ObjectType a, ObjectType b);
ObjectType &operator|=(ObjectType &a, ObjectType b);
ObjectType &operator&=(ObjectType &a, ObjectType b);
ObjectType &operator^=(ObjectType &a, ObjectType b);
struct Object {
static const Object nullObject;
Object()
: _name(kNoString)
, _description(kStringDefaultDescription)
, _id(INVALIDOBJECT)
, _roomId(NULLROOM)
, _type(NULLTYPE)
, _click(0)
, _click2(0)
, _section(0)
, _exitRoom(NULLROOM)
, _direction(0)
{}
Object(byte roomId, StringID name, StringID description, ObjectID id, ObjectType type,
byte click, byte click2, byte section = 0, RoomID exitRoom = NULLROOM, byte direction = 0)
: _name(name)
, _description(description)
, _id(id)
, _roomId(roomId)
, _type(type)
, _click(click)
, _click2(click2)
, _section(section)
, _exitRoom(exitRoom)
, _direction(direction)
{}
static void setObjectNull(Object *&obj) {
obj = const_cast<Object *>(&nullObject);
}
static bool isNullObject(Object *obj) {
return obj == &nullObject;
}
void resetProperty(ObjectType type = NULLTYPE) {
_type = type;
}
void setProperty(ObjectType type) {
_type |= type;
}
void disableProperty(ObjectType type) {
_type &= ~type;
}
bool hasProperty(ObjectType type) const {
return _type & type;
}
static bool combine(Object &obj1, Object &obj2, ObjectID id1, ObjectID id2) {
if (obj1.hasProperty(COMBINABLE))
return (((obj1._id == id1) && (obj2._id == id2)) ||
((obj1._id == id2) && (obj2._id == id1)));
else
return false;
}
byte _roomId;
StringID _name;
StringID _description;
ObjectID _id;
ObjectTypes _type;
byte _click;
byte _click2;
byte _section;
RoomID _exitRoom;
byte _direction;
};
#define ticksToMsec(x) (x * kMsecPerTick)
}
#endif // SUPERNOVA_MSN_DEF_H

3247
engines/supernova/rooms.cpp Normal file

File diff suppressed because it is too large Load Diff

1388
engines/supernova/rooms.h Normal file

File diff suppressed because it is too large Load Diff

2388
engines/supernova/state.cpp Normal file

File diff suppressed because it is too large Load Diff

234
engines/supernova/state.h Normal file
View File

@ -0,0 +1,234 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SUPERNOVA_STATE_H
#define SUPERNOVA_STATE_H
#include "common/rect.h"
#include "common/keyboard.h"
#include "supernova/rooms.h"
namespace Supernova {
const int32 kMaxTimerValue = 0x7FFFFFFF;
enum EventFunction { kNoFn, kSupernovaFn, kGuardReturnedFn, kGuardWalkFn, kTaxiFn, kSearchStartFn };
struct GameState {
int32 _time;
int32 _timeSleep;
int32 _timeAlarm;
int32 _eventTime;
EventFunction _eventCallback;
int32 _arrivalDaysLeft;
int32 _shipEnergyDaysLeft;
int32 _landingModuleEnergyDaysLeft;
uint16 _greatFlag;
int16 _timeRobot;
int16 _money;
byte _coins;
byte _shoes;
byte _origin;
byte _destination;
byte _language;
bool _corridorSearch;
bool _alarmOn;
bool _terminalStripConnected;
bool _terminalStripWire;
bool _cableConnected;
bool _powerOff;
bool _dream;
bool _nameSeen[4];
bool _playerHidden;
};
class Inventory {
public:
Inventory(int &inventoryScroll)
: _numObjects(0)
, _inventoryScroll(inventoryScroll)
{}
void add(Object &obj);
void remove(Object &obj);
void clear();
Object *get(int index) const;
Object *get(ObjectID id) const;
int getSize() const { return _numObjects; }
private:
Object *_inventory[kMaxCarry];
int &_inventoryScroll;
int _numObjects;
};
class GuiElement : public Common::Rect {
public:
GuiElement();
void setSize(int x1, int y1, int x2, int y2);
void setText(const char *text);
void setTextPosition(int x, int y);
void setColor(int bgColor, int textColor, int bgColorHighlighted, int textColorHightlighted);
void setHighlight(bool isHighlighted);
Common::Point _textPosition;
char _text[128];
int _bgColor;
int _textColor;
int _bgColorNormal;
int _bgColorHighlighted;
int _textColorNormal;
int _textColorHighlighted;
bool _isHighlighted;
};
class GameManager {
public:
GameManager(SupernovaEngine *vm);
~GameManager();
void processInput(Common::KeyState &state);
void processInput();
void executeRoom();
bool serialize(Common::WriteStream *out);
bool deserialize(Common::ReadStream *in, int version);
static StringID guiCommands[];
static StringID guiStatusCommands[];
SupernovaEngine *_vm;
Common::KeyState _key;
Common::EventType _mouseClickType;
bool _mouseClicked;
bool _keyPressed;
int _mouseX;
int _mouseY;
int _mouseField;
Room *_currentRoom;
bool _newRoom;
Room *_rooms[NUMROOMS];
Inventory _inventory;
GameState _state;
bool _processInput;
bool _guiEnabled;
bool _animationEnabled;
byte _roomBrightness;
Action _inputVerb;
Object *_currentInputObject;
Object *_inputObject[2];
bool _waitEvent;
int32 _oldTime;
uint _timePaused;
bool _timerPaused;
int32 _timer1;
int32 _animationTimer;
int _inventoryScroll;
int _exitList[25];
GuiElement _guiCommandButton[10];
GuiElement _guiInventory[8];
GuiElement _guiInventoryArrow[2];
// 0 PC Speaker | 1 SoundBlaster | 2 No Sound
int _soundDevice;
// Dialog
int _currentSentence;
int _sentenceNumber[6];
StringID _texts[6];
byte _rows[6];
byte _rowsStart[6];
void takeObject(Object &obj);
void initState();
void initRooms();
void destroyRooms();
void initGui();
bool genericInteract(Action verb, Object &obj1, Object &obj2);
bool isHelmetOff();
void great(uint number);
bool airless();
void shock();
Common::EventType getMouseInput();
uint16 getKeyInput(bool blockForPrintChar = false);
void getInput();
void mouseInput3();
void wait2(int ticks);
void waitOnInput(int ticks);
bool waitOnInput(int ticks, Common::KeyCode &keycode);
void turnOff();
void turnOn();
void screenShake();
void roomBrightness();
void showMenu();
void animationOff();
void animationOn();
void openLocker(const Room *room, Object *obj, Object *lock, int section);
void closeLocker(const Room *room, Object *obj, Object *lock, int section);
void edit(Common::String &input, int x, int y, uint length);
int invertSection(int section);
void drawMapExits();
void drawStatus();
void drawCommandBox();
void drawInventory();
void changeRoom(RoomID id);
void resetInputState();
void handleInput();
void handleTime();
void pauseTimer(bool pause);
void loadTime();
void saveTime();
void setAnimationTimer(int ticks);
void dead(StringID messageId);
int dialog(int num, byte rowLength[6], StringID text[6], int number);
void sentence(int number, bool brightness);
void say(StringID textId);
void say(const char *text);
void reply(StringID textId, int aus1, int aus2);
void reply(const char *text, int aus1, int aus2);
void mousePosDialog(int x, int y);
void shot(int a, int b);
void takeMoney(int amount);
void search(int time);
void startSearch();
void guardNoticed();
void busted(int i);
void corridorOnEntrance();
void telomat(int number);
void novaScroll();
void supernovaEvent();
void guardReturnedEvent();
void walk(int a);
void guardWalkEvent();
void taxiEvent();
void searchStartEvent();
void outro();
void guardShot();
void guard3Shot();
void alarm();
void alarmSound();
private:
int _prevImgId;
};
}
#endif // SUPERNOVA_STATE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,218 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SUPERNOVA_SUPERNOVA_H
#define SUPERNOVA_SUPERNOVA_H
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "audio/decoders/raw.h"
#include "common/array.h"
#include "common/events.h"
#include "common/random.h"
#include "common/scummsys.h"
#include "engines/engine.h"
#include "common/file.h"
#include "common/memstream.h"
#include "supernova/console.h"
#include "supernova/graphics.h"
#include "supernova/msn_def.h"
#include "supernova/rooms.h"
namespace Supernova {
#define SAVEGAME_HEADER MKTAG('M','S','N','1')
#define SAVEGAME_VERSION 8
#define SUPERNOVA_DAT "supernova.dat"
#define SUPERNOVA_DAT_VERSION 1
struct ScreenBuffer {
ScreenBuffer()
: _x(0)
, _y(0)
, _width(0)
, _height(0)
, _pixels(NULL)
{}
byte *_pixels;
int _x;
int _y;
int _width;
int _height;
};
class ScreenBufferStack {
public:
ScreenBufferStack();
void push(int x, int y, int width, int height);
void restore();
private:
ScreenBuffer _buffer[8];
ScreenBuffer *_last;
};
struct SoundSample {
SoundSample()
: _buffer(NULL)
, _length(0)
{}
~SoundSample() {
delete[] _buffer;
}
byte *_buffer;
int _length;
};
class SupernovaEngine : public Engine {
public:
explicit SupernovaEngine(OSystem *syst);
~SupernovaEngine();
virtual Common::Error run();
Common::RandomSource _rnd;
GameManager *_gm;
Console *_console;
Audio::SoundHandle _soundHandle;
ScreenBufferStack _screenBuffer;
byte _mouseNormal[256];
byte _mouseWait[256];
MSNImageDecoder *_currentImage;
SoundSample _soundSamples[kAudioNumSamples];
Common::MemoryReadStream *_soundMusicIntro;
Common::MemoryReadStream *_soundMusicOutro;
int _screenWidth;
int _screenHeight;
bool _allowLoadGame;
bool _allowSaveGame;
Common::StringArray _gameStrings;
Common::String _nullString;
byte _menuBrightness;
byte _brightness;
uint _delay;
bool _messageDisplayed;
int _textSpeed;
int _textCursorX;
int _textCursorY;
int _textColor;
int textWidth(const char *text);
int textWidth(const uint16 key);
Common::Error loadGameStrings();
void initData();
void initPalette();
void paletteFadeIn();
void paletteFadeOut();
void paletteBrightness();
void updateEvents();
void playSound(AudioIndex sample);
void playSoundMod(int filenumber);
void stopSound();
void renderImageSection(int section);
void renderImage(int section);
bool setCurrentImage(int filenumber);
void saveScreen(int x, int y, int width, int height);
void restoreScreen();
void renderRoom(Room &room);
void renderMessage(const char *text, MessagePosition position = kMessageNormal);
void removeMessage();
void renderText(const char *text, int x, int y, byte color);
void renderText(const uint16 character, int x, int y, byte color);
void renderText(const char *text);
void renderText(const uint16 character);
void renderBox(int x, int y, int width, int height, byte color);
void setColor63(byte value);
bool loadGame(int slot);
bool saveGame(int slot, const Common::String &description);
void errorTempSave(bool saving);
void setTextSpeed();
const Common::String &getGameString(int idx) const {
if (idx < 0 || idx >= (int)_gameStrings.size())
return _nullString;
return _gameStrings[idx];
}
void setGameString(int idx, const Common::String &string) {
if (idx < 0)
return;
while ((int)_gameStrings.size() <= idx)
_gameStrings.push_back(Common::String());
_gameStrings[idx] = string;
}
int textWidth(const Common::String &text) {
if (text.empty())
return 0;
return textWidth(text.c_str());
}
void renderMessage(StringID stringId, MessagePosition position = kMessageNormal, Common::String var1 = "", Common::String var2 = "") {
Common::String text = getGameString(stringId);
if (!var1.empty()) {
if (!var2.empty())
text = Common::String::format(text.c_str(), var1.c_str(), var2.c_str());
else
text = Common::String::format(text.c_str(), var1.c_str());
}
renderMessage(text, position);
}
void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal) {
if (!text.empty())
renderMessage(text.c_str(), position);
}
void renderText(StringID stringId, int x, int y, byte color) {
renderText(getGameString(stringId), x, y, color);
}
void renderText(const Common::String &text, int x, int y, byte color) {
if (!text.empty())
renderText(text.c_str(), x, y, color);
}
void renderText(StringID stringId) {
renderText(getGameString(stringId));
}
void renderText(const Common::String &text) {
if (!text.empty())
renderText(text.c_str());
}
Common::MemoryReadStream *convertToMod(const char *filename, int version = 1);
virtual Common::Error loadGameState(int slot);
virtual bool canLoadGameStateCurrently();
virtual Common::Error saveGameState(int slot, const Common::String &desc);
virtual bool canSaveGameStateCurrently();
virtual bool hasFeature(EngineFeature f) const;
virtual void pauseEngineIntern(bool pause);
};
}
#endif