diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/startrek/awaymission.cpp | 182 | ||||
-rw-r--r-- | engines/startrek/awaymission.h | 4 | ||||
-rw-r--r-- | engines/startrek/bitmap.cpp | 2 | ||||
-rw-r--r-- | engines/startrek/bitmap.h | 4 | ||||
-rw-r--r-- | engines/startrek/filestream.cpp | 43 | ||||
-rw-r--r-- | engines/startrek/filestream.h | 20 | ||||
-rw-r--r-- | engines/startrek/font.cpp | 23 | ||||
-rw-r--r-- | engines/startrek/graphics.cpp | 18 | ||||
-rw-r--r-- | engines/startrek/items.h | 82 | ||||
-rw-r--r-- | engines/startrek/sound.cpp | 2 | ||||
-rw-r--r-- | engines/startrek/startrek.cpp | 26 | ||||
-rw-r--r-- | engines/startrek/startrek.h | 42 | ||||
-rw-r--r-- | engines/startrek/text.cpp | 44 |
13 files changed, 375 insertions, 117 deletions
diff --git a/engines/startrek/awaymission.cpp b/engines/startrek/awaymission.cpp index e0499240be..ec931bb735 100644 --- a/engines/startrek/awaymission.cpp +++ b/engines/startrek/awaymission.cpp @@ -29,8 +29,11 @@ void StarTrekEngine::initAwayMission() { _awayMission = AwayMission(); // Initialize members to 0 // memset(bitmapBuffer->pixels, 0, 0xfa00); - // sub_15ab1("ground"); - // sub_23a60(); + + _txtFilename = "ground"; + _itemDescription = ""; + + // sub_23a60(); // TODO _sound->loadMusicFile("ground"); loadRoom(_missionToLoad, _roomIndexToLoad); @@ -196,41 +199,107 @@ void StarTrekEngine::handleAwayMissionEvents() { } break; - case ACTION_USE: - if (_awayMission.activeItem != OBJECT_REDSHIRT - || (!_awayMission.redshirtDead && !(_awayMission.field24 & 8))) { - int clickedObject = findObjectAt(_gfx->getMousePos()); + case ACTION_USE: { + if (_awayMission.activeObject == OBJECT_REDSHIRT && (_awayMission.redshirtDead || (_awayMission.field24 & 8))) { hideInventoryIcons(); + _awayMission.activeAction = ACTION_WALK; + break; + } - if (clickedObject == OBJECT_INVENTORY_ICON) - clickedObject = showInventoryMenu(50, 50, false); + int clickedObject = findObjectAt(_gfx->getMousePos()); + hideInventoryIcons(); - if (clickedObject == -1) - clickedObject = -2; + if (clickedObject == OBJECT_INVENTORY_ICON) + clickedObject = showInventoryMenu(50, 50, false); - _awayMission.passiveItem = clickedObject; - if (clickedObject != -2) { - // TODO + if (clickedObject == -1) + clickedObject = -2; + + _awayMission.passiveObject = clickedObject; + + bool activeIsCrewman = _awayMission.activeObject <= OBJECT_REDSHIRT; + bool activeIsItem = _awayMission.activeObject >= ITEMS_START && _awayMission.activeObject < ITEMS_END; + bool passiveIsCrewman = _awayMission.passiveObject <= OBJECT_REDSHIRT; + bool passiveIsItem = _awayMission.passiveObject >= ITEMS_START && _awayMission.passiveObject <= ITEMS_END; // FIXME: "<= ITEMS_END" doesn't make sense? + + if (clickedObject == -2) + goto checkAddCommand; + if (checkItemInteractionExists(ACTION_USE, _awayMission.activeObject, _awayMission.passiveObject, 0)) + goto checkAddCommand; + if (_awayMission.activeObject == OBJECT_MCCOY) { + if (checkItemInteractionExists(ACTION_USE, OBJECT_IMEDKIT, _awayMission.passiveObject, 0)) + goto checkAddCommand; + if (checkItemInteractionExists(ACTION_USE, OBJECT_IMEDKIT, _awayMission.passiveObject, 0)) + goto checkAddCommand; + } + else if (_awayMission.activeObject == OBJECT_SPOCK) { + if (checkItemInteractionExists(ACTION_USE, OBJECT_ISTRICOR, _awayMission.passiveObject, 0)) + goto checkAddCommand; + } + + if ((activeIsCrewman && passiveIsCrewman) + || (activeIsCrewman && passiveIsItem) + || (activeIsItem && passiveIsItem)) { + if (_awayMission.passiveObject == OBJECT_ICOMM) { + if (sub_2330c()) + break; + addCommand(Command(ACTION_USE, OBJECT_ICOMM, 0, 0)); + _sound->playVoc("commun30"); + if (_awayMission.activeObject <= OBJECT_REDSHIRT) { + goto checkShowInventory; + } + else { + _awayMission.activeAction = ACTION_WALK; + break; + } } - // if (!sub_2330c()) // TODO - { - if (clickedObject != -2) - addCommand(Command(_awayMission.activeAction, _awayMission.activeItem, _awayMission.passiveItem, 0)); + _awayMission.activeObject = _awayMission.passiveObject; + goto checkShowInventory; + } - if (!(_awayMission.field24 & 1)) - showInventoryIcons(true); - } +checkAddCommand: + if (!sub_2330c()) + { + if (clickedObject != -2) + addCommand(Command(_awayMission.activeAction, _awayMission.activeObject, _awayMission.passiveObject, 0)); + +checkShowInventory: + if (!(_awayMission.field24 & 1)) + showInventoryIcons(true); } break; - case 3: - break; - case 4: - break; - case 5: + } + + case ACTION_GET: + case ACTION_LOOK: + case ACTION_TALK: { + int clickedObject = findObjectAt(_gfx->getMousePos()); + // if (!sub_23611(clickedObject, _awayMission.activeAction)) // TODO + { + hideInventoryIcons(); + if (clickedObject == OBJECT_INVENTORY_ICON) { + clickedObject = showInventoryMenu(50, 50, false); + if (clickedObject == -1) + clickedObject = -2; + } + + _awayMission.activeObject = clickedObject; + + if (sub_2330c()) + break; + + if (clickedObject != -2) + addCommand(Command(_awayMission.activeAction, _awayMission.activeObject, 0, 0)); + + if (_awayMission.activeAction == ACTION_LOOK && !(_awayMission.field24 & 1)) + showInventoryIcons(false); + } break; } - break; + + } + break; // End of TREKEVENT_LBUTTONDOWN case TREKEVENT_MOUSEMOVE: break; @@ -241,32 +310,32 @@ void StarTrekEngine::handleAwayMissionEvents() { hideInventoryIcons(); playSoundEffectIndex(0x07); _awayMission.activeAction = showActionMenu(); - if (_awayMission.activeAction == ACTION_USE) { + if (_awayMission.activeAction == ACTION_USE) { // TODO /* int16 clickedObject = sub_22f08(); if (clickedObject == -1) break; else - _awayMission.activeItem = clickedObject; + _awayMission.activeObject = clickedObject; */ } if (_awayMission.activeAction == ACTION_USE - && _awayMission.activeItem == 0x47 && (_awayMission.field24 & 1) == 0) { - /* - if (sub_2330c() == 0) { - addCommand(Command(_awayMission.activeAction, _awayMission.activeItem, 0, 0)); + && _awayMission.activeObject == OBJECT_ICOMM && (_awayMission.field24 & 1) == 0) { // TODO + if (!sub_2330c()) { + addCommand(Command(_awayMission.activeAction, _awayMission.activeObject, 0, 0)); _sound->playVoc("communic"); _awayMission.activeAction = ACTION_WALK; } - */ } else if (_awayMission.activeAction == ACTION_LOOK) showInventoryIcons(false); else if (_awayMission.activeAction == ACTION_USE && (_awayMission.field24 & 1) == 0) showInventoryIcons(true); break; - case TREKEVENT_KEYDOWN: + + case TREKEVENT_KEYDOWN: // TODO break; + default: break; } @@ -309,27 +378,64 @@ SharedPtr<Room> StarTrekEngine::getRoom() { void StarTrekEngine::addCommand(const Command &command) { if (command.type != COMMAND_TICK) - debug("Command %d: %x, %x, %x", command.type, command.b1, command.b2, command.b3); + debug("Command %d: %x, %x, %x", command.type, command.gen.b1, command.gen.b2, command.gen.b3); _commandQueue.push(command); } +bool StarTrekEngine::checkItemInteractionExists(int action, int activeItem, int passiveItem, int16 arg6) { + // TODO + return false; +} + void StarTrekEngine::handleAwayMissionCommand() { Command command = _commandQueue.pop(); - if ((command.type == COMMAND_FINISHED_BEAMING_IN || command.type == COMMAND_FINISHED_ENTERING_ROOM) && command.b1 == 0xff) { + if ((command.type == COMMAND_FINISHED_BEAMING_IN || command.type == COMMAND_FINISHED_ENTERING_ROOM) && command.gen.b1 == 0xff) { _awayMission.transitioningIntoRoom = 0; _warpHotspotsActive = true; return; } - else if (command.type == COMMAND_FINISHED_ENTERING_ROOM && command.b1 >= 0xe0) { // TODO + else if (command.type == COMMAND_FINISHED_ENTERING_ROOM && command.gen.b1 >= 0xe0) { // TODO return; } switch (command.type) { // TODO: everything + + case COMMAND_WALK: // TODO + break; + + case COMMAND_USE: // TODO + break; + + case COMMAND_GET: // TODO + break; + + case COMMAND_LOOK: + if (command.action.activeObject >= ITEMS_START && command.action.activeObject < ITEMS_END) { + int i = command.action.activeObject - ITEMS_START; + Common::String text = getItemDescription(_itemList[i].textIndex); + showTextbox("", text, 20, 20, TEXTCOLOR_YELLOW, 0); + } + else if (command.action.activeObject == OBJECT_KIRK) + showTextbox("", getItemDescription(0x49), 20, 20, TEXTCOLOR_YELLOW, 0); + else if (command.action.activeObject == OBJECT_SPOCK) + showTextbox("", getItemDescription(0x4a), 20, 20, TEXTCOLOR_YELLOW, 0); + else if (command.action.activeObject == OBJECT_MCCOY) + showTextbox("", getItemDescription(0x4b), 20, 20, TEXTCOLOR_YELLOW, 0); + else { + if (command.action.activeObject == OBJECT_REDSHIRT) + showTextbox("", getItemDescription(0x4c), 20, 20, TEXTCOLOR_YELLOW, 0); + showTextbox("", getItemDescription(0x4d), 20, 20, TEXTCOLOR_YELLOW, 0); + } + break; + + case COMMAND_TALK: // TODO + break; + case COMMAND_TOUCHED_WARP: // if (!sub_203e1(command.type)) // Probably calls RDF code { - byte warpIndex = command.b1; + byte warpIndex = command.gen.b1; int16 roomIndex = _room->readRdfWord(RDF_WARP_ROOM_INDICES + warpIndex * 2); unloadRoom(); _sound->loadMusicFile("ground"); diff --git a/engines/startrek/awaymission.h b/engines/startrek/awaymission.h index c75960334b..8972306f41 100644 --- a/engines/startrek/awaymission.h +++ b/engines/startrek/awaymission.h @@ -32,8 +32,8 @@ struct AwayMission { byte transitioningIntoRoom; // Set while beaming in or walking into a room bool redshirtDead; byte activeAction; - byte activeItem; // The item that is going to be used on something - byte passiveItem; // The item that the active item is used on (or the item looked at, etc). + byte activeObject; // The item that is going to be used on something + byte passiveObject; // The item that the active item is used on (or the item looked at, etc). byte field24; int8 field25[4]; diff --git a/engines/startrek/bitmap.cpp b/engines/startrek/bitmap.cpp index 61e5bcee03..19f1434388 100644 --- a/engines/startrek/bitmap.cpp +++ b/engines/startrek/bitmap.cpp @@ -24,7 +24,7 @@ namespace StarTrek { -Bitmap::Bitmap(SharedPtr<Common::ReadStreamEndian> stream) { +Bitmap::Bitmap(SharedPtr<FileStream> stream) { xoffset = stream->readUint16(); yoffset = stream->readUint16(); width = stream->readUint16(); diff --git a/engines/startrek/bitmap.h b/engines/startrek/bitmap.h index 7d3f2fdaf5..fcebd67aa0 100644 --- a/engines/startrek/bitmap.h +++ b/engines/startrek/bitmap.h @@ -1,6 +1,8 @@ #ifndef STARTREK_BITMAP_H #define STARTREK_BITMAP_H +#include "startrek/filestream.h" + #include "common/ptr.h" #include "common/stream.h" @@ -13,7 +15,7 @@ struct Bitmap { uint16 height; byte *pixels; - Bitmap(Common::SharedPtr<Common::ReadStreamEndian> stream); + Bitmap(Common::SharedPtr<FileStream> stream); Bitmap(int w, int h); ~Bitmap(); diff --git a/engines/startrek/filestream.cpp b/engines/startrek/filestream.cpp index 3af5ca8bb7..31cb789a88 100644 --- a/engines/startrek/filestream.cpp +++ b/engines/startrek/filestream.cpp @@ -2,37 +2,60 @@ namespace StarTrek { -FileStream::FileStream(Common::SeekableReadStream *stream, bool bigEndian) : Common::SeekableReadStreamEndian(bigEndian) { - _stream = stream; +FileStream::FileStream(Common::SeekableReadStream *stream, bool bigEndian) { _bigEndian = bigEndian; + + _pos = 0; + _size = stream->size(); + _data = new byte[_size]; + stream->read(_data, _size); + delete stream; } FileStream::~FileStream() { - delete _stream; + delete[] _data; } // ReadStream functions -bool FileStream::eos() const { - return _stream->eos(); +uint32 FileStream::read(void* dataPtr, uint32 dataSize) { + if (_pos + dataSize > (uint32)size()) + dataSize = size() - _pos; + memcpy(dataPtr, _data + _pos, dataSize); + _pos += dataSize; + return dataSize; } -uint32 FileStream::read(void* dataPtr, uint32 dataSize) { - return _stream->read(dataPtr, dataSize); +byte FileStream::readByte() { + assert(_pos + 1 <= size()); + return _data[_pos++]; +} + +uint16 FileStream::readUint16() { + assert(_pos + 2 <= size()); + uint16 w; + if (_bigEndian) + w = _data[_pos + 1] | (_data[_pos] << 8); + else + w = _data[_pos] | (_data[_pos + 1] << 8); + _pos += 2; + return w; } // SeekableReadStream functions int32 FileStream::pos() const { - return _stream->pos(); + return _pos; } int32 FileStream::size() const { - return _stream->size(); + return _size; } bool FileStream::seek(int32 offset, int whence) { - return _stream->seek(offset, whence); + assert(whence == SEEK_SET); + _pos = offset; + return true; } } diff --git a/engines/startrek/filestream.h b/engines/startrek/filestream.h index dcc806043c..79a919ac22 100644 --- a/engines/startrek/filestream.h +++ b/engines/startrek/filestream.h @@ -26,25 +26,31 @@ namespace StarTrek { -class FileStream : public Common::SeekableReadStreamEndian { +class FileStream { public: FileStream(Common::SeekableReadStream *stream, bool bigEndian); ~FileStream(); + byte *_data; + private: - Common::SeekableReadStream *_stream; bool _bigEndian; + int32 _pos; + int32 _size; public: // ReadStream functions - virtual bool eos() const; - virtual uint32 read(void *dataPtr, uint32 dataSize); + bool eos() const; + uint32 read(void *dataPtr, uint32 dataSize); + + byte readByte(); + uint16 readUint16(); // SeekableReadStream functions - virtual int32 pos() const; - virtual int32 size() const; - virtual bool seek(int32 offset, int whence); + int32 pos() const; + int32 size() const; + bool seek(int32 offset, int whence); }; diff --git a/engines/startrek/font.cpp b/engines/startrek/font.cpp index 8463841ece..7cba71196e 100644 --- a/engines/startrek/font.cpp +++ b/engines/startrek/font.cpp @@ -31,33 +31,12 @@ static const byte CHARACTER_COUNT = 0x80; static const byte CHARACTER_SIZE = 0x40; Font::Font(StarTrekEngine *vm) : _vm(vm) { - SharedPtr<Common::SeekableReadStream> fontStream = _vm->loadFile("FONT.FNT"); + SharedPtr<FileStream> fontStream = _vm->loadFile("FONT.FNT"); _characters = new Character[CHARACTER_COUNT]; for (byte i = 0; i < CHARACTER_COUNT; i++) fontStream->read(_characters[i].data, CHARACTER_SIZE); - -#if 0 - // Code to dump the font - printf ("DUMPING FONT"); - for (byte i = 0; i < CHARACTER_COUNT; i++) { - printf ("\n\nCHARACTER %02x (%d):\n", i, i); - for (byte j = 0; j < CHARACTER_SIZE; j++) { - if (!(j % 8)) - printf ("\n"); - if (_characters[i].data[j] == 0x7d) - printf ("1 "); - else if (_characters[i].data[j] == 0x78) - printf ("0 "); - else if (_characters[i].data[j] == 0) - printf (" "); - else - printf ("? "); - } - } - printf("\n\n"); -#endif } Font::~Font() { diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp index e33fa519a4..2e289514f0 100644 --- a/engines/startrek/graphics.cpp +++ b/engines/startrek/graphics.cpp @@ -80,11 +80,11 @@ void Graphics::loadPalette(const Common::String &paletteName) { Common::String palFile = paletteName + ".PAL"; Common::String lutFile = paletteName + ".LUT"; - SharedPtr<Common::SeekableReadStream> palStream = _vm->loadFile(palFile.c_str()); + SharedPtr<FileStream> palStream = _vm->loadFile(palFile.c_str()); palStream->read(_palData, 256 * 3); // Load LUT file - SharedPtr<Common::SeekableReadStream> lutStream = _vm->loadFile(lutFile.c_str()); + SharedPtr<FileStream> lutStream = _vm->loadFile(lutFile.c_str()); lutStream->read(_lutData, 256); } @@ -160,7 +160,7 @@ void Graphics::decPaletteFadeLevel() { void Graphics::loadPri(const Common::String &priFile) { - SharedPtr<Common::SeekableReadStream> priStream = _vm->loadFile(priFile); + SharedPtr<FileStream> priStream = _vm->loadFile(priFile); priStream->read(_priData, SCREEN_WIDTH * SCREEN_HEIGHT / 2); } @@ -632,14 +632,14 @@ void Graphics::loadEGAData(const char *filename) { if (!_egaData) _egaData = new byte[256]; - SharedPtr<Common::SeekableReadStream> egaStream = _vm->loadFile(filename); + SharedPtr<FileStream> egaStream = _vm->loadFile(filename); egaStream->read(_egaData, 256); } void Graphics::drawBackgroundImage(const char *filename) { // Draw an stjr BGD image (palette built-in) - SharedPtr<Common::SeekableReadStream> imageStream = _vm->loadFile(filename); + SharedPtr<FileStream> imageStream = _vm->loadFile(filename); byte *palette = new byte[256 * 3]; imageStream->read(palette, 256 * 3); @@ -647,10 +647,10 @@ void Graphics::drawBackgroundImage(const char *filename) { for (uint16 i = 0; i < 256 * 3; i++) palette[i] <<= 2; - uint16 xoffset = imageStream->readUint16LE(); - uint16 yoffset = imageStream->readUint16LE(); - uint16 width = imageStream->readUint16LE(); - uint16 height = imageStream->readUint16LE(); + uint16 xoffset = imageStream->readUint16(); + uint16 yoffset = imageStream->readUint16(); + uint16 width = imageStream->readUint16(); + uint16 height = imageStream->readUint16(); byte *pixels = new byte[width * height]; imageStream->read(pixels, width * height); diff --git a/engines/startrek/items.h b/engines/startrek/items.h index 913ec7dfc6..2bf89f6c05 100644 --- a/engines/startrek/items.h +++ b/engines/startrek/items.h @@ -25,11 +25,87 @@ namespace StarTrek { +enum Items { + OBJECT_IPHASERS = 64, + OBJECT_IPHASERK, + OBJECT_IHAND, + OBJECT_IROCK, + OBJECT_ISTRICOR, + OBJECT_IMTRICOR, + OBJECT_IDEADGUY, + OBJECT_ICOMM, + OBJECT_IPBC, + OBJECT_IRLG, + OBJECT_IWRENCH, + OBJECT_IINSULAT, + OBJECT_ISAMPLE, + OBJECT_ICURE, + OBJECT_IDISHES, + OBJECT_IRT, + OBJECT_IRTWB, + OBJECT_ICOMBBIT, + OBJECT_IJNKMETL, + OBJECT_IWIRING, + OBJECT_IWIRSCRP, + OBJECT_IPWF, + OBJECT_IPWE, + OBJECT_IDEADPH, + OBJECT_IBOMB, + OBJECT_IMETAL, + OBJECT_ISKULL, + OBJECT_IMINERAL, + OBJECT_IMETEOR, + OBJECT_ISHELLS, + OBJECT_IDEGRIME, + OBJECT_ILENSES, + OBJECT_IDISKS, + OBJECT_IANTIGRA, + OBJECT_IN2GAS, + OBJECT_IO2GAS, + OBJECT_IH2GAS, + OBJECT_IN2O, + OBJECT_INH3, + OBJECT_IH2O, + OBJECT_IWROD, + OBJECT_IIROD, + OBJECT_IREDGEM_A, // FIXME: repeated items? (applies to all names with _A, _B, or _C) + OBJECT_IREDGEM_B, + OBJECT_IREDGEM_C, + OBJECT_IGRNGEM_A, + OBJECT_IGRNGEM_B, + OBJECT_IGRNGEM_C, + OBJECT_IBLUGEM_A, + OBJECT_IBLUGEM_B, + OBJECT_IBLUGEM_C, + OBJECT_ICONECT, + OBJECT_IS8ROCKS, + OBJECT_IIDCARD, + OBJECT_ISNAKE, + OBJECT_IFERN, + OBJECT_ICRYSTAL, + OBJECT_IKNIFE, + OBJECT_IDETOXIN, + OBJECT_IBERRY, + OBJECT_IDOOVER, + OBJECT_IALIENDV, + OBJECT_ICAPSULE, + OBJECT_IMEDKIT, + OBJECT_IBEAM, + OBJECT_IDRILL, + OBJECT_IHYPO, + OBJECT_IFUSION, + OBJECT_ICABLE1, + OBJECT_ICABLE2, + OBJECT_ILMD, + OBJECT_IDECK, + OBJECT_ITECH +}; + struct Item { bool have; int16 field2; char name[10]; - int16 index; + int16 textIndex; }; // This is copied to StarTrekEngine::_itemList when the engine initializes. @@ -174,10 +250,10 @@ const Item g_itemList[] = { { false, 0x00, "", 0x00 }, { false, 0x00, "", 0x00 }, { false, 0x00, "", 0x00 }, - { false, 0x00, "", 0x00 }, + { false, 0x00, "", 0x00 } }; -const int NUM_ITEMS = sizeof(g_itemList) / sizeof(struct Item) - 0x40; // 0x49 +const int NUM_ITEMS = sizeof(g_itemList) / sizeof(struct Item) - 64; // 0x49 } diff --git a/engines/startrek/sound.cpp b/engines/startrek/sound.cpp index 45b6eb064a..5ae06e29c5 100644 --- a/engines/startrek/sound.cpp +++ b/engines/startrek/sound.cpp @@ -312,7 +312,7 @@ void Sound::loadPCMusicFile(const Common::String &baseSoundName) { } debugC(5, kDebugSound, "Loading midi \'%s\'\n", soundName.c_str()); - SharedPtr<Common::SeekableReadStream> soundStream = _vm->loadFile(soundName.c_str()); + SharedPtr<FileStream> soundStream = _vm->loadFile(soundName.c_str()); if (loadedSoundData != nullptr) delete[] loadedSoundData; diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index 8df22ead12..5e64682566 100644 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -815,7 +815,7 @@ int StarTrekEngine::findObjectAt(int x, int y) { if (sprite == &_inventoryIconSprite) return OBJECT_INVENTORY_ICON; else if (sprite == &_itemIconSprite) - return _awayMission.activeItem; + return _awayMission.activeObject; for (int i = 0; i < NUM_ACTORS; i++) { Actor *actor = &_actorList[i]; @@ -1019,11 +1019,13 @@ void StarTrekEngine::showInventoryIcons(bool showItem) { Common::String itemFilename; if (showItem) { - int i = _awayMission.activeItem; - if (i >= 0 && i <= 3) + int i = _awayMission.activeObject; + if (i >= OBJECT_KIRK && i <= OBJECT_REDSHIRT) itemFilename = crewmanFilenames[i]; else { - // TODO + assert(i >= ITEMS_START && i < ITEMS_END); + Item *item = &_itemList[i - ITEMS_START]; + itemFilename = item->name; } } @@ -1602,4 +1604,20 @@ uint16 StarTrekEngine::getRandomWord() { return _randomSource.getRandomNumber(0xffff); } +/** + * ".txt" files are just lists of strings. This traverses the file to get a particular + * string index. + */ +Common::String StarTrekEngine::getItemDescription(int itemIndex) { + SharedPtr<FileStream> txtFile = loadFile(_txtFilename + ".txt"); + + byte *data = txtFile->_data; + while (itemIndex != 0) { + while (*(data++) != '\0'); + itemIndex--; + } + + return (char *)data; +} + } // End of namespace StarTrek diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index b853809413..9689c04ef8 100644 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -93,6 +93,10 @@ enum TextDisplayMode { TEXTDISPLAY_NONE // No text displayed }; +enum TextColor { + TEXTCOLOR_YELLOW = 0xb0 +}; + // Keeps track of data for a list of buttons making up a menu struct Menu { Sprite sprites[MAX_MENUBUTTONS]; @@ -161,7 +165,11 @@ struct TrekEvent { // code. enum Commands { COMMAND_TICK = 0, - COMMAND_CLICKED_ON_OBJECT = 1, + COMMAND_WALK = 1, // Commands 1-5 correspond to Actions of the same number. + COMMAND_USE = 2, + COMMAND_GET = 3, + COMMAND_LOOK = 4, + COMMAND_TALK = 5, COMMAND_TOUCHED_WARP = 6, COMMAND_7 = 7, // Doors? (Or just hotspots activated by Kirk moving there?) COMMAND_FINISHED_BEAMING_IN = 10, @@ -170,12 +178,26 @@ enum Commands { struct Command { byte type; - byte b1; - byte b2; - byte b3; + + union { // FIXME: using unions in a dangeous way here... + struct { + byte b1; + byte b2; + byte b3; + } gen; + + struct { + byte activeObject; + byte passiveObject; + } action; + }; Command(byte _type, byte _b1, byte _b2, byte _b3) - : type(_type), b1(_b1), b2(_b2), b3(_b3) {} + : type(_type) { + gen.b1 = _b1; + gen.b2 = _b2; + gen.b3 = _b3; + } }; // Actions that can be used on away missions. @@ -213,6 +235,7 @@ private: int loadActorAnimWithRoomScaling(int actorIndex, const Common::String &animName, int16 x, int16 y); uint16 getActorScaleAtPosition(int16 y); void addCommand(const Command &command); + bool checkItemInteractionExists(int action, int activeItem, int passiveItem, int16 arg6); void handleAwayMissionCommand(); bool isPointInPolygon(int16 *data, int16 x, int16 y); @@ -254,6 +277,7 @@ public: SharedPtr<Bitmap> loadAnimationFrame(const Common::String &filename, Fixed16 scale); Common::String getCrewmanAnimFilename(int actorIndex, const Common::String &basename); void updateMouseBitmap(); + bool sub_2330c() { return false; } // TODO void showInventoryIcons(bool showItem); void hideInventoryIcons(); int showInventoryMenu(int x, int y, bool restoreMouse); @@ -293,6 +317,8 @@ public: String readTextFromRdf(int choiceIndex, uintptr data, String *headerTextOutput); String readTextFromBuffer(int choiceIndex, uintptr data, String *headerTextOutput); + int showTextbox(String headerText, const String &mainText, int xoffset, int yoffset, byte textColor, int maxTextLines); // TODO: better name. (return type?) + String skipTextAudioPrompt(const String &str); String playTextAudio(const String &str); @@ -359,6 +385,7 @@ public: // Misc uint16 getRandomWord(); + Common::String getItemDescription(int itemIndex); public: @@ -375,6 +402,9 @@ public: SharedPtr<FileStream> _mapFile; int32 _playerActorScale; + Common::String _txtFilename; + Common::String _itemDescription; + // Queue of "commands" (ie. next frame, clicked on object) for away mission or bridge Common::Queue<Command> _commandQueue; @@ -384,7 +414,7 @@ public: int16 _activeDoorWarpHotspot; int16 _lookActionBitmapIndex; - Item _itemList[NUM_ITEMS]; + Item _itemList[NUM_OBJECTS]; Actor _actorList[NUM_ACTORS]; Actor * const _kirkActor; diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index 04b40bfee2..217bd7feb7 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -130,17 +130,32 @@ String StarTrekEngine::readTextFromRdf(int choiceIndex, uintptr data, String *he } /** - * Text getter for showText which reads from a given buffer. + * Shows text with the given header and main text. */ -String StarTrekEngine::readTextFromBuffer(int choiceIndex, uintptr data, String *headerTextOutput) { - char buf[TEXTBOX_WIDTH]; - memcpy(buf, (byte*)data, TEXTBOX_WIDTH-2); - buf[TEXTBOX_WIDTH-2] = '\0'; +int StarTrekEngine::showTextbox(String headerText, const String &mainText, int xoffset, int yoffset, byte textColor, int maxTextLines) { + if (!headerText.empty()) { + while (headerText.size() < TEXTBOX_WIDTH - 2) + headerText += ' '; + } + + int newMaxTextLines = (maxTextLines < 0 ? 0 : maxTextLines); + if (maxTextLines < 0) + maxTextLines = -maxTextLines; - *headerTextOutput = String(buf); + const char *strings[3]; + + if (headerText.empty()) + strings[0] = nullptr; + else + strings[0] = headerText.c_str(); + strings[1] = mainText.c_str(); + strings[2] = ""; - char *text = (char*)data+TEXTBOX_WIDTH-2; - return String(text); + showText(&StarTrekEngine::readTextFromArray, (uintptr)strings, xoffset, yoffset, textColor, false, maxTextLines, 0); + + // TODO + // sub_15a77(); + // sub_14669(newMaxTextLines); } String StarTrekEngine::skipTextAudioPrompt(const String &str) { @@ -587,8 +602,7 @@ String StarTrekEngine::readLineFormattedText(TextGetterFunc textGetter, uintptr String lineFormattedText = putTextIntoLines(text); drawMainText(textBitmap, *numTextLines, numTextboxLines, lineFormattedText, hasHeader); - assert(headerText.size() == TEXTBOX_WIDTH-2); - memcpy(textBitmap->pixels+TEXTBOX_WIDTH+1, headerText.c_str(), TEXTBOX_WIDTH-2); + memcpy(textBitmap->pixels+TEXTBOX_WIDTH+1, headerText.c_str(), headerText.size()); return lineFormattedText; } @@ -627,9 +641,13 @@ String StarTrekEngine::readTextFromArray(int choiceIndex, uintptr data, String * if (*mainText == '\0') return Common::String(); // Technically should be nullptr... - *headerTextOutput = headerText; - while (headerTextOutput->size() < TEXTBOX_WIDTH-2) - *headerTextOutput += ' '; + if (headerText == nullptr) + *headerTextOutput = ""; + else { + *headerTextOutput = headerText; + while (headerTextOutput->size() < TEXTBOX_WIDTH-2) + *headerTextOutput += ' '; + } return String(mainText); } |