From c836646b69a685ff59818a130bd98555d481d010 Mon Sep 17 00:00:00 2001 From: Eric Fry Date: Mon, 18 Nov 2019 20:31:17 +1100 Subject: [PATCH] DRAGONS: added ScriptOpCode constructor. Work on eyes bg layer in mini game 3 --- engines/dragons/cursor.cpp | 8 ++--- engines/dragons/dragons.cpp | 54 ++++++++++++++----------------- engines/dragons/minigame3.cpp | 11 ++++--- engines/dragons/scene.cpp | 34 ++++++++++--------- engines/dragons/scriptopcodes.cpp | 23 ++++++------- engines/dragons/scriptopcodes.h | 2 ++ engines/dragons/talk.cpp | 4 +-- 7 files changed, 64 insertions(+), 72 deletions(-) diff --git a/engines/dragons/cursor.cpp b/engines/dragons/cursor.cpp index db9f5ad716d..09d86292b71 100644 --- a/engines/dragons/cursor.cpp +++ b/engines/dragons/cursor.cpp @@ -247,9 +247,7 @@ int16 Cursor::updateIniFromScene() { for(int idx=0; idx < 5; idx++) { data_800728b0_cursor_seqID = idx; byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 8; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd)); // uVar17 = uVar15; // local_58 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8; @@ -276,9 +274,7 @@ int16 Cursor::updateIniFromScene() { return _iniUnderCursor; } byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 8; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd)); // local_48 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8; // local_44 = read_int32(); diff --git a/engines/dragons/dragons.cpp b/engines/dragons/dragons.cpp index 91547b4fa01..a24573eb3c3 100644 --- a/engines/dragons/dragons.cpp +++ b/engines/dragons/dragons.cpp @@ -263,7 +263,6 @@ void DragonsEngine::gameLoop() uint16_t sequenceId; DragonINI *pDVar8; ushort *puVar9; - ScriptOpCall local_30; _cursor->_cursorActivationSeqOffset = 0; bit_flags_8006fbd8 = 0; @@ -314,9 +313,7 @@ void DragonsEngine::gameLoop() if (actorId_00 == 0) goto LAB_80026d34; if (actorId_00 != (actorId & 0xffff)) { byte *obd = _dragonOBD->getFromOpt(actorId_00 - 1); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 8; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd)); if(_scriptOpcodes->runScript4(scriptOpCall)) { scriptOpCall._codeEnd = scriptOpCall._code + 4 + READ_LE_UINT16(scriptOpCall._code + 2); @@ -832,9 +829,7 @@ void DragonsEngine::runINIScripts() { if (ini->field_1a_flags_maybe & Dragons::INI_FLAG_10) { ini->field_1a_flags_maybe &= ~Dragons::INI_FLAG_10; byte *data = _dragonOBD->getFromOpt(i); - ScriptOpCall scriptOpCall; - scriptOpCall._code = data + 8; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(data); + ScriptOpCall scriptOpCall(data + 8, READ_LE_UINT32(data)); uint32 currentFlags = _flags; clearFlags(Dragons::ENGINE_FLAG_8); _scriptOpcodes->runScript3(scriptOpCall); @@ -1034,17 +1029,16 @@ void DragonsEngine::performAction() { uint uVar4; uint uVar5; uint uVar6; - ScriptOpCall local_48; - ScriptOpCall local_38; - ScriptOpCall local_58; byte * pvVar7; byte * pvVar8; + byte *local_58_code; + byte *local_58_codeEnd; + bool load_58_result = false; uVar2 = _scriptOpcodes->_scriptTargetINI; uVar1 = _flags; - local_58._code = NULL; - local_58._codeEnd = NULL; - local_58._result = 0; + local_58_code = NULL; + local_58_codeEnd = NULL; uVar6 = 0; _scriptOpcodes->_data_80071f5c = 0; @@ -1053,8 +1047,9 @@ void DragonsEngine::performAction() { byte *obd = _dragonOBD->getFromOpt(_cursor->data_80072890 - 1); - local_48._code = pvVar7 = obd + 8; - local_48._codeEnd = pvVar8 = local_48._code + READ_LE_UINT32(obd); + ScriptOpCall local_48(obd + 8, READ_LE_UINT32(obd)); + pvVar7 = local_48._code; + pvVar8 = local_48._codeEnd; uVar4 = _cursor->executeScript(local_48, 1); if (_cursor->data_800728b0_cursor_seqID > 4) { @@ -1063,29 +1058,30 @@ void DragonsEngine::performAction() { obd = _dragonOBD->getFromOpt(_scriptOpcodes->_scriptTargetINI - 1); _scriptOpcodes->_scriptTargetINI = _cursor->data_80072890; - local_38._code = obd + 8; - local_38._codeEnd = local_38._code + READ_LE_UINT32(obd); + ScriptOpCall local_38(obd + 8, READ_LE_UINT32(obd)); uVar6 = _cursor->executeScript(local_38, 1); _scriptOpcodes->_scriptTargetINI = uVar2; - } - if ((uVar6 & 0xffff) != 0) { - local_58._code = local_38._code + 8; - local_58._codeEnd = local_58._code + READ_LE_UINT16(local_38._code + 6); + + if ((uVar6 & 0xffff) != 0) { + local_58_code = local_38._code + 8; + local_58_codeEnd = local_58_code + READ_LE_UINT16(local_38._code + 6); + } } if (((uVar4 & 0xffff) != 0) && ((((uVar4 & 2) == 0 || ((uVar6 & 2) != 0)) || ((uVar6 & 0xffff) == 0)))) { - local_58._code = local_48._code + 8; - local_58._codeEnd = local_58._code + READ_LE_UINT16(local_48._code + 6); + local_58_code = local_48._code + 8; + local_58_codeEnd = local_58_code + READ_LE_UINT16(local_48._code + 6); } uVar4 = uVar4 & 0xfffd; - if (local_58._code != NULL && local_58._codeEnd != NULL) { + if (local_58_code != NULL && local_58_codeEnd != NULL) { clearFlags(ENGINE_FLAG_8); + ScriptOpCall local_58(local_58_code, local_58_codeEnd - local_58_code); _scriptOpcodes->runScript(local_58); + load_58_result = local_58._result; } - if ((local_58._result & 1U) == 0) { + if (!load_58_result) { if (_cursor->data_800728b0_cursor_seqID == 3) { - local_58._code = pvVar7; - local_58._codeEnd = pvVar8; + ScriptOpCall local_58(pvVar7, pvVar8 - pvVar7); uVar5 = _talk->talkToActor(local_58); uVar4 = uVar4 | uVar5; } @@ -1260,9 +1256,7 @@ void DragonsEngine::loadScene(uint16 sceneId) { //if (sceneId > 2) { //TODO remove this restriction to enable intro sequence. _scene->setSceneId(2); byte *obd = _dragonOBD->getFromSpt(3); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 4; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd)); _scriptOpcodes->runScript(scriptOpCall); //} else { // sceneId = 0x12; // HACK the first scene. TODO remove this diff --git a/engines/dragons/minigame3.cpp b/engines/dragons/minigame3.cpp index 18ef0c2f961..136061119b7 100644 --- a/engines/dragons/minigame3.cpp +++ b/engines/dragons/minigame3.cpp @@ -93,8 +93,7 @@ void Minigame3::run() { int16 local_1bc; int16 local_1ba; uint16 local_1b8; -// undefined auStack432 [20]; - int16 asStack412 [14]; + int16 eyeBgYOffsetTbl[21]; TearInfo tearInfo [30]; Common::Point bunnyPositionsTbl [4]; Common::Point handPositionsTbl [4]; @@ -127,7 +126,9 @@ void Minigame3::run() { error("Failed to open arc1.bin"); } - //TODO do we need this? memcpy(auStack432,&DAT_8008e88c,0x2a); + for (i = 0;i < 21; i++) { + eyeBgYOffsetTbl[i] = fd->readUint16LE(); + } fd->seek(0x2c); for (i = 0; i < 30; i++) { @@ -651,8 +652,8 @@ void Minigame3::run() { local_14 = 4; } updateBackgroundLayerOffset(2, (int) local_14 * 0x140, 0); - updateBackgroundLayerOffset(1, (int) -local_1c0, (int) asStack412[local_1c0]); - updateBackgroundLayerOffset(0, (int) -local_1c0, (int) asStack412[local_1c0]); + updateBackgroundLayerOffset(1, (int) -local_1c0, (int) eyeBgYOffsetTbl[local_1c0 + 10]); + updateBackgroundLayerOffset(0, (int) -local_1c0, (int) eyeBgYOffsetTbl[local_1c0 + 10]); } } else { diff --git a/engines/dragons/scene.cpp b/engines/dragons/scene.cpp index f3c87284d8d..da578a0a593 100644 --- a/engines/dragons/scene.cpp +++ b/engines/dragons/scene.cpp @@ -74,9 +74,7 @@ void Scene::loadScene(uint32 sceneId, uint32 cameraPointId) { if (!(sceneId & 0x8000)) { byte *obd = _dragonRMS->getObdDataFieldC(sceneId); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 4; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd)); _scriptOpcodes->runScript(scriptOpCall); } DragonINI *ini = _dragonINIResource->getRecord(0xc4); @@ -106,9 +104,7 @@ void Scene::loadSceneData(uint32 sceneId, uint32 cameraPointId) { if (!(sceneId & 0x8000)) { byte *obd = _dragonRMS->getObdDataField10(sceneId); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 4; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd)); uint16 oldSceneId = _currentSceneId; _currentSceneId = -1; _scriptOpcodes->runScript(scriptOpCall); @@ -330,9 +326,7 @@ void Scene::loadSceneData(uint32 sceneId, uint32 cameraPointId) { if (!(sceneId & 0x8000)) { byte *obd = _dragonRMS->getObdData(sceneId); - ScriptOpCall scriptOpCall; - scriptOpCall._code = obd + 4; - scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd); + ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd)); _scriptOpcodes->runScript(scriptOpCall); } @@ -500,12 +494,22 @@ Common::Point Scene::getLayerOffset(uint8 layerNumber) { void Scene::drawBgLayer(uint8 layerNumber, Common::Rect rect, Graphics::Surface *surface) { Common::Point offset = _stage->getLayerOffset(layerNumber); - Common::Rect clippedRect = _screen->clipRectToRect(offset.x, offset.y, rect, Common::Rect(_stage->getBgLayer()->w, _stage->getBgLayer()->h)); - clippedRect.left += offset.x < 0 ? -offset.x : 0; - clippedRect.right += offset.x < 0 ? -offset.x : 0; - clippedRect.top += offset.y < 0 ? -offset.y : 0; - clippedRect.bottom += offset.y < 0 ? -offset.y : 0; - _screen->copyRectToSurface8bpp(*surface, _screen->getPalette(0), 0, 0, clippedRect, false, 128); +// Common::Rect clippedRect = _screen->clipRectToRect(offset.x, offset.y, rect, Common::Rect(_stage->getBgLayer()->w, _stage->getBgLayer()->h)); + rect.left += rect.left + offset.x < 0 ? -(rect.left + offset.x) : offset.x; + if (rect.right + offset.x > surface->w) { + rect.right = surface->w - 1; + } else { + rect.right += offset.x; + } +// clippedRect.right += offset.x < 0 ? -offset.x : 0; + rect.top += rect.top + offset.y < 0 ? -(rect.top + offset.y) : offset.y; + if (rect.bottom + offset.y > surface->h) { + rect.bottom = surface->h - 1; + } else { + rect.bottom += offset.y; + } +// clippedRect.bottom += offset.y < 0 ? -offset.y : 0; + _screen->copyRectToSurface8bpp(*surface, _screen->getPalette(0), 0, 0, rect, false, 128); } } // End of namespace Dragons diff --git a/engines/dragons/scriptopcodes.cpp b/engines/dragons/scriptopcodes.cpp index 0f85318b60d..9b11af5d081 100644 --- a/engines/dragons/scriptopcodes.cpp +++ b/engines/dragons/scriptopcodes.cpp @@ -59,6 +59,11 @@ uint32 ScriptOpCall::readUint32() { return value; } +ScriptOpCall::ScriptOpCall(byte *start, uint32 length): _op(0), _result(0), _field8(0) { + _code = _base = start; + _codeEnd = _code + length; +} + // ScriptOpcodes ScriptOpcodes::ScriptOpcodes(DragonsEngine *vm, DragonFLG *dragonFLG) @@ -76,7 +81,7 @@ ScriptOpcodes::~ScriptOpcodes() { void ScriptOpcodes::execOpcode(ScriptOpCall &scriptOpCall) { if (!_opcodes[scriptOpCall._op]) error("ScriptOpcodes::execOpcode() Unimplemented opcode %d (0x%X)", scriptOpCall._op, scriptOpCall._op); - debug("execScriptOpcode(0x%X) %s", scriptOpCall._op, _opcodeNames[scriptOpCall._op].c_str()); + debug("execScriptOpcode(0x%X) @%X %s", scriptOpCall._op, scriptOpCall._code - scriptOpCall._base, _opcodeNames[scriptOpCall._op].c_str()); (*_opcodes[scriptOpCall._op])(scriptOpCall); } @@ -273,11 +278,9 @@ void ScriptOpcodes::opUnk3(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opExecuteScript(ScriptOpCall &scriptOpCall) { ARG_SKIP(2); ARG_UINT32(obdOffset); - ScriptOpCall newScriptOpCall; byte *data =_vm->_dragonOBD->getObdAtOffset(obdOffset); - newScriptOpCall._code = data + 4; - newScriptOpCall._codeEnd = newScriptOpCall._code + READ_LE_UINT32(data); + ScriptOpCall newScriptOpCall(data + 4, READ_LE_UINT32(data)); newScriptOpCall._field8 = scriptOpCall._field8; newScriptOpCall._result = 0; @@ -393,9 +396,7 @@ void ScriptOpcodes::opUnk13PropertiesRelated(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opUnk14PropertiesRelated(ScriptOpCall &scriptOpCall) { if (checkPropertyFlag(scriptOpCall)) { - ScriptOpCall localScriptOpCall; - localScriptOpCall._code = scriptOpCall._code + 4; - localScriptOpCall._codeEnd = localScriptOpCall._code + READ_LE_UINT16(scriptOpCall._code); + ScriptOpCall localScriptOpCall(scriptOpCall._code + 4, READ_LE_UINT16(scriptOpCall._code)); localScriptOpCall._field8 = scriptOpCall._field8; localScriptOpCall._result = 0; @@ -418,9 +419,7 @@ void ScriptOpcodes::opUnk14PropertiesRelated(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opUnk15PropertiesRelated(ScriptOpCall &scriptOpCall) { while (true) { if (checkPropertyFlag(scriptOpCall)) { - ScriptOpCall localScriptOpCall; - localScriptOpCall._code = scriptOpCall._code + 4; - localScriptOpCall._codeEnd = localScriptOpCall._code + READ_LE_UINT32(scriptOpCall._code); + ScriptOpCall localScriptOpCall(scriptOpCall._code + 4, READ_LE_UINT32(scriptOpCall._code)); runScript(localScriptOpCall); @@ -1076,9 +1075,7 @@ void ScriptOpcodes::opUnk19(ScriptOpCall &scriptOpCall) { ARG_INT16(size); if (scriptOpCall._field8 == 3) { - ScriptOpCall newCall; - newCall._code = scriptOpCall._code; - newCall._codeEnd = scriptOpCall._code + size; + ScriptOpCall newCall(scriptOpCall._code, size); _vm->_scriptOpcodes->runScript(newCall); } scriptOpCall._code += size; diff --git a/engines/dragons/scriptopcodes.h b/engines/dragons/scriptopcodes.h index ae75d91e0ff..7f2ddf29b16 100644 --- a/engines/dragons/scriptopcodes.h +++ b/engines/dragons/scriptopcodes.h @@ -34,10 +34,12 @@ class DragonsEngine; struct ScriptOpCall { byte _op; + byte *_base; byte *_code; byte *_codeEnd; int _field8; int _result; + ScriptOpCall(byte *start, uint32 length); void skip(uint size); byte readByte(); int16 readSint16(); diff --git a/engines/dragons/talk.cpp b/engines/dragons/talk.cpp index 7f192254a4a..81021c2617d 100644 --- a/engines/dragons/talk.cpp +++ b/engines/dragons/talk.cpp @@ -536,7 +536,6 @@ bool Talk::talkToActor(ScriptOpCall &scriptOpCall) { uint16_t sequenceId; TalkDialogEntry *selectedDialogText; uint iniId; - ScriptOpCall local_1d20; short local_990 [5]; uint16 auStack2438 [195]; uint16 local_800 [1000]; @@ -610,8 +609,7 @@ bool Talk::talkToActor(ScriptOpCall &scriptOpCall) { iniActor->updateSequence(sequenceId); } } - local_1d20._code = selectedDialogText->scriptCodeStartPtr; - local_1d20._codeEnd = selectedDialogText->scriptCodeEndPtr; + ScriptOpCall local_1d20(selectedDialogText->scriptCodeStartPtr, selectedDialogText->scriptCodeEndPtr - selectedDialogText->scriptCodeStartPtr); _vm->_scriptOpcodes->runScript(local_1d20); if (_vm->_scriptOpcodes->_data_80071f5c != 0) break; local_1d20._code = selectedDialogText->scriptCodeStartPtr;