diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/detection.cpp | 18 | ||||
-rw-r--r-- | engines/gob/draw.cpp | 35 | ||||
-rw-r--r-- | engines/gob/draw.h | 7 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 26 | ||||
-rw-r--r-- | engines/gob/gob.h | 3 | ||||
-rw-r--r-- | engines/gob/inter.h | 58 | ||||
-rw-r--r-- | engines/gob/inter_v5.cpp | 1035 | ||||
-rw-r--r-- | engines/gob/module.mk | 1 | ||||
-rw-r--r-- | engines/gob/parse_v2.cpp | 107 |
9 files changed, 1278 insertions, 12 deletions
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 63a0f8f45b..85ac455c6c 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -57,6 +57,7 @@ static const PlainGameDescriptor gobGames[] = { {"inca2", "Inca II: Wiracocha"}, {"woodruff", "The Bizarre Adventures of Woodruff and the Schnibble"}, {"dynasty", "The Last Dynasty"}, + {"urban", "Urban Runner"}, {0, 0} }; @@ -1771,7 +1772,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - kGameTypeWoodruff, + kGameTypeDynasty, kFeatures640, "intro" }, @@ -1784,7 +1785,20 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - kGameTypeWoodruff, + kGameTypeDynasty, + kFeatures640, + "intro" + }, + { + { + "urban", + "", + AD_ENTRY1s("intro.stk", "3ab2c542bd9216ae5d02cc6f45701ae1", 1252436), + EN_USA, + kPlatformPC, + Common::ADGF_NO_FLAGS + }, + kGameTypeDynasty, kFeatures640, "intro" }, diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 8a7de9bdaa..2bb99272df 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -323,7 +323,38 @@ void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) { } } -void Draw::drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, +int Draw::stringLength(const char *str, int16 fontIndex) { + static const int8 dword_8F74C[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + if ((fontIndex < 0) || (fontIndex > 7) || !_fonts[fontIndex]) + return 0; + + int len = 0; + + if (_vm->_global->_language == 10) { + + for (int i = 0; str[i] != 0; i++) { + if (str[i+1] < 128) { + len += dword_8F74C[4]; + i++; + } else + len += _fonts[fontIndex]->itemWidth; + } + + } else { + + if (_fonts[fontIndex]->extraData) + while (*str != 0) + len += *(_fonts[fontIndex]->extraData + (*str++ - _fonts[fontIndex]->startItem)); + else + len = (strlen(str) * _fonts[fontIndex]->itemWidth); + + } + + return len; +} + +void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, int16 transp, SurfaceDesc *dest, Video::FontDesc *font) { while (*str != '\0') { @@ -337,7 +368,7 @@ void Draw::drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, } void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, - int16 bottom, char *str, int16 fontIndex, int16 color) { + int16 bottom, const char *str, int16 fontIndex, int16 color) { adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 9ba589aa53..897208a42d 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -69,7 +69,7 @@ public: int16 _destSurface; char _letterToPrint; - char *_textToPrint; + const char *_textToPrint; int16 _backDeltaX; int16 _backDeltaY; @@ -146,10 +146,11 @@ public: void adjustCoords(char adjust, uint16 *coord1, uint16 *coord2) { adjustCoords(adjust, (int16 *) coord1, (int16 *) coord2); } - void drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, + int stringLength(const char *str, int16 fontIndex); + void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, int16 transp, SurfaceDesc *dest, Video::FontDesc *font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, - int16 bottom, char *str, int16 fontIndex, int16 color); + int16 bottom, const char *str, int16 fontIndex, int16 color); int32 getSpriteRectSize(int16 index); void forceBlit(bool backwards = false); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 34443251d8..3bae48c679 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -62,7 +62,9 @@ const Common::Language GobEngine::_gobToScummVMLang[] = { Common::EN_USA, Common::NL_NLD, Common::KO_KOR, - Common::HB_ISR + Common::HB_ISR, + Common::PT_BRA, + Common::JA_JPN }; GobEngine::GobEngine(OSystem *syst) : Engine(syst) { @@ -120,7 +122,7 @@ void GobEngine::shutdown() { } const char *GobEngine::getLangDesc(int16 language) const { - if ((language < 0) || (language > 8)) + if ((language < 0) || (language > 10)) language = 2; return Common::getLanguageDescription(_gobToScummVMLang[language]); } @@ -244,6 +246,12 @@ int GobEngine::init() { case Common::HB_ISR: _global->_language = 8; break; + case Common::PT_BRA: + _global->_language = 9; + break; + case Common::JA_JPN: + _global->_language = 10; + break; default: // Default to English _global->_language = 2; @@ -387,6 +395,20 @@ bool GobEngine::initGameParts() { _saveLoad = new SaveLoad_v4(this, _targetName.c_str()); break; + case kGameTypeDynasty: + _init = new Init_v3(this); + _video = new Video_v2(this); + _inter = new Inter_v5(this); + _parse = new Parse_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _game = new Game_v2(this); + _map = new Map_v4(this); + _goblin = new Goblin_v4(this); + _scenery = new Scenery_v2(this); + _saveLoad = new SaveLoad_v4(this, _targetName.c_str()); + break; + default: deinitGameParts(); return false; diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 041658baea..b308fd4df0 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -93,7 +93,8 @@ enum GameType { kGameTypeBargon, kGameTypeWeen, kGameTypeLostInTime, - kGameTypeInca2 + kGameTypeInca2, + kGameTypeDynasty }; enum Features { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index b684be6c07..ad59d0d15a 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -529,6 +529,64 @@ protected: void o4_playVmdOrMusic(); }; +class Inter_v5 : public Inter_v4 { +public: + Inter_v5(GobEngine *vm); + virtual ~Inter_v5() {} + +protected: + typedef void (Inter_v5::*OpcodeDrawProcV5)(); + typedef bool (Inter_v5::*OpcodeFuncProcV5)(OpFuncParams &); + typedef void (Inter_v5::*OpcodeGoblinProcV5)(OpGobParams &); + struct OpcodeDrawEntryV5 { + OpcodeDrawProcV5 proc; + const char *desc; + }; + struct OpcodeFuncEntryV5 { + OpcodeFuncProcV5 proc; + const char *desc; + }; + struct OpcodeGoblinEntryV5 { + OpcodeGoblinProcV5 proc; + const char *desc; + }; + const OpcodeDrawEntryV5 *_opcodesDrawV5; + const OpcodeFuncEntryV5 *_opcodesFuncV5; + const OpcodeGoblinEntryV5 *_opcodesGoblinV5; + static const int _goblinFuncLookUp[][2]; + + virtual void setupOpcodes(); + virtual void executeDrawOpcode(byte i); + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); + virtual const char *getOpcodeDrawDesc(byte i); + virtual const char *getOpcodeFuncDesc(byte i, byte j); + virtual const char *getOpcodeGoblinDesc(int i); + + byte _byte_8AA14; + + void o5_deleteFile(); + + bool o5_istrlen(OpFuncParams ¶ms); + + void o5_spaceShooter(OpGobParams ¶ms); + void o5_getSystemCDSpeed(OpGobParams ¶ms); + void o5_getSystemRAM(OpGobParams ¶ms); + void o5_getSystemCPUSpeed(OpGobParams ¶ms); + void o5_getSystemDrawSpeed(OpGobParams ¶ms); + void o5_totalSystemSpecs(OpGobParams ¶ms); + void o5_saveSystemSpecs(OpGobParams ¶ms); + void o5_loadSystemSpecs(OpGobParams ¶ms); + + void o5_gob92(OpGobParams ¶ms); + void o5_gob95(OpGobParams ¶ms); + void o5_gob96(OpGobParams ¶ms); + void o5_gob97(OpGobParams ¶ms); + void o5_gob98(OpGobParams ¶ms); + void o5_gob100(OpGobParams ¶ms); + void o5_gob200(OpGobParams ¶ms); +}; + } // End of namespace Gob #endif // GOB_INTER_H diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp new file mode 100644 index 0000000000..5137b71580 --- /dev/null +++ b/engines/gob/inter_v5.cpp @@ -0,0 +1,1035 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" +#include "common/file.h" + +#include "gob/gob.h" +#include "gob/inter.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/parse.h" +#include "gob/draw.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_v5, x) + +const int Inter_v5::_goblinFuncLookUp[][2] = { + {0, 0}, + {1, 0}, + {80, 1}, + {81, 2}, + {82, 3}, + {83, 4}, + {84, 5}, + {85, 6}, + {86, 7}, + {87, 0}, + {88, 0}, + {89, 0}, + {90, 0}, + {91, 0}, + {92, 8}, + {93, 0}, + {94, 0}, + {95, 9}, + {96, 10}, + {97, 11}, + {98, 12}, + {99, 0}, + {100, 13}, + {200, 14}, + {30, 24}, + {32, 25}, + {33, 26}, + {34, 27}, + {35, 28}, + {36, 29}, + {37, 30}, + {40, 31}, + {41, 32}, + {42, 33}, + {43, 34}, + {44, 35}, + {50, 36}, + {52, 37}, + {53, 38}, + {100, 39}, + {152, 40}, + {200, 41}, + {201, 42}, + {202, 43}, + {203, 44}, + {204, 45}, + {250, 46}, + {251, 47}, + {252, 48}, + {500, 49}, + {502, 50}, + {503, 51}, + {600, 52}, + {601, 53}, + {602, 54}, + {603, 55}, + {604, 56}, + {605, 57}, + {1000, 58}, + {1001, 59}, + {1002, 60}, + {1003, 61}, + {1004, 62}, + {1005, 63}, + {1006, 64}, + {1008, 65}, + {1009, 66}, + {1010, 67}, + {1011, 68}, + {1015, 69}, + {2005, 70} +}; + +Inter_v5::Inter_v5(GobEngine *vm) : Inter_v4(vm) { + setupOpcodes(); +} + +void Inter_v5::setupOpcodes() { + static const OpcodeDrawEntryV5 opcodesDraw[256] = { + /* 00 */ + OPCODE(o1_loadMult), + OPCODE(o2_playMult), + OPCODE(o2_freeMultKeys), + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_initCursor), + /* 08 */ + OPCODE(o1_initCursorAnim), + OPCODE(o1_clearCursorAnim), + OPCODE(o2_setRenderFlags), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + OPCODE(o1_loadAnim), + OPCODE(o1_freeAnim), + OPCODE(o1_updateAnim), + OPCODE(o2_multSub), + /* 14 */ + OPCODE(o2_initMult), + OPCODE(o1_freeMult), + OPCODE(o1_animate), + OPCODE(o2_loadMultObject), + /* 18 */ + OPCODE(o1_getAnimLayerInfo), + OPCODE(o1_getObjAnimSize), + OPCODE(o1_loadStatic), + OPCODE(o1_freeStatic), + /* 1C */ + OPCODE(o2_renderStatic), + OPCODE(o2_loadCurLayer), + {NULL, ""}, + {NULL, ""}, + /* 20 */ + OPCODE(o2_playCDTrack), + OPCODE(o2_waitCDTrackEnd), + OPCODE(o2_stopCD), + OPCODE(o2_readLIC), + /* 24 */ + OPCODE(o2_freeLIC), + OPCODE(o2_getCDTrackPos), + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o2_loadFontToSprite), + OPCODE(o1_freeFontToSprite), + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + OPCODE(o2_totSub), + OPCODE(o2_switchTotSub), + OPCODE(o2_copyVars), + OPCODE(o2_pasteVars), + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 48 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 4C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 50 */ + OPCODE(o2_loadMapObjects), + OPCODE(o2_freeGoblins), + OPCODE(o2_moveGoblin), + OPCODE(o2_writeGoblinPos), + /* 54 */ + OPCODE(o2_stopGoblin), + OPCODE(o2_setGoblinState), + OPCODE(o2_placeGoblin), + {NULL, ""}, + /* 58 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 5C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 60 */ + {NULL, ""}, + OPCODE(o5_deleteFile), + {NULL, ""}, + {NULL, ""}, + /* 64 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 68 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 6C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 70 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 74 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 78 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 7C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 80 */ + OPCODE(o4_initScreen), + OPCODE(o2_scroll), + OPCODE(o2_setScrollOffset), + OPCODE(o4_playVmdOrMusic), + /* 84 */ + OPCODE(o2_getImdInfo), + OPCODE(o2_openItk), + OPCODE(o2_closeItk), + OPCODE(o2_setImdFrontSurf), + /* 88 */ + OPCODE(o2_resetImdFrontSurf), + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 8C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 90 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 94 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 98 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 9C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* AC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* BC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* CC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* DC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* EC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* FC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""} + }; + + static const OpcodeFuncEntryV5 opcodesFunc[80] = { + /* 00 */ + OPCODE(o1_callSub), + OPCODE(o1_callSub), + OPCODE(o1_printTotText), + OPCODE(o1_loadCursor), + /* 04 */ + {NULL, ""}, + OPCODE(o1_switch), + OPCODE(o1_repeatUntil), + OPCODE(o1_whileDo), + /* 08 */ + OPCODE(o1_if), + OPCODE(o2_evaluateStore), + OPCODE(o1_loadSpriteToPos), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + OPCODE(o2_printText), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), + /* 14 */ + OPCODE(o1_keyFunc), + OPCODE(o1_capturePush), + OPCODE(o1_capturePop), + OPCODE(o2_animPalInit), + /* 18 */ + OPCODE(o2_addCollision), + OPCODE(o2_freeCollision), + OPCODE(o3_getTotTextItemPart), + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_drawOperations), + OPCODE(o1_setcmdCount), + /* 20 */ + OPCODE(o1_return), + OPCODE(o1_renewTimeInVars), + OPCODE(o1_speakerOn), + OPCODE(o1_speakerOff), + /* 24 */ + OPCODE(o1_putPixel), + OPCODE(o2_goblinFunc), + OPCODE(o2_createSprite), + OPCODE(o1_freeSprite), + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_returnTo), + OPCODE(o1_loadSpriteContent), + OPCODE(o1_copySprite), + OPCODE(o1_fillRect), + /* 34 */ + OPCODE(o1_drawLine), + OPCODE(o1_strToLong), + OPCODE(o1_invalidate), + OPCODE(o1_setBackDelta), + /* 38 */ + OPCODE(o1_playSound), + OPCODE(o2_stopSound), + OPCODE(o2_loadSound), + OPCODE(o1_freeSoundSlot), + /* 3C */ + OPCODE(o1_waitEndPlay), + OPCODE(o1_playComposition), + OPCODE(o2_getFreeMem), + OPCODE(o2_checkData), + /* 40 */ + {NULL, ""}, + OPCODE(o1_prepareStr), + OPCODE(o1_insertStr), + OPCODE(o1_cutStr), + /* 44 */ + OPCODE(o1_strstr), + OPCODE(o5_istrlen), + OPCODE(o1_setMousePos), + OPCODE(o1_setFrameRate), + /* 48 */ + OPCODE(o1_animatePalette), + OPCODE(o1_animateCursor), + OPCODE(o1_blitCursor), + OPCODE(o1_loadFont), + /* 4C */ + OPCODE(o1_freeFont), + OPCODE(o2_readData), + OPCODE(o2_writeData), + OPCODE(o1_manageDataFile), + }; + + static const OpcodeGoblinEntryV5 opcodesGoblin[71] = { + /* 00 */ + OPCODE(o5_spaceShooter), + OPCODE(o5_getSystemCDSpeed), + OPCODE(o5_getSystemRAM), + OPCODE(o5_getSystemCPUSpeed), + /* 04 */ + OPCODE(o5_getSystemDrawSpeed), + OPCODE(o5_totalSystemSpecs), + OPCODE(o5_saveSystemSpecs), + OPCODE(o5_loadSystemSpecs), + /* 08 */ + OPCODE(o5_gob92), + OPCODE(o5_gob95), + OPCODE(o5_gob96), + OPCODE(o5_gob97), + /* 0C */ + OPCODE(o5_gob98), + OPCODE(o5_gob100), + OPCODE(o5_gob200), + {NULL, ""}, + /* 10 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 14 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 20 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 24 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + }; + + _opcodesDrawV5 = opcodesDraw; + _opcodesFuncV5 = opcodesFunc; + _opcodesGoblinV5 = opcodesGoblin; +} + +void Inter_v5::executeDrawOpcode(byte i) { + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcV5 op = _opcodesDrawV5[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_v5::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %d, %d", + i, j, i, j, getOpcodeFuncDesc(i, j), _vm->_game->_curTotFile, + (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData), + (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData - params.counter - 4)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d", i, j); + return false; + } + + OpcodeFuncProcV5 op = _opcodesFuncV5[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (params); + + return false; +} + +void Inter_v5::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); + + OpcodeGoblinProcV5 op = NULL; + + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) { + op = _opcodesGoblinV5[_goblinFuncLookUp[j][1]].proc; + break; + } + + _vm->_global->_inter_execPtr -= 2; + + if (op == NULL) { + warning("unimplemented opcodeGoblin: %d", i); + + int16 paramCount = load16(); + _vm->_global->_inter_execPtr += paramCount * 2; + } else { + params.extraData = i; + + (this->*op) (params); + } +} + +const char *Inter_v5::getOpcodeDrawDesc(byte i) { + return _opcodesDrawV5[i].desc; +} + +const char *Inter_v5::getOpcodeFuncDesc(byte i, byte j) { + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncV5[i*16 + j].desc; +} + +const char *Inter_v5::getOpcodeGoblinDesc(int i) { + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) + return _opcodesGoblinV5[_goblinFuncLookUp[j][1]].desc; + return ""; +} + +void Inter_v5::o5_deleteFile() { + evalExpr(0); + + warning("Dynasty Stub: deleteFile \"%s\"", _vm->_global->_inter_resStr); +} + +bool Inter_v5::o5_istrlen(OpFuncParams ¶ms) { + int16 strVar1, strVar2; + int16 len; + + if (*_vm->_global->_inter_execPtr == 0x80) { + _vm->_global->_inter_execPtr++; + + strVar1 = _vm->_parse->parseVarIndex(); + strVar2 = _vm->_parse->parseVarIndex(); + + len = _vm->_draw->stringLength(GET_VARO_STR(strVar1), READ_VARO_UINT16(strVar2)); + + } else { + + strVar1 = _vm->_parse->parseVarIndex(); + strVar2 = _vm->_parse->parseVarIndex(); + + if (_vm->_global->_language == 10) { + // Extra handling for Japanese strings + + for (len = 0; READ_VARO_UINT8(strVar1) != 0; strVar1++, len++) + if (READ_VARO_UINT8(strVar1) >= 128) + strVar1++; + + } else + len = strlen(GET_VARO_STR(strVar1)); + } + + WRITE_VAR_OFFSET(strVar2, len); + return false; +} + +void Inter_v5::o5_spaceShooter(OpGobParams ¶ms) { + int16 paramCount = load16(); + + warning("Dynasty Stub: Space shooter: %d, %d, %s", + params.extraData, paramCount, _vm->_game->_curTotFile); + + if (paramCount < 4) { + warning("Space shooter variable counter < 4"); + _vm->_global->_inter_execPtr += paramCount * 2; + return; + } + + uint32 var1 = load16() * 4; + uint32 var2 = load16() * 4; + uint32 var3 = load16() * 4; + uint16 var4 = load16(); + + if (params.extraData != 0) { + WRITE_VARO_UINT32(var1, 0); + WRITE_VARO_UINT32(var2, 0); + } else { + if (paramCount < 5) { + warning("Space shooter variable counter < 5"); + return; + } + + _vm->_global->_inter_execPtr += (paramCount - 4) * 2; + } +} + +void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + + Video::FontDesc *font; + if ((font = _vm->_util->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->forceBlit(); + + _vm->_util->freeFont(font); + } +} + +void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + + Video::FontDesc *font; + if ((font = _vm->_util->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->forceBlit(); + + _vm->_util->freeFont(font); + } +} + +void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + + Video::FontDesc *font; + if ((font = _vm->_util->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->forceBlit(); + + _vm->_util->freeFont(font); + } +} + +void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + + Video::FontDesc *font; + if ((font = _vm->_util->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->forceBlit(); + + _vm->_util->freeFont(font); + } +} + +void Inter_v5::o5_totalSystemSpecs(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + + Video::FontDesc *font; + if ((font = _vm->_util->loadFont("SPEED.LET"))) { + _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->forceBlit(); + + _vm->_util->freeFont(font); + } +} + +void Inter_v5::o5_saveSystemSpecs(OpGobParams ¶ms) { + warning("Dynasty Stub: Saving system specifications"); + + _vm->_global->_inter_execPtr += 2; + +/* + FILE *f = fopen("SAVE\\SPEED.INF", w); + fwrite(&_cdSpeed, sizeof(_cdSpeed), 1, f); + fwrite(&_ram, sizeof(_ram), 1, f); + fwrite(&_cpuSpeed, sizeof(_cpuSpeed), 1, f); + fwrite(&_drawSpeed, sizeof(_drawSpeed), 1, f); + fwrite(&_total, sizeof(_total), 1, f); + fclose(f); +*/ +} + +void Inter_v5::o5_loadSystemSpecs(OpGobParams ¶ms) { + warning("Dynasty Stub: Loading system specifications"); + + _vm->_global->_inter_execPtr += 2; + +/* + FILE *f = fopen("SAVE\\SPEED.INF", r); + fread(&_cdSpeed, sizeof(_cdSpeed), 1, f); + fread(&_ram, sizeof(_ram), 1, f); + fread(&_cpuSpeed, sizeof(_cpuSpeed), 1, f); + fread(&_drawSpeed, sizeof(_drawSpeed), 1, f); + fread(&_total, sizeof(_total), 1, f); + fclose(f); +*/ + +/* + // Calculating whether speed throttling is necessary? + + var_E = MAX(_cdSpeed, 150); + var_E += (_ram << 3); + var_E += (_cpuSpeed << 3); + var_E /= 17; + + byte_8A61E = (var_E > 81) ? 1 : 0; + byte_8A5E0 = (_total >= 95) ? 1 : 0; + + if (byte_8A5E0 == 1) { + word_8AEE2 = 100; + byte_8AEE4 = 1; + byte_8AEE5 = 1; + word_8AEE6 = 0; + } else { + word_8AEE2 = 0; + byte_8AEE4 = 0; + byte_8AEE5 = 0; + word_8AEE6 = 40; + } +*/ +} + +void Inter_v5::o5_gob92(OpGobParams ¶ms) { + warning("Dynasty Stub: GobFunc 92"); + + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) byte_86B9E)) */); +} + +void Inter_v5::o5_gob95(OpGobParams ¶ms) { + warning("Dynasty Stub: GobFunc 95"); + + _vm->_global->_inter_execPtr += 2; + + WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int16) word_8AEE6)) */); + WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) byte_8AEE5)) */); + WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) byte_8AEE4)) */); + WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int16) word_8AEE2)) */); +} + +void Inter_v5::o5_gob96(OpGobParams ¶ms) { + int16 word_8AEE6, word_85B50, word_8AEE2; + byte byte_8AEE5, byte_8AEE4; + + _vm->_global->_inter_execPtr += 2; + + word_8AEE6 = word_85B50 = READ_VAR_UINT16(load16()); + byte_8AEE5 = READ_VAR_UINT8(load16()); + byte_8AEE4 = READ_VAR_UINT8(load16()); + word_8AEE2 = READ_VAR_UINT16(load16()); + + warning("Dynasty Stub: GobFunc 96: %d, %d, %d, %d", + word_8AEE6, byte_8AEE5, byte_8AEE4, word_8AEE2); + + // .--- sub_194B0 --- + + int16 word_8A8F0, word_8A8F2, word_8A8F4, word_8A8F6, word_8A8F8, word_8A8FA; + + int16 word_8A62C = 1; + int16 word_8A63C, word_8A640, word_8B464, word_8B466; + + byte byte_8A62E; + + int16 var_2, var_4; + + var_2 = word_85B50 + 31; + word_8A8F0 = word_8A8F2 = var_2; + word_8A8F4 = word_85B50; + + var_4 = 315 - word_85B50; + word_8A8F6 = word_8A8F8 = var_4; + + word_8A8FA = 479 - word_85B50; + + if (word_8A62C == 0) { + word_8A63C = word_8A8F0; + word_8A640 = word_8A8F6; + word_8B464 = word_8A8F0; + word_8B466 = word_8A8F6; + } else if (word_8A62C == 1) { + word_8A63C = word_85B50; + word_8A640 = word_8A8FA; + word_8B464 = word_85B50; + word_8B466 = word_8A8FA; + } else if (word_8A62C == 2) { + word_8A63C = word_8A8F4; + word_8A640 = word_8A8FA; + word_8B464 = word_8A8F4; + word_8B466 = word_8A8FA; + } else if (word_8A62C == 3) { + word_8A63C = word_8A8F4; + word_8A640 = word_8A8FA; + word_8B464 = word_8A8F4; + word_8B466 = word_8A8FA; + } else if (word_8A62C == 4) { + word_8A63C = word_8A8F4; + word_8A640 = word_8A8FA; + word_8B464 = word_8A8F4; + word_8B466 = word_8A8FA; + } + + byte_8A62E = 1; + +// '--- --- + +} + +void Inter_v5::o5_gob97(OpGobParams ¶ms) { + _byte_8AA14 = 1; + + _vm->_global->_inter_execPtr += 2; +} + +void Inter_v5::o5_gob98(OpGobParams ¶ms) { + _byte_8AA14 = 0; + + _vm->_global->_inter_execPtr += 2; +} + +void Inter_v5::o5_gob100(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + uint16 var1 = READ_VAR_UINT16(load16()); + uint16 var2 = READ_VAR_UINT16(load16()); + uint16 var3 = READ_VAR_UINT16(load16()); + uint16 var4 = READ_VAR_UINT16(load16()); + + warning("Dynasty Stub: GobFunc 100: %d, %d, %d, %d", var1, var2, var3, var4); + + var3 = (var3 + var1) - 1; + var4 = (var4 + var2) - 1; +} + +void Inter_v5::o5_gob200(OpGobParams ¶ms) { + _vm->_global->_inter_execPtr += 2; + + uint16 var1 = load16(); // index into the spritesArray + uint16 var2 = load16(); + uint16 var3 = load16(); + + warning("Dynasty Stub: GobFunc 200: %d, %d, %d", var1, var2, var3); +} + +} // End of namespace Gob diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 45048a0899..c69f76b2c3 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -30,6 +30,7 @@ MODULE_OBJS := \ inter_bargon.o \ inter_v3.o \ inter_v4.o \ + inter_v5.o \ map.o \ map_v1.o \ map_v2.o \ diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index a2e6b8fb37..f26d051ab5 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -116,6 +116,7 @@ int16 Parse_v2::parseValExpr(byte stopToken) { int16 brackPos; static int16 flag = 0; int16 oldflag; + uint32 varPos = 0; memset(values, 0, 20 * sizeof(int16)); @@ -130,11 +131,61 @@ int16 Parse_v2::parseValExpr(byte stopToken) { valPtr = values - 1; while (1) { + operation = *_vm->_global->_inter_execPtr++; + + while ((operation == 14) || (operation == 15)) { + if (operation == 14) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + _vm->_global->_inter_execPtr += 2; + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } else if (operation == 15) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + uint16 var_0C = _vm->_inter->load16(); + uint8 var_A = *_vm->_global->_inter_execPtr++; + + byte *var_12 = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += var_A; + + uint16 var_6 = 0; + + for (int i = 0; i < var_A; i++) { + temp2 = parseValExpr(12); + + //uint16 ax = sub_12063(temp2, var_12[i], varPos, 0); + + uint16 ax; + + if (temp2 < 0) { + ax = 0; + } else if (var_12[i] > temp2) { + ax = temp2; + } else { + ax = var_12[i] - 1; + } + + var_6 = var_6 * var_12[i] + ax; + } + + varPos += var_6 * var_0C * 4; + + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } + + warning("v5+ Stub: parseValExpr operation %d, offset %d", operation, varPos); + + operation = *_vm->_global->_inter_execPtr++; + } + stkPos++; operPtr++; valPtr++; - operation = *_vm->_global->_inter_execPtr++; if ((operation >= 16) && (operation <= 29)) { *operPtr = 20; switch (operation) { @@ -373,6 +424,7 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { bool var_1A; int16 stkPos; int16 brackStart; + uint32 varPos = 0; memset(operStack, 0, 20); @@ -381,10 +433,61 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { valPtr = values - 1; while (1) { + operation = *_vm->_global->_inter_execPtr++; + + while ((operation == 14) || (operation == 15)) { + if (operation == 14) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + _vm->_global->_inter_execPtr += 2; + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } else if (operation == 15) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + uint16 var_0C = _vm->_inter->load16(); + uint8 var_A = *_vm->_global->_inter_execPtr++; + + byte *var_12 = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += var_A; + + uint16 var_6 = 0; + + for (int i = 0; i < var_A; i++) { + temp2 = parseValExpr(12); + + //uint16 ax = sub_12063(temp2, var_12[i], varPos, 0); + + uint16 ax; + + if (temp2 < 0) { + ax = 0; + } else if (var_12[i] > temp2) { + ax = temp2; + } else { + ax = var_12[i] - 1; + } + + var_6 = var_6 * var_12[i] + ax; + } + + varPos += var_6 * var_0C * 4; + + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } + + warning("v5+ Stub: parseExpr operation %d, offset %d", operation, varPos); + + operation = *_vm->_global->_inter_execPtr++; + } + stkPos++; operPtr++; valPtr++; - operation = *_vm->_global->_inter_execPtr++; + if ((operation >= 16) && (operation <= 29)) { switch (operation) { case 16: |