DRAGONS: added ScriptOpCode constructor. Work on eyes bg layer in mini

game 3
This commit is contained in:
Eric Fry 2019-11-18 20:31:17 +11:00 committed by Eugene Sandulenko
parent fcd92dc4c3
commit c836646b69
7 changed files with 64 additions and 72 deletions

View file

@ -247,9 +247,7 @@ int16 Cursor::updateIniFromScene() {
for(int idx=0; idx < 5; idx++) { for(int idx=0; idx < 5; idx++) {
data_800728b0_cursor_seqID = idx; data_800728b0_cursor_seqID = idx;
byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId); byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 8;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
// uVar17 = uVar15; // uVar17 = uVar15;
// local_58 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8; // local_58 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8;
@ -276,9 +274,7 @@ int16 Cursor::updateIniFromScene() {
return _iniUnderCursor; return _iniUnderCursor;
} }
byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId); byte *obd = _vm->_dragonOBD->getFromOpt(cursorOverIni - 1); //_dragonRMS->getObdDataFieldC(sceneId);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 8;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
// local_48 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8; // local_48 = dragon_Obd_Offset + *(int *)(uVar16 * 8 + dragon_Opt_Offset + -8) + 8;
// local_44 = read_int32(); // local_44 = read_int32();

View file

@ -263,7 +263,6 @@ void DragonsEngine::gameLoop()
uint16_t sequenceId; uint16_t sequenceId;
DragonINI *pDVar8; DragonINI *pDVar8;
ushort *puVar9; ushort *puVar9;
ScriptOpCall local_30;
_cursor->_cursorActivationSeqOffset = 0; _cursor->_cursorActivationSeqOffset = 0;
bit_flags_8006fbd8 = 0; bit_flags_8006fbd8 = 0;
@ -314,9 +313,7 @@ void DragonsEngine::gameLoop()
if (actorId_00 == 0) goto LAB_80026d34; if (actorId_00 == 0) goto LAB_80026d34;
if (actorId_00 != (actorId & 0xffff)) { if (actorId_00 != (actorId & 0xffff)) {
byte *obd = _dragonOBD->getFromOpt(actorId_00 - 1); byte *obd = _dragonOBD->getFromOpt(actorId_00 - 1);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 8;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
if(_scriptOpcodes->runScript4(scriptOpCall)) { if(_scriptOpcodes->runScript4(scriptOpCall)) {
scriptOpCall._codeEnd = scriptOpCall._code + 4 + READ_LE_UINT16(scriptOpCall._code + 2); 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) { if (ini->field_1a_flags_maybe & Dragons::INI_FLAG_10) {
ini->field_1a_flags_maybe &= ~Dragons::INI_FLAG_10; ini->field_1a_flags_maybe &= ~Dragons::INI_FLAG_10;
byte *data = _dragonOBD->getFromOpt(i); byte *data = _dragonOBD->getFromOpt(i);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(data + 8, READ_LE_UINT32(data));
scriptOpCall._code = data + 8;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(data);
uint32 currentFlags = _flags; uint32 currentFlags = _flags;
clearFlags(Dragons::ENGINE_FLAG_8); clearFlags(Dragons::ENGINE_FLAG_8);
_scriptOpcodes->runScript3(scriptOpCall); _scriptOpcodes->runScript3(scriptOpCall);
@ -1034,17 +1029,16 @@ void DragonsEngine::performAction() {
uint uVar4; uint uVar4;
uint uVar5; uint uVar5;
uint uVar6; uint uVar6;
ScriptOpCall local_48;
ScriptOpCall local_38;
ScriptOpCall local_58;
byte * pvVar7; byte * pvVar7;
byte * pvVar8; byte * pvVar8;
byte *local_58_code;
byte *local_58_codeEnd;
bool load_58_result = false;
uVar2 = _scriptOpcodes->_scriptTargetINI; uVar2 = _scriptOpcodes->_scriptTargetINI;
uVar1 = _flags; uVar1 = _flags;
local_58._code = NULL; local_58_code = NULL;
local_58._codeEnd = NULL; local_58_codeEnd = NULL;
local_58._result = 0;
uVar6 = 0; uVar6 = 0;
_scriptOpcodes->_data_80071f5c = 0; _scriptOpcodes->_data_80071f5c = 0;
@ -1053,8 +1047,9 @@ void DragonsEngine::performAction() {
byte *obd = _dragonOBD->getFromOpt(_cursor->data_80072890 - 1); byte *obd = _dragonOBD->getFromOpt(_cursor->data_80072890 - 1);
local_48._code = pvVar7 = obd + 8; ScriptOpCall local_48(obd + 8, READ_LE_UINT32(obd));
local_48._codeEnd = pvVar8 = local_48._code + READ_LE_UINT32(obd); pvVar7 = local_48._code;
pvVar8 = local_48._codeEnd;
uVar4 = _cursor->executeScript(local_48, 1); uVar4 = _cursor->executeScript(local_48, 1);
if (_cursor->data_800728b0_cursor_seqID > 4) { if (_cursor->data_800728b0_cursor_seqID > 4) {
@ -1063,29 +1058,30 @@ void DragonsEngine::performAction() {
obd = _dragonOBD->getFromOpt(_scriptOpcodes->_scriptTargetINI - 1); obd = _dragonOBD->getFromOpt(_scriptOpcodes->_scriptTargetINI - 1);
_scriptOpcodes->_scriptTargetINI = _cursor->data_80072890; _scriptOpcodes->_scriptTargetINI = _cursor->data_80072890;
local_38._code = obd + 8; ScriptOpCall local_38(obd + 8, READ_LE_UINT32(obd));
local_38._codeEnd = local_38._code + READ_LE_UINT32(obd);
uVar6 = _cursor->executeScript(local_38, 1); uVar6 = _cursor->executeScript(local_38, 1);
_scriptOpcodes->_scriptTargetINI = uVar2; _scriptOpcodes->_scriptTargetINI = uVar2;
}
if ((uVar6 & 0xffff) != 0) { if ((uVar6 & 0xffff) != 0) {
local_58._code = local_38._code + 8; local_58_code = local_38._code + 8;
local_58._codeEnd = local_58._code + READ_LE_UINT16(local_38._code + 6); 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)))) { if (((uVar4 & 0xffff) != 0) && ((((uVar4 & 2) == 0 || ((uVar6 & 2) != 0)) || ((uVar6 & 0xffff) == 0)))) {
local_58._code = local_48._code + 8; local_58_code = local_48._code + 8;
local_58._codeEnd = local_58._code + READ_LE_UINT16(local_48._code + 6); local_58_codeEnd = local_58_code + READ_LE_UINT16(local_48._code + 6);
} }
uVar4 = uVar4 & 0xfffd; 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); clearFlags(ENGINE_FLAG_8);
ScriptOpCall local_58(local_58_code, local_58_codeEnd - local_58_code);
_scriptOpcodes->runScript(local_58); _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) { if (_cursor->data_800728b0_cursor_seqID == 3) {
local_58._code = pvVar7; ScriptOpCall local_58(pvVar7, pvVar8 - pvVar7);
local_58._codeEnd = pvVar8;
uVar5 = _talk->talkToActor(local_58); uVar5 = _talk->talkToActor(local_58);
uVar4 = uVar4 | uVar5; uVar4 = uVar4 | uVar5;
} }
@ -1260,9 +1256,7 @@ void DragonsEngine::loadScene(uint16 sceneId) {
//if (sceneId > 2) { //TODO remove this restriction to enable intro sequence. //if (sceneId > 2) { //TODO remove this restriction to enable intro sequence.
_scene->setSceneId(2); _scene->setSceneId(2);
byte *obd = _dragonOBD->getFromSpt(3); byte *obd = _dragonOBD->getFromSpt(3);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 4;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
_scriptOpcodes->runScript(scriptOpCall); _scriptOpcodes->runScript(scriptOpCall);
//} else { //} else {
// sceneId = 0x12; // HACK the first scene. TODO remove this // sceneId = 0x12; // HACK the first scene. TODO remove this

View file

@ -93,8 +93,7 @@ void Minigame3::run() {
int16 local_1bc; int16 local_1bc;
int16 local_1ba; int16 local_1ba;
uint16 local_1b8; uint16 local_1b8;
// undefined auStack432 [20]; int16 eyeBgYOffsetTbl[21];
int16 asStack412 [14];
TearInfo tearInfo [30]; TearInfo tearInfo [30];
Common::Point bunnyPositionsTbl [4]; Common::Point bunnyPositionsTbl [4];
Common::Point handPositionsTbl [4]; Common::Point handPositionsTbl [4];
@ -127,7 +126,9 @@ void Minigame3::run() {
error("Failed to open arc1.bin"); 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); fd->seek(0x2c);
for (i = 0; i < 30; i++) { for (i = 0; i < 30; i++) {
@ -651,8 +652,8 @@ void Minigame3::run() {
local_14 = 4; local_14 = 4;
} }
updateBackgroundLayerOffset(2, (int) local_14 * 0x140, 0); updateBackgroundLayerOffset(2, (int) local_14 * 0x140, 0);
updateBackgroundLayerOffset(1, (int) -local_1c0, (int) asStack412[local_1c0]); updateBackgroundLayerOffset(1, (int) -local_1c0, (int) eyeBgYOffsetTbl[local_1c0 + 10]);
updateBackgroundLayerOffset(0, (int) -local_1c0, (int) asStack412[local_1c0]); updateBackgroundLayerOffset(0, (int) -local_1c0, (int) eyeBgYOffsetTbl[local_1c0 + 10]);
} }
} }
else { else {

View file

@ -74,9 +74,7 @@ void Scene::loadScene(uint32 sceneId, uint32 cameraPointId) {
if (!(sceneId & 0x8000)) { if (!(sceneId & 0x8000)) {
byte *obd = _dragonRMS->getObdDataFieldC(sceneId); byte *obd = _dragonRMS->getObdDataFieldC(sceneId);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 4;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
_scriptOpcodes->runScript(scriptOpCall); _scriptOpcodes->runScript(scriptOpCall);
} }
DragonINI *ini = _dragonINIResource->getRecord(0xc4); DragonINI *ini = _dragonINIResource->getRecord(0xc4);
@ -106,9 +104,7 @@ void Scene::loadSceneData(uint32 sceneId, uint32 cameraPointId) {
if (!(sceneId & 0x8000)) { if (!(sceneId & 0x8000)) {
byte *obd = _dragonRMS->getObdDataField10(sceneId); byte *obd = _dragonRMS->getObdDataField10(sceneId);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 4;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
uint16 oldSceneId = _currentSceneId; uint16 oldSceneId = _currentSceneId;
_currentSceneId = -1; _currentSceneId = -1;
_scriptOpcodes->runScript(scriptOpCall); _scriptOpcodes->runScript(scriptOpCall);
@ -330,9 +326,7 @@ void Scene::loadSceneData(uint32 sceneId, uint32 cameraPointId) {
if (!(sceneId & 0x8000)) { if (!(sceneId & 0x8000)) {
byte *obd = _dragonRMS->getObdData(sceneId); byte *obd = _dragonRMS->getObdData(sceneId);
ScriptOpCall scriptOpCall; ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd));
scriptOpCall._code = obd + 4;
scriptOpCall._codeEnd = scriptOpCall._code + READ_LE_UINT32(obd);
_scriptOpcodes->runScript(scriptOpCall); _scriptOpcodes->runScript(scriptOpCall);
} }
@ -500,12 +494,22 @@ Common::Point Scene::getLayerOffset(uint8 layerNumber) {
void Scene::drawBgLayer(uint8 layerNumber, Common::Rect rect, Graphics::Surface *surface) { void Scene::drawBgLayer(uint8 layerNumber, Common::Rect rect, Graphics::Surface *surface) {
Common::Point offset = _stage->getLayerOffset(layerNumber); Common::Point offset = _stage->getLayerOffset(layerNumber);
Common::Rect clippedRect = _screen->clipRectToRect(offset.x, offset.y, rect, Common::Rect(_stage->getBgLayer()->w, _stage->getBgLayer()->h)); // 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; rect.left += rect.left + offset.x < 0 ? -(rect.left + offset.x) : offset.x;
clippedRect.right += offset.x < 0 ? -offset.x : 0; if (rect.right + offset.x > surface->w) {
clippedRect.top += offset.y < 0 ? -offset.y : 0; rect.right = surface->w - 1;
clippedRect.bottom += offset.y < 0 ? -offset.y : 0; } else {
_screen->copyRectToSurface8bpp(*surface, _screen->getPalette(0), 0, 0, clippedRect, false, 128); 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 } // End of namespace Dragons

View file

@ -59,6 +59,11 @@ uint32 ScriptOpCall::readUint32() {
return value; return value;
} }
ScriptOpCall::ScriptOpCall(byte *start, uint32 length): _op(0), _result(0), _field8(0) {
_code = _base = start;
_codeEnd = _code + length;
}
// ScriptOpcodes // ScriptOpcodes
ScriptOpcodes::ScriptOpcodes(DragonsEngine *vm, DragonFLG *dragonFLG) ScriptOpcodes::ScriptOpcodes(DragonsEngine *vm, DragonFLG *dragonFLG)
@ -76,7 +81,7 @@ ScriptOpcodes::~ScriptOpcodes() {
void ScriptOpcodes::execOpcode(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::execOpcode(ScriptOpCall &scriptOpCall) {
if (!_opcodes[scriptOpCall._op]) if (!_opcodes[scriptOpCall._op])
error("ScriptOpcodes::execOpcode() Unimplemented opcode %d (0x%X)", scriptOpCall._op, 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); (*_opcodes[scriptOpCall._op])(scriptOpCall);
} }
@ -273,11 +278,9 @@ void ScriptOpcodes::opUnk3(ScriptOpCall &scriptOpCall) {
void ScriptOpcodes::opExecuteScript(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opExecuteScript(ScriptOpCall &scriptOpCall) {
ARG_SKIP(2); ARG_SKIP(2);
ARG_UINT32(obdOffset); ARG_UINT32(obdOffset);
ScriptOpCall newScriptOpCall;
byte *data =_vm->_dragonOBD->getObdAtOffset(obdOffset); byte *data =_vm->_dragonOBD->getObdAtOffset(obdOffset);
newScriptOpCall._code = data + 4; ScriptOpCall newScriptOpCall(data + 4, READ_LE_UINT32(data));
newScriptOpCall._codeEnd = newScriptOpCall._code + READ_LE_UINT32(data);
newScriptOpCall._field8 = scriptOpCall._field8; newScriptOpCall._field8 = scriptOpCall._field8;
newScriptOpCall._result = 0; newScriptOpCall._result = 0;
@ -393,9 +396,7 @@ void ScriptOpcodes::opUnk13PropertiesRelated(ScriptOpCall &scriptOpCall) {
void ScriptOpcodes::opUnk14PropertiesRelated(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opUnk14PropertiesRelated(ScriptOpCall &scriptOpCall) {
if (checkPropertyFlag(scriptOpCall)) { if (checkPropertyFlag(scriptOpCall)) {
ScriptOpCall localScriptOpCall; ScriptOpCall localScriptOpCall(scriptOpCall._code + 4, READ_LE_UINT16(scriptOpCall._code));
localScriptOpCall._code = scriptOpCall._code + 4;
localScriptOpCall._codeEnd = localScriptOpCall._code + READ_LE_UINT16(scriptOpCall._code);
localScriptOpCall._field8 = scriptOpCall._field8; localScriptOpCall._field8 = scriptOpCall._field8;
localScriptOpCall._result = 0; localScriptOpCall._result = 0;
@ -418,9 +419,7 @@ void ScriptOpcodes::opUnk14PropertiesRelated(ScriptOpCall &scriptOpCall) {
void ScriptOpcodes::opUnk15PropertiesRelated(ScriptOpCall &scriptOpCall) { void ScriptOpcodes::opUnk15PropertiesRelated(ScriptOpCall &scriptOpCall) {
while (true) { while (true) {
if (checkPropertyFlag(scriptOpCall)) { if (checkPropertyFlag(scriptOpCall)) {
ScriptOpCall localScriptOpCall; ScriptOpCall localScriptOpCall(scriptOpCall._code + 4, READ_LE_UINT32(scriptOpCall._code));
localScriptOpCall._code = scriptOpCall._code + 4;
localScriptOpCall._codeEnd = localScriptOpCall._code + READ_LE_UINT32(scriptOpCall._code);
runScript(localScriptOpCall); runScript(localScriptOpCall);
@ -1076,9 +1075,7 @@ void ScriptOpcodes::opUnk19(ScriptOpCall &scriptOpCall) {
ARG_INT16(size); ARG_INT16(size);
if (scriptOpCall._field8 == 3) { if (scriptOpCall._field8 == 3) {
ScriptOpCall newCall; ScriptOpCall newCall(scriptOpCall._code, size);
newCall._code = scriptOpCall._code;
newCall._codeEnd = scriptOpCall._code + size;
_vm->_scriptOpcodes->runScript(newCall); _vm->_scriptOpcodes->runScript(newCall);
} }
scriptOpCall._code += size; scriptOpCall._code += size;

View file

@ -34,10 +34,12 @@ class DragonsEngine;
struct ScriptOpCall { struct ScriptOpCall {
byte _op; byte _op;
byte *_base;
byte *_code; byte *_code;
byte *_codeEnd; byte *_codeEnd;
int _field8; int _field8;
int _result; int _result;
ScriptOpCall(byte *start, uint32 length);
void skip(uint size); void skip(uint size);
byte readByte(); byte readByte();
int16 readSint16(); int16 readSint16();

View file

@ -536,7 +536,6 @@ bool Talk::talkToActor(ScriptOpCall &scriptOpCall) {
uint16_t sequenceId; uint16_t sequenceId;
TalkDialogEntry *selectedDialogText; TalkDialogEntry *selectedDialogText;
uint iniId; uint iniId;
ScriptOpCall local_1d20;
short local_990 [5]; short local_990 [5];
uint16 auStack2438 [195]; uint16 auStack2438 [195];
uint16 local_800 [1000]; uint16 local_800 [1000];
@ -610,8 +609,7 @@ bool Talk::talkToActor(ScriptOpCall &scriptOpCall) {
iniActor->updateSequence(sequenceId); iniActor->updateSequence(sequenceId);
} }
} }
local_1d20._code = selectedDialogText->scriptCodeStartPtr; ScriptOpCall local_1d20(selectedDialogText->scriptCodeStartPtr, selectedDialogText->scriptCodeEndPtr - selectedDialogText->scriptCodeStartPtr);
local_1d20._codeEnd = selectedDialogText->scriptCodeEndPtr;
_vm->_scriptOpcodes->runScript(local_1d20); _vm->_scriptOpcodes->runScript(local_1d20);
if (_vm->_scriptOpcodes->_data_80071f5c != 0) break; if (_vm->_scriptOpcodes->_data_80071f5c != 0) break;
local_1d20._code = selectedDialogText->scriptCodeStartPtr; local_1d20._code = selectedDialogText->scriptCodeStartPtr;