diff options
Diffstat (limited to 'engines/made')
-rw-r--r-- | engines/made/database.cpp | 154 | ||||
-rw-r--r-- | engines/made/database.h | 11 | ||||
-rw-r--r-- | engines/made/made.cpp | 5 | ||||
-rw-r--r-- | engines/made/made.h | 4 | ||||
-rw-r--r-- | engines/made/module.mk | 4 | ||||
-rw-r--r-- | engines/made/resource.cpp | 16 | ||||
-rw-r--r-- | engines/made/resource.h | 12 | ||||
-rw-r--r-- | engines/made/script.cpp | 119 | ||||
-rw-r--r-- | engines/made/scriptfuncs.h | 134 | ||||
-rw-r--r-- | engines/made/scriptfuncs_lgop2.cpp | 467 | ||||
-rw-r--r-- | engines/made/scriptfuncs_mhne.cpp | 494 | ||||
-rw-r--r-- | engines/made/scriptfuncs_rtz.cpp | 864 |
12 files changed, 2141 insertions, 143 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp index 108d1391e5..406639a1fc 100644 --- a/engines/made/database.cpp +++ b/engines/made/database.cpp @@ -47,7 +47,7 @@ Object::~Object() { delete[] _objData; } -int Object::load(Common::SeekableReadStream &source) { +int Object::loadVersion2(Common::SeekableReadStream &source) { _freeData = true; uint16 type = source.readUint16LE(); if (type == 0x7FFF) { @@ -59,6 +59,27 @@ int Object::load(Common::SeekableReadStream &source) { byte count2 = source.readByte(); _objSize = (count1 + count2) * 2; } + source.seek(-4, SEEK_CUR); + _objSize += 6; + _objData = new byte[_objSize]; + WRITE_LE_UINT16(_objData, 1); + source.read(_objData + 2, _objSize - 2); + return _objSize - 2; +} + +int Object::loadVersion3(Common::SeekableReadStream &source) { + _freeData = true; + source.readUint16LE(); // skip flags + uint16 type = source.readUint16LE(); + if (type == 0x7FFF) { + _objSize = source.readUint16LE(); + } else if (type == 0x7FFE) { + _objSize = source.readUint16LE() * 2; + } else if (type < 0x7FFE) { + byte count1 = source.readByte(); + byte count2 = source.readByte(); + _objSize = (count1 + count2) * 2; + } source.seek(-6, SEEK_CUR); _objSize += 6; _objData = new byte[_objSize]; @@ -66,7 +87,7 @@ int Object::load(Common::SeekableReadStream &source) { return _objSize; } -int Object::load(byte *source) { +int Object::loadVersion3(byte *source) { _objData = source; _freeData = false; if (getClass() < 0x7FFE) { @@ -175,11 +196,14 @@ void Object::dump(const char *filename) { } GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) { + _gameText = NULL; } GameDatabase::~GameDatabase() { if (_gameState) delete[] _gameState; + if (_gameText) + delete[] _gameText; } void GameDatabase::open(const char *filename) { @@ -218,7 +242,7 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) { sourceS.seek(0x1C); - uint32 textStartOffs = sourceS.readUint16LE() * 512; + uint32 textOffs = sourceS.readUint16LE() * 512; uint16 objectCount = sourceS.readUint16LE(); uint16 varObjectCount = sourceS.readUint16LE(); _gameStateSize = sourceS.readUint16LE() * 2; @@ -228,25 +252,31 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) { _mainCodeObjectIndex = sourceS.readUint16LE(); sourceS.readUint16LE(); // unknown uint32 objectsSize = sourceS.readUint32LE() * 2; + uint32 textSize = objectsOffs - textOffs; - debug(2, "textStartOffs = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textStartOffs, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize); + debug(2, "textOffs = %08X; textSize = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textOffs, textSize, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize); _gameState = new byte[_gameStateSize]; memset(_gameState, 0, _gameStateSize); + sourceS.seek(textOffs); + _gameText = new char[textSize]; + sourceS.read(_gameText, textSize); + // "Decrypt" the text data + for (int i = 0; i < textSize; i++) + _gameText[i] += 0x1E; + sourceS.seek(objectsOffs); for (uint32 i = 0; i < objectCount; i++) { Object *obj = new Object(); - int objSize = obj->load(sourceS); + int objSize = obj->loadVersion2(sourceS); objSize = objSize % 2; // objects are aligned on 2-byte-boundaries, skip unused bytes sourceS.skip(objSize); _objects.push_back(obj); } - printf("ok!\n"); fflush(stdout); - } void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) { @@ -286,11 +316,10 @@ void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) { if (objectOffsets[i] & 1) { debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1); sourceS.seek(objectsOffs + objectOffsets[i] - 1); - sourceS.readUint16LE(); // skip flags - obj->load(sourceS); + obj->loadVersion3(sourceS); } else { debug(2, "-> var\n"); - obj->load(_gameState + objectOffsets[i]); + obj->loadVersion3(_gameState + objectOffsets[i]); } _objects.push_back(obj); } @@ -378,13 +407,80 @@ void GameDatabase::setVar(int16 index, int16 value) { WRITE_LE_UINT16(_gameState + index * 2, value); } -int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) { +int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag) { Object *obj = getObject(objectIndex); int16 *prop = (int16*)obj->getData(); byte count1 = obj->getCount1(); byte count2 = obj->getCount2(); - + + int16 *propPtr1 = prop + count1; + int16 *propPtr2 = prop + count2; + + // First see if the property exists in the given object + while (count2-- > 0) { + if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) { + propertyFlag = obj->getFlags() & 1; + return propPtr1; + } + prop++; + propPtr1++; + } + + // Now check in the object hierarchy of the given object + int16 parentObjectIndex = obj->getClass(); + if (parentObjectIndex == 0) { + //debug(2, "! NULL(np)\n"); + return NULL; + } + + while (parentObjectIndex != 0) { + + //debug(2, "parentObjectIndex = %04X\n", parentObjectIndex); + + obj = getObject(parentObjectIndex); + + prop = (int16*)obj->getData(); + count1 = obj->getCount1(); + count2 = obj->getCount2(); + + propPtr1 = propPtr2 + count1 - count2; + int16 *propertyPtr = prop + count1; + + while (count2-- > 0) { + if (!(READ_LE_UINT16(prop) & 0x8000)) { + if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) { + propertyFlag = obj->getFlags() & 1; + return propPtr1; + } else { + propPtr1++; + } + } else { + if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) { + propertyFlag = obj->getFlags() & 1; + return propertyPtr; + } + } + prop++; + propertyPtr++; + } + + parentObjectIndex = obj->getClass(); + + } + + //debug(2, "! NULL(nf)\n"); + return NULL; + +} + +int16 *GameDatabase::getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId, int16 &propertyFlag) { + Object *obj = getObject(objectIndex); + + int16 *prop = (int16*)obj->getData(); + byte count1 = obj->getCount1(); + byte count2 = obj->getCount2(); + int16 *propPtr1 = prop + count1; int16 *propPtr2 = prop + count2; @@ -402,27 +498,27 @@ int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, i prop++; propPtr1++; } - + // Now check in the object hierarchy of the given object int16 parentObjectIndex = obj->getClass(); if (parentObjectIndex == 0) { //debug(2, "! NULL(np)\n"); return NULL; } - + while (parentObjectIndex != 0) { - + //debug(2, "parentObjectIndex = %04X\n", parentObjectIndex); obj = getObject(parentObjectIndex); - + prop = (int16*)obj->getData(); count1 = obj->getCount1(); count2 = obj->getCount2(); propPtr1 = propPtr2 + count1 - count2; int16 *propertyPtr = prop + count1; - + while (count2-- > 0) { if (!(READ_LE_UINT16(prop) & 0x8000)) { if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) { @@ -450,14 +546,26 @@ int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, i prop++; propertyPtr++; } - + parentObjectIndex = obj->getClass(); - + } //debug(2, "! NULL(nf)\n"); return NULL; - + +} + +int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) { + switch (_vm->_engineVersion) { + case 2: + return getObjectPropertyPtrV2(objectIndex, propertyId, propertyFlag); + case 3: + return getObjectPropertyPtrV3(objectIndex, propertyId, propertyFlag); + default: + error("GameDatabase::getObjectPropertyPtr() Unknown engine version"); + return NULL; + } } int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) { @@ -467,7 +575,7 @@ int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) { int16 propertyFlag; int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag); - + if (property) { return (int16)READ_LE_UINT16(property); } else { @@ -498,6 +606,10 @@ int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 } +const char *GameDatabase::getString(uint16 offset) { + return (const char*)&_gameText[offset * 4]; +} + void GameDatabase::dumpObject(int16 index) { Object *obj = getObject(index); char fn[512]; diff --git a/engines/made/database.h b/engines/made/database.h index adaf91f6d3..b92bd8f2dd 100644 --- a/engines/made/database.h +++ b/engines/made/database.h @@ -41,8 +41,9 @@ class Object { public: Object(); ~Object(); - int load(Common::SeekableReadStream &source); - int load(byte *source); + int loadVersion2(Common::SeekableReadStream &source); + int loadVersion3(Common::SeekableReadStream &source); + int loadVersion3(byte *source); uint16 getFlags() const; uint16 getClass() const; @@ -96,9 +97,14 @@ public: int16 getVar(int16 index); void setVar(int16 index, int16 value); + int16 *getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag); + int16 *getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId, int16 &propertyFlag); int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag); + int16 getObjectProperty(int16 objectIndex, int16 propertyId); int16 setObjectProperty(int16 objectIndex, int16 propertyId, int16 value); + + const char *getString(uint16 offset); void dumpObject(int16 index); @@ -107,6 +113,7 @@ protected: Common::Array<Object*> _objects; byte *_gameState; uint32 _gameStateSize; + char *_gameText; int16 _mainCodeObjectIndex; void load(Common::SeekableReadStream &sourceS); void loadVersion2(Common::SeekableReadStream &sourceS); diff --git a/engines/made/made.cpp b/engines/made/made.cpp index e82b2957cf..932f5ddcc4 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -106,6 +106,8 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng if (!_musicVolume) { debug(1, "Music disabled."); } + + _soundRate = 8000; } @@ -161,6 +163,7 @@ int MadeEngine::go() { _timers[i] = -1; if (getGameID() == GID_RTZ) { + _engineVersion = 3; if (getFeatures() & GF_DEMO) { _dat->open("demo.dat"); _res->open("demo.prj"); @@ -177,9 +180,11 @@ int MadeEngine::go() { error("Unknown RTZ game features"); } } else if (getGameID() == GID_MANHOLE) { + _engineVersion = 2; _dat->open("manhole.dat"); _res->open("manhole.prj"); } else if (getGameID() == GID_LGOP2) { + _engineVersion = 2; _dat->open("lgop2.dat"); _res->open("lgop2.prj"); } else { diff --git a/engines/made/made.h b/engines/made/made.h index ea28222492..b3a25b4e02 100644 --- a/engines/made/made.h +++ b/engines/made/made.h @@ -106,6 +106,10 @@ public: uint16 _eventKey; int _soundRate; int _musicVolume; + + // 2 = LGOP2, Manhole N&E + // 3 = Return to Zork + int _engineVersion; int32 _timers[50]; int16 getTimer(int16 timerNum); diff --git a/engines/made/module.mk b/engines/made/module.mk index 9963f19660..2c1219d09e 100644 --- a/engines/made/module.mk +++ b/engines/made/module.mk @@ -11,7 +11,9 @@ MODULE_OBJS = \ resource.o \ screen.o \ script.o \ - scriptfuncs.o \ + scriptfuncs_lgop2.o \ + scriptfuncs_mhne.o \ + scriptfuncs_rtz.o \ sound.o diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index 1eb04f6211..7151f2424a 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -257,17 +257,17 @@ byte *FontResource::getCharData(uint c) const { return _data + 1 + (c - 28) * (getHeight() + 1); } -/* XmidiResource */ +/* GenericResource */ -XmidiResource::XmidiResource() : _data(NULL), _size(0) { +GenericResource::GenericResource() : _data(NULL), _size(0) { } -XmidiResource::~XmidiResource() { +GenericResource::~GenericResource() { if (_data) delete[] _data; } -void XmidiResource::load(byte *source, int size) { +void GenericResource::load(byte *source, int size) { _data = new byte[size]; _size = size; memcpy(_data, source, size); @@ -341,8 +341,12 @@ FontResource *ProjectReader::getFont(int index) { return createResource<FontResource>(kResFONT, index); } -XmidiResource *ProjectReader::getXmidi(int index) { - return createResource<XmidiResource>(kResXMID, index); +GenericResource *ProjectReader::getXmidi(int index) { + return createResource<GenericResource>(kResXMID, index); +} + +GenericResource *ProjectReader::getMidi(int index) { + return createResource<GenericResource>(kResMIDI, index); } void ProjectReader::loadIndex(ResourceSlots *slots) { diff --git a/engines/made/resource.h b/engines/made/resource.h index 3dc055946f..be85561318 100644 --- a/engines/made/resource.h +++ b/engines/made/resource.h @@ -46,7 +46,8 @@ enum ResourceType { kResANIM = MKID_BE('ANIM'), kResMENU = MKID_BE('MENU'), kResFONT = MKID_BE('FONT'), - kResXMID = MKID_BE('XMID') + kResXMID = MKID_BE('XMID'), + kResMIDI = MKID_BE('MIDI') }; struct ResourceSlot; @@ -127,10 +128,10 @@ protected: byte *getCharData(uint c) const; }; -class XmidiResource : public Resource { +class GenericResource : public Resource { public: - XmidiResource(); - ~XmidiResource(); + GenericResource(); + ~GenericResource(); void load(byte *source, int size); byte *getData() const { return _data; } int getSize() const { return _size; } @@ -163,7 +164,8 @@ public: SoundResource *getSound(int index); MenuResource *getMenu(int index); FontResource *getFont(int index); - XmidiResource *getXmidi(int index); + GenericResource *getXmidi(int index); + GenericResource *getMidi(int index); void freeResource(Resource *resource); diff --git a/engines/made/script.cpp b/engines/made/script.cpp index ded516c8b8..74dc9e0d9f 100644 --- a/engines/made/script.cpp +++ b/engines/made/script.cpp @@ -33,110 +33,6 @@ namespace Made { - -const char *extendFuncNames[] = { - "SYSTEM", - "INITGRAF", - "RESTOREGRAF", - "DRAWPIC", - "CLS", - "SHOWPAGE", - "EVENT", - "EVENTX", - "EVENTY", - "EVENTKEY", - "VISUALFX", - "PLAYSND", - "PLAYMUS", - "STOPMUS", - "ISMUS", - "TEXTPOS", - "FLASH", - "PLAYNOTE", - "STOPNOTE", - "PLAYTELE", - "STOPTELE", - "HIDECURS", - "SHOWCURS", - "MUSICBEAT", - "SCREENLOCK", - "ADDSPRITE", - "FREEANIM", - "DRAWSPRITE", - "ERASESPRITES", - "UPDATESPRITES", - "GETTIMER", - "SETTIMER", - "RESETTIMER", - "ALLOCTIMER", - "FREETIMER", - "PALETTELOCK", - "FONT", - "DRAWTEXT", - "HOMETEXT", - "TEXTRECT", - "TEXTXY", - "DROPSHADOW", - "TEXTCOLOR", - "OUTLINE", - "LOADCURSOR", - "SETGROUND", - "RESTEXT", - "CLIPAREA", - "SETCLIP", - "ISSND", - "STOPSND", - "PLAYVOICE", - "CDPLAY", - "STOPCD", - "CDSTATUS", - "CDTIME", - "CDPLAYSEG", - "PRINTF", - "MONOCLS", - "SNDENERGY", - "CLEARTEXT", - "ANIMTEXT", - "TEXTWIDTH", - "PLAYMOVIE", - "LOADSND", - "LOADMUS", - "LOADPIC", - "MUSICVOL", - "RESTARTEVENTS", - "PLACESPRITE", - "PLACETEXT", - "DELETECHANNEL", - "CHANNELTYPE", - "SETSTATE", - "SETLOCATION", - "SETCONTENT", - "EXCLUDEAREA", - "SETEXCLUDE", - "GETSTATE", - "PLACEANIM", - "SETFRAME", - "GETFRAME", - "GETFRAMECOUNT", - "PICWIDTH", - "PICHEIGHT", - "SOUNDRATE", - "DRAWANIMPIC", - "LOADANIM", - "READTEXT", - "READMENU", - "DRAWMENU", - "MENUCOUNT", - "SAVEGAME", - "LOADGAME", - "GAMENAME", - "SHAKESCREEN", - "PLACEMENU", - "SETVOLUME", - "WHATSYNTH", - "SLOWSYSTEM" -}; - /* ScriptStack */ ScriptStack::ScriptStack() { @@ -275,8 +171,16 @@ ScriptInterpreter::ScriptInterpreter(MadeEngine *vm) : _vm(vm) { }; _commands = commandProcs; _commandsMax = ARRAYSIZE(commandProcs) + 1; - - _functions = new ScriptFunctionsRtz(_vm); + + if (_vm->getGameID() == GID_RTZ) + _functions = new ScriptFunctionsRtz(_vm); + else if (_vm->getGameID() == GID_LGOP2) + _functions = new ScriptFunctionsLgop2(_vm); + else if (_vm->getGameID() == GID_MANHOLE) + _functions = new ScriptFunctionsMhne(_vm); + else + error("Unsupported GameID"); + _functions->setupExternalsTable(); #undef COMMAND @@ -679,7 +583,8 @@ void ScriptInterpreter::cmd_extend() { byte argc = readByte(); int16 *argv = _stack.getStackPtr(); - debug(4, "func = %d (%s); argc = %d\n", func, extendFuncNames[func], argc); + //debug(4, "func = %d (%s); argc = %d\n", func, extendFuncNames[func], argc); + debug(4, "func = %d; argc = %d\n", func, argc); for (int i = 0; i < argc; i++) debug(4, "argv[%02d] = %04X (%d)\n", i, argv[i], argv[i]); diff --git a/engines/made/scriptfuncs.h b/engines/made/scriptfuncs.h index 2f6def0fa9..7e826a9f5e 100644 --- a/engines/made/scriptfuncs.h +++ b/engines/made/scriptfuncs.h @@ -41,7 +41,13 @@ class ScriptFunctions { public: ScriptFunctions(MadeEngine *vm) : _vm(vm) {} virtual ~ScriptFunctions() {} - int16 callFunction(uint16 index, int16 argc, int16 *argv); + int16 callFunction(uint16 index, int16 argc, int16 *argv) { + if (index >= _externalFuncs.size()) { + // TODO: ERROR! + return 0; + } + return (*_externalFuncs[index])(argc, argv); + } virtual void setupExternalsTable() = 0; protected: MadeEngine *_vm; @@ -52,6 +58,67 @@ protected: }; +class ScriptFunctionsLgop2 : public ScriptFunctions { +public: + ScriptFunctionsLgop2(MadeEngine *vm) : ScriptFunctions(vm) {} + ~ScriptFunctionsLgop2() {} + void setupExternalsTable(); +protected: + + int16 o1_SYSTEM(int16 argc, int16 *argv); + int16 o1_INITGRAF(int16 argc, int16 *argv); + int16 o1_RESTOREGRAF(int16 argc, int16 *argv); + int16 o1_DRAWPIC(int16 argc, int16 *argv); + int16 o1_CLS(int16 argc, int16 *argv); + int16 o1_SHOWPAGE(int16 argc, int16 *argv); + int16 o1_EVENT(int16 argc, int16 *argv); + int16 o1_EVENTX(int16 argc, int16 *argv); + int16 o1_EVENTY(int16 argc, int16 *argv); + int16 o1_EVENTKEY(int16 argc, int16 *argv); + int16 o1_VISUALFX(int16 argc, int16 *argv); + int16 o1_PLAYSND(int16 argc, int16 *argv); + int16 o1_PLAYMUS(int16 argc, int16 *argv); + int16 o1_STOPMUS(int16 argc, int16 *argv); + int16 o1_ISMUS(int16 argc, int16 *argv); + int16 o1_TEXTPOS(int16 argc, int16 *argv); + int16 o1_FLASH(int16 argc, int16 *argv); + int16 o1_PLAYNOTE(int16 argc, int16 *argv); + int16 o1_STOPNOTE(int16 argc, int16 *argv); + int16 o1_PLAYTELE(int16 argc, int16 *argv); + int16 o1_STOPTELE(int16 argc, int16 *argv); + int16 o1_HIDECURS(int16 argc, int16 *argv); + int16 o1_SHOWCURS(int16 argc, int16 *argv); + int16 o1_MUSICBEAT(int16 argc, int16 *argv); + int16 o1_SCREENLOCK(int16 argc, int16 *argv); + int16 o1_ADDSPRITE(int16 argc, int16 *argv); + int16 o1_FREEANIM(int16 argc, int16 *argv); + int16 o1_DRAWSPRITE(int16 argc, int16 *argv); + int16 o1_ERASESPRITES(int16 argc, int16 *argv); + int16 o1_UPDATESPRITES(int16 argc, int16 *argv); + int16 o1_GETTIMER(int16 argc, int16 *argv); + int16 o1_SETTIMER(int16 argc, int16 *argv); + int16 o1_RESETTIMER(int16 argc, int16 *argv); + int16 o1_ALLOCTIMER(int16 argc, int16 *argv); + int16 o1_FREETIMER(int16 argc, int16 *argv); + int16 o1_PALETTELOCK(int16 argc, int16 *argv); + int16 o1_FONT(int16 argc, int16 *argv); + int16 o1_DRAWTEXT(int16 argc, int16 *argv); + int16 o1_HOMETEXT(int16 argc, int16 *argv); + int16 o1_TEXTRECT(int16 argc, int16 *argv); + int16 o1_TEXTXY(int16 argc, int16 *argv); + int16 o1_DROPSHADOW(int16 argc, int16 *argv); + int16 o1_TEXTCOLOR(int16 argc, int16 *argv); + int16 o1_OUTLINE(int16 argc, int16 *argv); + int16 o1_LOADCURSOR(int16 argc, int16 *argv); + int16 o1_SETGROUND(int16 argc, int16 *argv); + int16 o1_RESTEXT(int16 argc, int16 *argv); + int16 o1_ADDMASK(int16 argc, int16 *argv); + int16 o1_SETMASK(int16 argc, int16 *argv); + int16 o1_ISSND(int16 argc, int16 *argv); + int16 o1_STOPSND(int16 argc, int16 *argv); + int16 o1_PLAYVOICE(int16 argc, int16 *argv); +}; + class ScriptFunctionsRtz : public ScriptFunctions { public: ScriptFunctionsRtz(MadeEngine *vm) : ScriptFunctions(vm) {} @@ -159,7 +226,72 @@ protected: int16 o1_SETVOLUME(int16 argc, int16 *argv); int16 o1_WHATSYNTH(int16 argc, int16 *argv); int16 o1_SLOWSYSTEM(int16 argc, int16 *argv); +}; + +class ScriptFunctionsMhne : public ScriptFunctions { +public: + ScriptFunctionsMhne(MadeEngine *vm) : ScriptFunctions(vm) {} + ~ScriptFunctionsMhne() {} + void setupExternalsTable(); +protected: + int16 o1_SYSTEM(int16 argc, int16 *argv); + int16 o1_INITGRAF(int16 argc, int16 *argv); + int16 o1_RESTOREGRAF(int16 argc, int16 *argv); + int16 o1_DRAWPIC(int16 argc, int16 *argv); + int16 o1_CLS(int16 argc, int16 *argv); + int16 o1_SHOWPAGE(int16 argc, int16 *argv); + int16 o1_EVENT(int16 argc, int16 *argv); + int16 o1_EVENTX(int16 argc, int16 *argv); + int16 o1_EVENTY(int16 argc, int16 *argv); + int16 o1_EVENTKEY(int16 argc, int16 *argv); + int16 o1_VISUALFX(int16 argc, int16 *argv); + int16 o1_PLAYSND(int16 argc, int16 *argv); + int16 o1_PLAYMUS(int16 argc, int16 *argv); + int16 o1_STOPMUS(int16 argc, int16 *argv); + int16 o1_ISMUS(int16 argc, int16 *argv); + int16 o1_TEXTPOS(int16 argc, int16 *argv); + int16 o1_FLASH(int16 argc, int16 *argv); + int16 o1_PLAYNOTE(int16 argc, int16 *argv); + int16 o1_STOPNOTE(int16 argc, int16 *argv); + int16 o1_PLAYTELE(int16 argc, int16 *argv); + int16 o1_STOPTELE(int16 argc, int16 *argv); + int16 o1_HIDECURS(int16 argc, int16 *argv); + int16 o1_SHOWCURS(int16 argc, int16 *argv); + int16 o1_MUSICBEAT(int16 argc, int16 *argv); + int16 o1_SCREENLOCK(int16 argc, int16 *argv); + int16 o1_ADDSPRITE(int16 argc, int16 *argv); + int16 o1_FREEANIM(int16 argc, int16 *argv); + int16 o1_DRAWSPRITE(int16 argc, int16 *argv); + int16 o1_ERASESPRITES(int16 argc, int16 *argv); + int16 o1_UPDATESPRITES(int16 argc, int16 *argv); + int16 o1_GETTIMER(int16 argc, int16 *argv); + int16 o1_SETTIMER(int16 argc, int16 *argv); + int16 o1_RESETTIMER(int16 argc, int16 *argv); + int16 o1_ALLOCTIMER(int16 argc, int16 *argv); + int16 o1_FREETIMER(int16 argc, int16 *argv); + int16 o1_PALETTELOCK(int16 argc, int16 *argv); + int16 o1_FONT(int16 argc, int16 *argv); + int16 o1_DRAWTEXT(int16 argc, int16 *argv); + int16 o1_HOMETEXT(int16 argc, int16 *argv); + int16 o1_TEXTRECT(int16 argc, int16 *argv); + int16 o1_TEXTXY(int16 argc, int16 *argv); + int16 o1_DROPSHADOW(int16 argc, int16 *argv); + int16 o1_TEXTCOLOR(int16 argc, int16 *argv); + int16 o1_OUTLINE(int16 argc, int16 *argv); + int16 o1_LOADCURSOR(int16 argc, int16 *argv); + int16 o1_SETGROUND(int16 argc, int16 *argv); + int16 o1_RESTEXT(int16 argc, int16 *argv); + int16 o1_ADDMASK(int16 argc, int16 *argv); + int16 o1_SETMASK(int16 argc, int16 *argv); + int16 o1_ISSND(int16 argc, int16 *argv); + int16 o1_STOPSND(int16 argc, int16 *argv); + int16 o1_PLAYVOICE(int16 argc, int16 *argv); + int16 o1_CDPLAY(int16 argc, int16 *argv); + int16 o1_STOPCD(int16 argc, int16 *argv); + int16 o1_CDSTATUS(int16 argc, int16 *argv); + int16 o1_CDTIME(int16 argc, int16 *argv); + int16 o1_CDPLAYSEG(int16 argc, int16 *argv); }; } // End of namespace Made diff --git a/engines/made/scriptfuncs_lgop2.cpp b/engines/made/scriptfuncs_lgop2.cpp new file mode 100644 index 0000000000..579492a39e --- /dev/null +++ b/engines/made/scriptfuncs_lgop2.cpp @@ -0,0 +1,467 @@ +/* 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/util.h" +#include "common/events.h" + +#include "graphics/cursorman.h" + +#include "made/made.h" +#include "made/resource.h" +#include "made/database.h" +#include "made/screen.h" +#include "made/script.h" +#include "made/pmvplayer.h" +#include "made/scriptfuncs.h" +#include "made/music.h" + +namespace Made { + +/* ScriptFunctionsLgop2 */ + +typedef Common::Functor2Mem<int16, int16*, int16, ScriptFunctionsLgop2> ExternalFuncLgop2; +#define External(x) ExternalFuncLgop2(this, &ScriptFunctionsLgop2::x) +void ScriptFunctionsLgop2::setupExternalsTable() { + static const ExternalFuncLgop2 externalsTable[] = { + External(o1_SYSTEM), + External(o1_INITGRAF), + External(o1_RESTOREGRAF), + External(o1_DRAWPIC), + External(o1_CLS), + External(o1_SHOWPAGE), + External(o1_EVENT), + External(o1_EVENTX), + External(o1_EVENTY), + External(o1_EVENTKEY), + External(o1_VISUALFX), + External(o1_PLAYSND), + External(o1_PLAYMUS), + External(o1_STOPMUS), + External(o1_ISMUS), + External(o1_TEXTPOS), + External(o1_FLASH), + External(o1_PLAYNOTE), + External(o1_STOPNOTE), + External(o1_PLAYTELE), + External(o1_STOPTELE), + External(o1_HIDECURS), + External(o1_SHOWCURS), + External(o1_MUSICBEAT), + External(o1_SCREENLOCK), + External(o1_ADDSPRITE), + External(o1_FREEANIM), + External(o1_DRAWSPRITE), + External(o1_ERASESPRITES), + External(o1_UPDATESPRITES), + External(o1_GETTIMER), + External(o1_SETTIMER), + External(o1_RESETTIMER), + External(o1_ALLOCTIMER), + External(o1_FREETIMER), + External(o1_PALETTELOCK), + External(o1_FONT), + External(o1_DRAWTEXT), + External(o1_HOMETEXT), + External(o1_TEXTRECT), + External(o1_TEXTXY), + External(o1_DROPSHADOW), + External(o1_TEXTCOLOR), + External(o1_OUTLINE), + External(o1_LOADCURSOR), + External(o1_SETGROUND), + External(o1_RESTEXT), + External(o1_ADDMASK), + External(o1_SETMASK), + External(o1_ISSND), + External(o1_STOPSND), + External(o1_PLAYVOICE) + }; + + for (int i = 0; i < ARRAYSIZE(externalsTable); ++i) + _externalFuncs.push_back(&externalsTable[i]); + +} +#undef External + +int16 ScriptFunctionsLgop2::o1_SYSTEM(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsLgop2::o1_INITGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsLgop2::o1_RESTOREGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsLgop2::o1_DRAWPIC(int16 argc, int16 *argv) { + return _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsLgop2::o1_CLS(int16 argc, int16 *argv) { + _vm->_screen->clearScreen(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_SHOWPAGE(int16 argc, int16 *argv) { + _vm->_screen->show(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_EVENT(int16 argc, int16 *argv) { + + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + int16 eventNum = 0; + + if (eventMan->pollEvent(event)) { + switch (event.type) { + + case Common::EVENT_MOUSEMOVE: + _vm->_eventMouseX = event.mouse.x; + _vm->_eventMouseY = event.mouse.y; + break; + + case Common::EVENT_LBUTTONDOWN: + eventNum = 1; + break; + + /* + case Common::EVENT_LBUTTONUP: + eventNum = 2; // TODO: Is this correct? + break; + */ + + case Common::EVENT_RBUTTONDOWN: + eventNum = 3; + break; + + /* + case Common::EVENT_RBUTTONUP: + eventNum = 4; // TODO: Is this correct? + break; + */ + + case Common::EVENT_KEYDOWN: + _vm->_eventKey = event.kbd.ascii; + eventNum = 5; + break; + + case Common::EVENT_QUIT: + // TODO: Exit more gracefully. + g_system->quit(); + break; + + default: + break; + + } + } + + _vm->_system->updateScreen(); + + return eventNum; +} + +int16 ScriptFunctionsLgop2::o1_EVENTX(int16 argc, int16 *argv) { + return _vm->_eventMouseX; +} + +int16 ScriptFunctionsLgop2::o1_EVENTY(int16 argc, int16 *argv) { + return _vm->_eventMouseY; +} + +int16 ScriptFunctionsLgop2::o1_EVENTKEY(int16 argc, int16 *argv) { + return _vm->_eventKey; +} + +int16 ScriptFunctionsLgop2::o1_VISUALFX(int16 argc, int16 *argv) { + _vm->_screen->setVisualEffectNum(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PLAYSND(int16 argc, int16 *argv) { + int soundNum = argv[0]; + bool loop = false; + + if (argc > 1) { + soundNum = argv[1]; + loop = (argv[0] == 1); + } + + if (soundNum > 0) { + if (!_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) { + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(soundNum)->getAudioStream(_vm->_soundRate, loop)); + } + } + + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PLAYMUS(int16 argc, int16 *argv) { + /* + + Disabled for now since MIDI player doesn't support all commands + which results in strange behavior. + + int16 musicNum = argv[0]; + if (musicNum > 0) { + GenericResource *midi = _vm->_res->getMidi(musicNum); + _vm->_music->playSMF(midi); + _vm->_res->freeResource(midi); + } + */ + return 0; +} + +int16 ScriptFunctionsLgop2::o1_STOPMUS(int16 argc, int16 *argv) { + _vm->_music->stop(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_ISMUS(int16 argc, int16 *argv) { + if (_vm->_music->isPlaying()) + return 1; + else + return 0; +} + +int16 ScriptFunctionsLgop2::o1_TEXTPOS(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_TEXTPOS"); + // This seems to be some kind of low-level opcode. + // The original engine calls int 10h to set the VGA cursor position. + return 0; +} + +int16 ScriptFunctionsLgop2::o1_FLASH(int16 argc, int16 *argv) { + _vm->_screen->flash(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PLAYNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYNOTE"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_STOPNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPNOTE"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PLAYTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYTELE"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_STOPTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPTELE"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_HIDECURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(false); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_SHOWCURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(true); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_MUSICBEAT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_MUSICBEAT"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_SCREENLOCK(int16 argc, int16 *argv) { + _vm->_screen->setScreenLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_ADDSPRITE(int16 argc, int16 *argv) { + //_vm->_screen->drawSprite(argv[2], argv[1], argv[0]); + return argv[2]; +} + +int16 ScriptFunctionsLgop2::o1_FREEANIM(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_DRAWSPRITE(int16 argc, int16 *argv) { + return _vm->_screen->drawSprite(argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsLgop2::o1_ERASESPRITES(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_UPDATESPRITES(int16 argc, int16 *argv) { + _vm->_screen->updateSprites(); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_GETTIMER(int16 argc, int16 *argv) { + return _vm->getTimer(argv[0]); +} + +int16 ScriptFunctionsLgop2::o1_SETTIMER(int16 argc, int16 *argv) { + _vm->setTimer(argv[1], argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_RESETTIMER(int16 argc, int16 *argv) { + _vm->resetTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_ALLOCTIMER(int16 argc, int16 *argv) { + int16 timerNum = _vm->allocTimer(); + return timerNum; +} + +int16 ScriptFunctionsLgop2::o1_FREETIMER(int16 argc, int16 *argv) { + _vm->freeTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PALETTELOCK(int16 argc, int16 *argv) { + _vm->_screen->setPaletteLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_FONT(int16 argc, int16 *argv) { + _vm->_screen->setFont(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_DRAWTEXT(int16 argc, int16 *argv) { + // TODO: Needs vsprintf to get the correct text + const char *text = _vm->_dat->getString(argv[argc - 1]); + _vm->_screen->printText(text); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_HOMETEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_HOMETEXT"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_TEXTRECT(int16 argc, int16 *argv) { + int16 x1 = CLIP<int16>(argv[4], 1, 318); + int16 y1 = CLIP<int16>(argv[3], 1, 198); + int16 x2 = CLIP<int16>(argv[2], 1, 318); + int16 y2 = CLIP<int16>(argv[1], 1, 198); + //int16 textValue = argv[0]; + // TODO: textValue + _vm->_screen->setTextRect(Common::Rect(x1, y1, x2, y2)); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_TEXTXY(int16 argc, int16 *argv) { + int16 x = CLIP<int16>(argv[1], 1, 318); + int16 y = CLIP<int16>(argv[0], 1, 198); + _vm->_screen->setTextXY(x, y); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_DROPSHADOW(int16 argc, int16 *argv) { + // if the drop shadow color is -1, then text drop shadow is disabled + // when font drop shadow is enabled, outline is disabled + _vm->_screen->setDropShadowColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_TEXTCOLOR(int16 argc, int16 *argv) { + _vm->_screen->setTextColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_OUTLINE(int16 argc, int16 *argv) { + // if the outline color is -1, then text outline is disabled + // when font outline is enabled, drop shadow is disabled + _vm->_screen->setOutlineColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_LOADCURSOR(int16 argc, int16 *argv) { + PictureResource *flex = _vm->_res->getPicture(argv[2]); + Graphics::Surface *surf = flex->getPicture(); + CursorMan.replaceCursor((const byte *)surf->pixels, surf->w, surf->h, argv[1], argv[0], 0); + CursorMan.showMouse(true); + _vm->_res->freeResource(flex); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_SETGROUND(int16 argc, int16 *argv) { + _vm->_screen->setGround(argv[0]); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_RESTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_RESTEXT"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_ADDMASK(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_ADDMASK"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_SETMASK(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SETMASK"); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_ISSND(int16 argc, int16 *argv) { + if (_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) + return 1; + else + return 0; +} + +int16 ScriptFunctionsLgop2::o1_STOPSND(int16 argc, int16 *argv) { + _vm->_mixer->stopHandle(_audioStreamHandle); + return 0; +} + +int16 ScriptFunctionsLgop2::o1_PLAYVOICE(int16 argc, int16 *argv) { + if (argv[0] > 0) { + _vm->_mixer->stopHandle(_audioStreamHandle); + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(argv[0])->getAudioStream(_vm->_soundRate, false)); + } + return 0; +} + +} // End of namespace Made diff --git a/engines/made/scriptfuncs_mhne.cpp b/engines/made/scriptfuncs_mhne.cpp new file mode 100644 index 0000000000..65e9c6e070 --- /dev/null +++ b/engines/made/scriptfuncs_mhne.cpp @@ -0,0 +1,494 @@ +/* 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/util.h" +#include "common/events.h" + +#include "graphics/cursorman.h" + +#include "made/made.h" +#include "made/resource.h" +#include "made/database.h" +#include "made/screen.h" +#include "made/script.h" +#include "made/pmvplayer.h" +#include "made/scriptfuncs.h" +#include "made/music.h" + +namespace Made { + +/* ScriptFunctionsMhne */ + +typedef Common::Functor2Mem<int16, int16*, int16, ScriptFunctionsMhne> ExternalFuncMhne; +#define External(x) ExternalFuncMhne(this, &ScriptFunctionsMhne::x) +void ScriptFunctionsMhne::setupExternalsTable() { + static const ExternalFuncMhne externalsTable[] = { + External(o1_SYSTEM), + External(o1_INITGRAF), + External(o1_RESTOREGRAF), + External(o1_DRAWPIC), + External(o1_CLS), + External(o1_SHOWPAGE), + External(o1_EVENT), + External(o1_EVENTX), + External(o1_EVENTY), + External(o1_EVENTKEY), + External(o1_VISUALFX), + External(o1_PLAYSND), + External(o1_PLAYMUS), + External(o1_STOPMUS), + External(o1_ISMUS), + External(o1_TEXTPOS), + External(o1_FLASH), + External(o1_PLAYNOTE), + External(o1_STOPNOTE), + External(o1_PLAYTELE), + External(o1_STOPTELE), + External(o1_HIDECURS), + External(o1_SHOWCURS), + External(o1_MUSICBEAT), + External(o1_SCREENLOCK), + External(o1_ADDSPRITE), + External(o1_FREEANIM), + External(o1_DRAWSPRITE), + External(o1_ERASESPRITES), + External(o1_UPDATESPRITES), + External(o1_GETTIMER), + External(o1_SETTIMER), + External(o1_RESETTIMER), + External(o1_ALLOCTIMER), + External(o1_FREETIMER), + External(o1_PALETTELOCK), + External(o1_FONT), + External(o1_DRAWTEXT), + External(o1_HOMETEXT), + External(o1_TEXTRECT), + External(o1_TEXTXY), + External(o1_DROPSHADOW), + External(o1_TEXTCOLOR), + External(o1_OUTLINE), + External(o1_LOADCURSOR), + External(o1_SETGROUND), + External(o1_RESTEXT), + External(o1_ADDMASK), + External(o1_SETMASK), + External(o1_ISSND), + External(o1_STOPSND), + External(o1_PLAYVOICE), + External(o1_CDPLAY), + External(o1_STOPCD), + External(o1_CDSTATUS), + External(o1_CDTIME), + External(o1_CDPLAYSEG), + }; + + for (int i = 0; i < ARRAYSIZE(externalsTable); ++i) + _externalFuncs.push_back(&externalsTable[i]); + +} +#undef External + +int16 ScriptFunctionsMhne::o1_SYSTEM(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsMhne::o1_INITGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsMhne::o1_RESTOREGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsMhne::o1_DRAWPIC(int16 argc, int16 *argv) { + return _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsMhne::o1_CLS(int16 argc, int16 *argv) { + _vm->_screen->clearScreen(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_SHOWPAGE(int16 argc, int16 *argv) { + _vm->_screen->show(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_EVENT(int16 argc, int16 *argv) { + + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + int16 eventNum = 0; + + if (eventMan->pollEvent(event)) { + switch (event.type) { + + case Common::EVENT_MOUSEMOVE: + _vm->_eventMouseX = event.mouse.x; + _vm->_eventMouseY = event.mouse.y; + break; + + case Common::EVENT_LBUTTONDOWN: + eventNum = 1; + break; + + /* + case Common::EVENT_LBUTTONUP: + eventNum = 2; // TODO: Is this correct? + break; + */ + + case Common::EVENT_RBUTTONDOWN: + eventNum = 3; + break; + + /* + case Common::EVENT_RBUTTONUP: + eventNum = 4; // TODO: Is this correct? + break; + */ + + case Common::EVENT_KEYDOWN: + _vm->_eventKey = event.kbd.ascii; + eventNum = 5; + break; + + case Common::EVENT_QUIT: + // TODO: Exit more gracefully. + g_system->quit(); + break; + + default: + break; + + } + } + + _vm->_system->updateScreen(); + + return eventNum; +} + +int16 ScriptFunctionsMhne::o1_EVENTX(int16 argc, int16 *argv) { + return _vm->_eventMouseX; +} + +int16 ScriptFunctionsMhne::o1_EVENTY(int16 argc, int16 *argv) { + return _vm->_eventMouseY; +} + +int16 ScriptFunctionsMhne::o1_EVENTKEY(int16 argc, int16 *argv) { + return _vm->_eventKey; +} + +int16 ScriptFunctionsMhne::o1_VISUALFX(int16 argc, int16 *argv) { + _vm->_screen->setVisualEffectNum(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_PLAYSND(int16 argc, int16 *argv) { + int soundNum = argv[0]; + bool loop = false; + + if (argc > 1) { + soundNum = argv[1]; + loop = (argv[0] == 1); + } + + if (soundNum > 0) { + if (!_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) { + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(soundNum)->getAudioStream(_vm->_soundRate, loop)); + } + } + + return 0; +} + +int16 ScriptFunctionsMhne::o1_PLAYMUS(int16 argc, int16 *argv) { + int16 musicNum = argv[0]; + if (musicNum > 0) { + GenericResource *xmidi = _vm->_res->getXmidi(musicNum); + _vm->_music->playXMIDI(xmidi); + _vm->_res->freeResource(xmidi); + } + return 0; +} + +int16 ScriptFunctionsMhne::o1_STOPMUS(int16 argc, int16 *argv) { + _vm->_music->stop(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_ISMUS(int16 argc, int16 *argv) { + if (_vm->_music->isPlaying()) + return 1; + else + return 0; +} + +int16 ScriptFunctionsMhne::o1_TEXTPOS(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_TEXTPOS"); + // This seems to be some kind of low-level opcode. + // The original engine calls int 10h to set the VGA cursor position. + return 0; +} + +int16 ScriptFunctionsMhne::o1_FLASH(int16 argc, int16 *argv) { + _vm->_screen->flash(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_PLAYNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYNOTE"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_STOPNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPNOTE"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_PLAYTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYTELE"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_STOPTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPTELE"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_HIDECURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(false); + return 0; +} + +int16 ScriptFunctionsMhne::o1_SHOWCURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(true); + return 0; +} + +int16 ScriptFunctionsMhne::o1_MUSICBEAT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_MUSICBEAT"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_SCREENLOCK(int16 argc, int16 *argv) { + _vm->_screen->setScreenLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsMhne::o1_ADDSPRITE(int16 argc, int16 *argv) { + //_vm->_screen->drawSprite(argv[2], argv[1], argv[0]); + return argv[2]; +} + +int16 ScriptFunctionsMhne::o1_FREEANIM(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_DRAWSPRITE(int16 argc, int16 *argv) { + return _vm->_screen->drawSprite(argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsMhne::o1_ERASESPRITES(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_UPDATESPRITES(int16 argc, int16 *argv) { + _vm->_screen->updateSprites(); + return 0; +} + +int16 ScriptFunctionsMhne::o1_GETTIMER(int16 argc, int16 *argv) { + return _vm->getTimer(argv[0]); +} + +int16 ScriptFunctionsMhne::o1_SETTIMER(int16 argc, int16 *argv) { + _vm->setTimer(argv[1], argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_RESETTIMER(int16 argc, int16 *argv) { + _vm->resetTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_ALLOCTIMER(int16 argc, int16 *argv) { + int16 timerNum = _vm->allocTimer(); + return timerNum; +} + +int16 ScriptFunctionsMhne::o1_FREETIMER(int16 argc, int16 *argv) { + _vm->freeTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_PALETTELOCK(int16 argc, int16 *argv) { + _vm->_screen->setPaletteLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsMhne::o1_FONT(int16 argc, int16 *argv) { + _vm->_screen->setFont(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_DRAWTEXT(int16 argc, int16 *argv) { + Object *obj = _vm->_dat->getObject(argv[argc - 1]); + const char *text = obj->getString(); + _vm->_screen->printText(text); + return 0; +} + +int16 ScriptFunctionsMhne::o1_HOMETEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_HOMETEXT"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_TEXTRECT(int16 argc, int16 *argv) { + int16 x1 = CLIP<int16>(argv[4], 1, 318); + int16 y1 = CLIP<int16>(argv[3], 1, 198); + int16 x2 = CLIP<int16>(argv[2], 1, 318); + int16 y2 = CLIP<int16>(argv[1], 1, 198); + //int16 textValue = argv[0]; + // TODO: textValue + _vm->_screen->setTextRect(Common::Rect(x1, y1, x2, y2)); + return 0; +} + +int16 ScriptFunctionsMhne::o1_TEXTXY(int16 argc, int16 *argv) { + int16 x = CLIP<int16>(argv[1], 1, 318); + int16 y = CLIP<int16>(argv[0], 1, 198); + _vm->_screen->setTextXY(x, y); + return 0; +} + +int16 ScriptFunctionsMhne::o1_DROPSHADOW(int16 argc, int16 *argv) { + // if the drop shadow color is -1, then text drop shadow is disabled + // when font drop shadow is enabled, outline is disabled + _vm->_screen->setDropShadowColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_TEXTCOLOR(int16 argc, int16 *argv) { + _vm->_screen->setTextColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_OUTLINE(int16 argc, int16 *argv) { + // if the outline color is -1, then text outline is disabled + // when font outline is enabled, drop shadow is disabled + _vm->_screen->setOutlineColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_LOADCURSOR(int16 argc, int16 *argv) { + PictureResource *flex = _vm->_res->getPicture(argv[2]); + Graphics::Surface *surf = flex->getPicture(); + CursorMan.replaceCursor((const byte *)surf->pixels, surf->w, surf->h, argv[1], argv[0], 0); + CursorMan.showMouse(true); + _vm->_res->freeResource(flex); + return 0; +} + +int16 ScriptFunctionsMhne::o1_SETGROUND(int16 argc, int16 *argv) { + _vm->_screen->setGround(argv[0]); + return 0; +} + +int16 ScriptFunctionsMhne::o1_RESTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_RESTEXT"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_ADDMASK(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_ADDMASK"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_SETMASK(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SETMASK"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_ISSND(int16 argc, int16 *argv) { + if (_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) + return 1; + else + return 0; +} + +int16 ScriptFunctionsMhne::o1_STOPSND(int16 argc, int16 *argv) { + _vm->_mixer->stopHandle(_audioStreamHandle); + return 0; +} + +int16 ScriptFunctionsMhne::o1_PLAYVOICE(int16 argc, int16 *argv) { + if (argv[0] > 0) { + _vm->_mixer->stopHandle(_audioStreamHandle); + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(argv[0])->getAudioStream(_vm->_soundRate, false)); + } + return 0; +} + +int16 ScriptFunctionsMhne::o1_CDPLAY(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDPLAY"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_STOPCD(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPCD"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_CDSTATUS(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDSTATUS"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_CDTIME(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDTIME"); + return 0; +} + +int16 ScriptFunctionsMhne::o1_CDPLAYSEG(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_CDPLAYSEG"); + return 0; +} + +} // End of namespace Made diff --git a/engines/made/scriptfuncs_rtz.cpp b/engines/made/scriptfuncs_rtz.cpp new file mode 100644 index 0000000000..1186a88de8 --- /dev/null +++ b/engines/made/scriptfuncs_rtz.cpp @@ -0,0 +1,864 @@ +/* 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/util.h" +#include "common/events.h" + +#include "graphics/cursorman.h" + +#include "made/made.h" +#include "made/resource.h" +#include "made/database.h" +#include "made/screen.h" +#include "made/script.h" +#include "made/pmvplayer.h" +#include "made/scriptfuncs.h" +#include "made/music.h" + +namespace Made { + +/* ScriptFunctionsRtz */ + +typedef Common::Functor2Mem<int16, int16*, int16, ScriptFunctionsRtz> ExternalFuncRtz; +#define External(x) ExternalFuncRtz(this, &ScriptFunctionsRtz::x) +void ScriptFunctionsRtz::setupExternalsTable() { + static const ExternalFuncRtz externalsTable[] = { + External(o1_SYSTEM), + External(o1_INITGRAF), + External(o1_RESTOREGRAF), + External(o1_DRAWPIC), + External(o1_CLS), + External(o1_SHOWPAGE), + External(o1_EVENT), + External(o1_EVENTX), + External(o1_EVENTY), + External(o1_EVENTKEY), + External(o1_VISUALFX), + External(o1_PLAYSND), + External(o1_PLAYMUS), + External(o1_STOPMUS), + External(o1_ISMUS), + External(o1_TEXTPOS), + External(o1_FLASH), + External(o1_PLAYNOTE), + External(o1_STOPNOTE), + External(o1_PLAYTELE), + External(o1_STOPTELE), + External(o1_HIDECURS), + External(o1_SHOWCURS), + External(o1_MUSICBEAT), + External(o1_SCREENLOCK), + External(o1_ADDSPRITE), + External(o1_FREEANIM), + External(o1_DRAWSPRITE), + External(o1_ERASESPRITES), + External(o1_UPDATESPRITES), + External(o1_GETTIMER), + External(o1_SETTIMER), + External(o1_RESETTIMER), + External(o1_ALLOCTIMER), + External(o1_FREETIMER), + External(o1_PALETTELOCK), + External(o1_FONT), + External(o1_DRAWTEXT), + External(o1_HOMETEXT), + External(o1_TEXTRECT), + External(o1_TEXTXY), + External(o1_DROPSHADOW), + External(o1_TEXTCOLOR), + External(o1_OUTLINE), + External(o1_LOADCURSOR), + External(o1_SETGROUND), + External(o1_RESTEXT), + External(o1_CLIPAREA), + External(o1_SETCLIP), + External(o1_ISSND), + External(o1_STOPSND), + External(o1_PLAYVOICE), + External(o1_CDPLAY), + External(o1_STOPCD), + External(o1_CDSTATUS), + External(o1_CDTIME), + External(o1_CDPLAYSEG), + External(o1_PRINTF), + External(o1_MONOCLS), + External(o1_SNDENERGY), + External(o1_CLEARTEXT), + External(o1_ANIMTEXT), + External(o1_TEXTWIDTH), + External(o1_PLAYMOVIE), + External(o1_LOADSND), + External(o1_LOADMUS), + External(o1_LOADPIC), + External(o1_MUSICVOL), + External(o1_RESTARTEVENTS), + External(o1_PLACESPRITE), + External(o1_PLACETEXT), + External(o1_DELETECHANNEL), + External(o1_CHANNELTYPE), + External(o1_SETSTATE), + External(o1_SETLOCATION), + External(o1_SETCONTENT), + External(o1_EXCLUDEAREA), + External(o1_SETEXCLUDE), + External(o1_GETSTATE), + External(o1_PLACEANIM), + External(o1_SETFRAME), + External(o1_GETFRAME), + External(o1_GETFRAMECOUNT), + External(o1_PICWIDTH), + External(o1_PICHEIGHT), + External(o1_SOUNDRATE), + External(o1_DRAWANIMPIC), + External(o1_LOADANIM), + External(o1_READTEXT), + External(o1_READMENU), + External(o1_DRAWMENU), + External(o1_MENUCOUNT), + External(o1_SAVEGAME), + External(o1_LOADGAME), + External(o1_GAMENAME), + External(o1_SHAKESCREEN), + External(o1_PLACEMENU), + External(o1_SETVOLUME), + External(o1_WHATSYNTH), + External(o1_SLOWSYSTEM) + }; + + for (int i = 0; i < ARRAYSIZE(externalsTable); ++i) + _externalFuncs.push_back(&externalsTable[i]); + +} +#undef External + +int16 ScriptFunctionsRtz::o1_SYSTEM(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsRtz::o1_INITGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsRtz::o1_RESTOREGRAF(int16 argc, int16 *argv) { + // This opcode is empty. + return 0; +} + +int16 ScriptFunctionsRtz::o1_DRAWPIC(int16 argc, int16 *argv) { + return _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsRtz::o1_CLS(int16 argc, int16 *argv) { + _vm->_screen->clearScreen(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SHOWPAGE(int16 argc, int16 *argv) { + _vm->_screen->show(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_EVENT(int16 argc, int16 *argv) { + + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + int16 eventNum = 0; + + if (eventMan->pollEvent(event)) { + switch (event.type) { + + case Common::EVENT_MOUSEMOVE: + _vm->_eventMouseX = event.mouse.x; + _vm->_eventMouseY = event.mouse.y; + break; + + case Common::EVENT_LBUTTONDOWN: + eventNum = 1; + break; + + /* + case Common::EVENT_LBUTTONUP: + eventNum = 2; // TODO: Is this correct? + break; + */ + + case Common::EVENT_RBUTTONDOWN: + eventNum = 3; + break; + + /* + case Common::EVENT_RBUTTONUP: + eventNum = 4; // TODO: Is this correct? + break; + */ + + case Common::EVENT_KEYDOWN: + _vm->_eventKey = event.kbd.ascii; + eventNum = 5; + break; + + case Common::EVENT_QUIT: + // TODO: Exit more gracefully. + g_system->quit(); + break; + + default: + break; + + } + } + + _vm->_system->updateScreen(); + + return eventNum; +} + +int16 ScriptFunctionsRtz::o1_EVENTX(int16 argc, int16 *argv) { + return _vm->_eventMouseX; +} + +int16 ScriptFunctionsRtz::o1_EVENTY(int16 argc, int16 *argv) { + return _vm->_eventMouseY; +} + +int16 ScriptFunctionsRtz::o1_EVENTKEY(int16 argc, int16 *argv) { + return _vm->_eventKey; +} + +int16 ScriptFunctionsRtz::o1_VISUALFX(int16 argc, int16 *argv) { + _vm->_screen->setVisualEffectNum(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLAYSND(int16 argc, int16 *argv) { + int soundNum = argv[0]; + bool loop = false; + + if (argc > 1) { + soundNum = argv[1]; + loop = (argv[0] == 1); + } + + if (soundNum > 0) { + if (!_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) { + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(soundNum)->getAudioStream(_vm->_soundRate, loop)); + } + } + + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) { + int16 musicNum = argv[0]; + if (musicNum > 0) { + GenericResource *xmidi = _vm->_res->getXmidi(musicNum); + _vm->_music->playXMIDI(xmidi); + _vm->_res->freeResource(xmidi); + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_STOPMUS(int16 argc, int16 *argv) { + _vm->_music->stop(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_ISMUS(int16 argc, int16 *argv) { + if (_vm->_music->isPlaying()) + return 1; + else + return 0; +} + +int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_TEXTPOS"); + // This seems to be some kind of low-level opcode. + // The original engine calls int 10h to set the VGA cursor position. + return 0; +} + +int16 ScriptFunctionsRtz::o1_FLASH(int16 argc, int16 *argv) { + _vm->_screen->flash(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLAYNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYNOTE"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_STOPNOTE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPNOTE"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLAYTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLAYTELE"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_STOPTELE(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPTELE"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_HIDECURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(false); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SHOWCURS(int16 argc, int16 *argv) { + _vm->_system->showMouse(true); + return 0; +} + +int16 ScriptFunctionsRtz::o1_MUSICBEAT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_MUSICBEAT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SCREENLOCK(int16 argc, int16 *argv) { + _vm->_screen->setScreenLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsRtz::o1_ADDSPRITE(int16 argc, int16 *argv) { + //_vm->_screen->drawSprite(argv[2], argv[1], argv[0]); + return 0;//argv[2]; +} + +int16 ScriptFunctionsRtz::o1_FREEANIM(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_DRAWSPRITE(int16 argc, int16 *argv) { + return _vm->_screen->drawSprite(argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsRtz::o1_ERASESPRITES(int16 argc, int16 *argv) { + _vm->_screen->clearChannels(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_UPDATESPRITES(int16 argc, int16 *argv) { + _vm->_screen->updateSprites(); + return 0; +} + +int16 ScriptFunctionsRtz::o1_GETTIMER(int16 argc, int16 *argv) { + return _vm->getTimer(argv[0]); +} + +int16 ScriptFunctionsRtz::o1_SETTIMER(int16 argc, int16 *argv) { + _vm->setTimer(argv[1], argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_RESETTIMER(int16 argc, int16 *argv) { + _vm->resetTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_ALLOCTIMER(int16 argc, int16 *argv) { + int16 timerNum = _vm->allocTimer(); + return timerNum; +} + +int16 ScriptFunctionsRtz::o1_FREETIMER(int16 argc, int16 *argv) { + _vm->freeTimer(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PALETTELOCK(int16 argc, int16 *argv) { + _vm->_screen->setPaletteLock(argv[0] != 0); + return 0; +} + +int16 ScriptFunctionsRtz::o1_FONT(int16 argc, int16 *argv) { + _vm->_screen->setFont(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_DRAWTEXT(int16 argc, int16 *argv) { + // TODO: Needs vsprintf to get the correct text + Object *obj = _vm->_dat->getObject(argv[argc - 1]); + const char *text = obj->getString(); + _vm->_screen->printText(text); + return 0; +} + +int16 ScriptFunctionsRtz::o1_HOMETEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_HOMETEXT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_TEXTRECT(int16 argc, int16 *argv) { + int16 x1 = CLIP<int16>(argv[4], 1, 318); + int16 y1 = CLIP<int16>(argv[3], 1, 198); + int16 x2 = CLIP<int16>(argv[2], 1, 318); + int16 y2 = CLIP<int16>(argv[1], 1, 198); + //int16 textValue = argv[0]; + // TODO: textValue + _vm->_screen->setTextRect(Common::Rect(x1, y1, x2, y2)); + return 0; +} + +int16 ScriptFunctionsRtz::o1_TEXTXY(int16 argc, int16 *argv) { + int16 x = CLIP<int16>(argv[1], 1, 318); + int16 y = CLIP<int16>(argv[0], 1, 198); + _vm->_screen->setTextXY(x, y); + return 0; +} + +int16 ScriptFunctionsRtz::o1_DROPSHADOW(int16 argc, int16 *argv) { + // if the drop shadow color is -1, then text drop shadow is disabled + // when font drop shadow is enabled, outline is disabled + _vm->_screen->setDropShadowColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_TEXTCOLOR(int16 argc, int16 *argv) { + _vm->_screen->setTextColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_OUTLINE(int16 argc, int16 *argv) { + // if the outline color is -1, then text outline is disabled + // when font outline is enabled, drop shadow is disabled + _vm->_screen->setOutlineColor(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_LOADCURSOR(int16 argc, int16 *argv) { + PictureResource *flex = _vm->_res->getPicture(argv[2]); + Graphics::Surface *surf = flex->getPicture(); + CursorMan.replaceCursor((const byte *)surf->pixels, surf->w, surf->h, argv[1], argv[0], 0); + CursorMan.showMouse(true); + _vm->_res->freeResource(flex); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETGROUND(int16 argc, int16 *argv) { + _vm->_screen->setGround(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_RESTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_RESTEXT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CLIPAREA(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_CLIPAREA"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETCLIP(int16 argc, int16 *argv) { + _vm->_screen->setClip(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_ISSND(int16 argc, int16 *argv) { + if (_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) + return 1; + else + return 0; +} + +int16 ScriptFunctionsRtz::o1_STOPSND(int16 argc, int16 *argv) { + _vm->_mixer->stopHandle(_audioStreamHandle); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLAYVOICE(int16 argc, int16 *argv) { + if (argv[0] > 0) { + _vm->_mixer->stopHandle(_audioStreamHandle); + _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, + _vm->_res->getSound(argv[0])->getAudioStream(_vm->_soundRate, false)); + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_CDPLAY(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDPLAY"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_STOPCD(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_STOPCD"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CDSTATUS(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDSTATUS"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CDTIME(int16 argc, int16 *argv) { + // This one is called loads of times, so it has been commented out to reduce spam + //warning("Unimplemented opcode: o1_CDTIME"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CDPLAYSEG(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_CDPLAYSEG"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PRINTF(int16 argc, int16 *argv) { + Object *obj = _vm->_dat->getObject(argv[argc - 1]); + const char *text = obj->getString(); + debug(4, "--> text = %s", text); + return 0; +} + +int16 ScriptFunctionsRtz::o1_MONOCLS(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_MONOCLS"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SNDENERGY(int16 argc, int16 *argv) { + // This is called while in-game voices are played + // Not sure what it's used for + // -> It's used to animate mouths when NPCs are talking + // Commented out to reduce spam + //warning("Unimplemented opcode: o1_SNDENERGY"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CLEARTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_CLEARTEXT"); + return 1; +} + +int16 ScriptFunctionsRtz::o1_ANIMTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_ANIMTEXT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_TEXTWIDTH(int16 argc, int16 *argv) { + int16 width = 0; + if (argv[1] > 0) { + Object *obj = _vm->_dat->getObject(argv[1]); + const char *text = obj->getString(); + width = _vm->_screen->getTextWidth(argv[0], text); + } + return width; +} + +int16 ScriptFunctionsRtz::o1_PLAYMOVIE(int16 argc, int16 *argv) { + const char *movieName = _vm->_dat->getObject(argv[1])->getString(); + _vm->_pmvPlayer->play(movieName); + return 0; +} + +int16 ScriptFunctionsRtz::o1_LOADSND(int16 argc, int16 *argv) { + SoundResource *sound = _vm->_res->getSound(argv[0]); + if (sound) { + _vm->_res->freeResource(sound); + return 1; + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_LOADMUS(int16 argc, int16 *argv) { + GenericResource *xmidi = _vm->_res->getXmidi(argv[0]); + if (xmidi) { + _vm->_res->freeResource(xmidi); + return 1; + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_LOADPIC(int16 argc, int16 *argv) { + PictureResource *flex = _vm->_res->getPicture(argv[0]); + if (flex) { + _vm->_res->freeResource(flex); + return 1; + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_MUSICVOL(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_MUSICVOL"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_RESTARTEVENTS(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_RESTARTEVENTS"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLACESPRITE(int16 argc, int16 *argv) { + return _vm->_screen->placeSprite(argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsRtz::o1_PLACETEXT(int16 argc, int16 *argv) { + return _vm->_screen->placeText(argv[6], argv[5], argv[4], argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsRtz::o1_DELETECHANNEL(int16 argc, int16 *argv) { + _vm->_screen->deleteChannel(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_CHANNELTYPE(int16 argc, int16 *argv) { + return _vm->_screen->getChannelType(argv[0]); +} + +int16 ScriptFunctionsRtz::o1_SETSTATE(int16 argc, int16 *argv) { + _vm->_screen->setChannelState(argv[1], argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETLOCATION(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SETLOCATION"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETCONTENT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SETCONTENT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_EXCLUDEAREA(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_EXCLUDEAREA"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETEXCLUDE(int16 argc, int16 *argv) { + _vm->_screen->setExclude(argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_GETSTATE(int16 argc, int16 *argv) { + return _vm->_screen->getChannelState(argv[0]); +} + +int16 ScriptFunctionsRtz::o1_PLACEANIM(int16 argc, int16 *argv) { + return _vm->_screen->placeAnim(argv[4], argv[3], argv[2], argv[1], argv[0]); +} + +int16 ScriptFunctionsRtz::o1_SETFRAME(int16 argc, int16 *argv) { + _vm->_screen->setAnimFrame(argv[1], argv[0]); + return 0; +} + +int16 ScriptFunctionsRtz::o1_GETFRAME(int16 argc, int16 *argv) { + return _vm->_screen->getAnimFrame(argv[0]); +} + +int16 ScriptFunctionsRtz::o1_GETFRAMECOUNT(int16 argc, int16 *argv) { + return _vm->_screen->getAnimFrameCount(argv[0]); +} + +int16 ScriptFunctionsRtz::o1_PICWIDTH(int16 argc, int16 *argv) { + int16 width = 0; + PictureResource *flex = _vm->_res->getPicture(argv[0]); + if (flex) { + width = flex->getPicture()->w; + _vm->_res->freeResource(flex); + } + return width; +} + +int16 ScriptFunctionsRtz::o1_PICHEIGHT(int16 argc, int16 *argv) { + int16 height = 0; + PictureResource *flex = _vm->_res->getPicture(argv[0]); + if (flex) { + height = flex->getPicture()->h; + _vm->_res->freeResource(flex); + } + return height; +} + +int16 ScriptFunctionsRtz::o1_SOUNDRATE(int16 argc, int16 *argv) { + _vm->_soundRate = argv[0]; + return 1; +} + +int16 ScriptFunctionsRtz::o1_DRAWANIMPIC(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_DRAWANIMPIC"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_LOADANIM(int16 argc, int16 *argv) { + AnimationResource *anim = _vm->_res->getAnimation(argv[0]); + if (anim) { + _vm->_res->freeResource(anim); + return 1; + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_READTEXT(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_READTEXT"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_READMENU(int16 argc, int16 *argv) { + int16 objectIndex = argv[2]; + int16 menuIndex = argv[1]; + int16 textIndex = argv[0]; + int16 length = 0; + MenuResource *menu = _vm->_res->getMenu(menuIndex); + if (menu) { + const char *text = menu->getString(textIndex); + debug(4, "objectIndex = %04X; text = %s\n", objectIndex, text); + Object *obj = _vm->_dat->getObject(objectIndex); + obj->setString(text); + _vm->_res->freeResource(menu); + if (text) + length = strlen(text); + } + return length; +} + +int16 ScriptFunctionsRtz::o1_DRAWMENU(int16 argc, int16 *argv) { + int16 menuIndex = argv[1]; + int16 textIndex = argv[0]; + MenuResource *menu = _vm->_res->getMenu(menuIndex); + if (menu) { + const char *text = menu->getString(textIndex); + if (text) + _vm->_screen->printText(text); + _vm->_res->freeResource(menu); + } + return 0; +} + +int16 ScriptFunctionsRtz::o1_MENUCOUNT(int16 argc, int16 *argv) { + int16 menuIndex = argv[0]; + int16 count = 0; + MenuResource *menu = _vm->_res->getMenu(menuIndex); + if (menu) { + count = menu->getCount(); + _vm->_res->freeResource(menu); + } + return count; +} + +int16 ScriptFunctionsRtz::o1_SAVEGAME(int16 argc, int16 *argv) { + + int16 saveNum = argv[2]; + int16 descObjectIndex = argv[1]; + int16 version = argv[0]; + + if (saveNum > 999) + return 6; + + Object *obj = _vm->_dat->getObject(descObjectIndex); + const char *description = obj->getString(); + + // TODO: Use better filename + char filename[256]; + snprintf(filename, 256, "rtz.%03d", saveNum); + + return _vm->_dat->savegame(filename, description, version); + +} + +int16 ScriptFunctionsRtz::o1_LOADGAME(int16 argc, int16 *argv) { + + int16 saveNum = argv[1]; + int16 version = argv[0]; + + if (saveNum > 999) + return 1; + + // TODO: Use better filename + char filename[256]; + snprintf(filename, 256, "rtz.%03d", saveNum); + + return _vm->_dat->loadgame(filename, version); + +} + +int16 ScriptFunctionsRtz::o1_GAMENAME(int16 argc, int16 *argv) { + + int16 descObjectIndex = argv[2]; + int16 saveNum = argv[1]; + /*int16 version = argv[0];*/ + Common::String description; + + if (saveNum > 999) + return 1; + + // TODO: Use better filename + char filename[256]; + snprintf(filename, 256, "rtz.%03d", saveNum); + + Object *obj = _vm->_dat->getObject(descObjectIndex); + + if (_vm->_dat->getSavegameDescription(filename, description)) { + obj->setString(description.c_str()); + return 0; + } else { + obj->setString(""); + return 1; + } + +} + +int16 ScriptFunctionsRtz::o1_SHAKESCREEN(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SHAKESCREEN"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_PLACEMENU(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_PLACEMENU"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SETVOLUME(int16 argc, int16 *argv) { + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, argv[0] * 25); + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, argv[0] * 25); + return 0; +} + +int16 ScriptFunctionsRtz::o1_WHATSYNTH(int16 argc, int16 *argv) { + // 0 = Default + // 1 = PCSPKR + // 2 = SBFM/ADLIB + // 3 = ADLIBG + // 4 = MT32MPU + warning("Unimplemented opcode: o1_WHATSYNTH"); + return 0; +} + +int16 ScriptFunctionsRtz::o1_SLOWSYSTEM(int16 argc, int16 *argv) { + warning("Unimplemented opcode: o1_SLOWSYSTEM"); + return 0; +} + +} // End of namespace Made |