mirror of
https://github.com/scummvm/gamos.git
synced 2026-05-21 05:40:53 +00:00
GAMOS: Change of VM class for eliminating global objects
This commit is contained in:
@@ -43,9 +43,6 @@
|
||||
|
||||
namespace Gamos {
|
||||
|
||||
GamosEngine *g_engine;
|
||||
|
||||
|
||||
const byte GamosEngine::_xorKeys[32] = {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c,
|
||||
0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
|
||||
0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
|
||||
@@ -53,9 +50,10 @@ const byte GamosEngine::_xorKeys[32] = {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x8
|
||||
};
|
||||
|
||||
GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
|
||||
_gameDescription(gameDesc), _randomSource("Gamos"), _messageProc(this) {
|
||||
g_engine = this;
|
||||
}
|
||||
_gameDescription(gameDesc), _randomSource("Gamos"),
|
||||
_messageProc(this),
|
||||
_vm(this, callbackVMCallDispatcher),
|
||||
_txtInputVMAccess(_vm) {}
|
||||
|
||||
GamosEngine::~GamosEngine() {
|
||||
freeImages();
|
||||
@@ -97,9 +95,6 @@ Common::Error GamosEngine::run() {
|
||||
// Set the engine's debugger console
|
||||
setDebugger(new Console());
|
||||
|
||||
VM::_callFuncs = callbackVMCallDispatcher;
|
||||
VM::_callingObject = this;
|
||||
|
||||
// If a savegame was selected from the launcher, load it
|
||||
int saveSlot = ConfMan.getInt("save_slot");
|
||||
if (saveSlot != -1)
|
||||
@@ -439,16 +434,16 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
|
||||
_addrKeyCode = _loadedDataSize + 3;
|
||||
_addrCurrentFrame = _loadedDataSize + 4;
|
||||
|
||||
VM::memory().setU8(_addrBlk12, dataStream.readByte());
|
||||
_vm.memory().setU8(_addrBlk12, dataStream.readByte());
|
||||
dataStream.skip(1);
|
||||
VM::memory().setU8(_addrFPS, _fps);
|
||||
VM::memory().setU8(_addrKeyDown, dataStream.readByte());
|
||||
VM::memory().setU8(_addrKeyCode, dataStream.readByte());
|
||||
VM::memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
|
||||
_vm.memory().setU8(_addrFPS, _fps);
|
||||
_vm.memory().setU8(_addrKeyDown, dataStream.readByte());
|
||||
_vm.memory().setU8(_addrKeyCode, dataStream.readByte());
|
||||
_vm.memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
|
||||
|
||||
setFPS(_fps);
|
||||
} else if (tp == RESTP_13) {
|
||||
VM::writeMemory(_loadedDataSize, data, dataSize);
|
||||
_vm.writeMemory(_loadedDataSize, data, dataSize);
|
||||
} else if (tp == RESTP_18) {
|
||||
loadRes18(pid, data, dataSize);
|
||||
} else if (tp == RESTP_19) {
|
||||
@@ -474,11 +469,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
|
||||
return false;
|
||||
_objectActions[pid].unk1 = getU32(data);
|
||||
} else if (tp == RESTP_21) {
|
||||
VM::writeMemory(_loadedDataSize, data, dataSize);
|
||||
_vm.writeMemory(_loadedDataSize, data, dataSize);
|
||||
_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
|
||||
//warning("RESTP_21 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
|
||||
} else if (tp == RESTP_22) {
|
||||
VM::writeMemory(_loadedDataSize, data, dataSize);
|
||||
_vm.writeMemory(_loadedDataSize, data, dataSize);
|
||||
_objectActions[pid].onDeleteAddress = _loadedDataSize + p3;
|
||||
//warning("RESTP_22 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
|
||||
} else if (tp == RESTP_23) {
|
||||
@@ -489,11 +484,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
|
||||
Actions &scr = _objectActions[pid].actions[p1];
|
||||
scr.parse(data, dataSize);
|
||||
} else if (tp == RESTP_2B) {
|
||||
VM::writeMemory(_loadedDataSize, data, dataSize);
|
||||
_vm.writeMemory(_loadedDataSize, data, dataSize);
|
||||
_objectActions[pid].actions[p1].conditionAddress = _loadedDataSize + p3;
|
||||
//warning("RESTP_2B %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
|
||||
} else if (tp == RESTP_2C) {
|
||||
VM::writeMemory(_loadedDataSize, data, dataSize);
|
||||
_vm.writeMemory(_loadedDataSize, data, dataSize);
|
||||
_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
|
||||
//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
|
||||
} else if (tp == RESTP_38) {
|
||||
@@ -734,7 +729,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
|
||||
_subtitlePoints.resize(dat6xCount);
|
||||
|
||||
_loadedDataSize = 0;
|
||||
VM::clearMemory();
|
||||
_vm.clearMemory();
|
||||
}
|
||||
|
||||
void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
|
||||
@@ -1221,7 +1216,7 @@ void GamosEngine::changeVolume() {
|
||||
|
||||
uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
|
||||
_needReload = false;
|
||||
VM::_interrupt = false;
|
||||
_vm._interrupt = false;
|
||||
|
||||
if (_d2_fld16 == 0) {
|
||||
act1 = ACT_NONE;
|
||||
@@ -2316,79 +2311,79 @@ bool GamosEngine::loadImage(Image *img) {
|
||||
}
|
||||
|
||||
uint32 GamosEngine::doScript(uint32 scriptAddress) {
|
||||
uint32 res = VM::doScript(scriptAddress, PTR_004173e8);
|
||||
uint32 res = _vm.doScript(scriptAddress, PTR_004173e8);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
|
||||
uint32 arg1 = 0, arg2 = 0;
|
||||
|
||||
switch (funcID) {
|
||||
case 0:
|
||||
DAT_004177ff = true;
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
case 1:
|
||||
vm->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
|
||||
ctx->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (PTR_00417218->x == -1)
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
else
|
||||
vm->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
|
||||
ctx->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
|
||||
break;
|
||||
case 3:
|
||||
vm->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
|
||||
ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
|
||||
break;
|
||||
case 4:
|
||||
vm->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
|
||||
ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
|
||||
break;
|
||||
case 5:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
|
||||
break;
|
||||
case 6:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
|
||||
break;
|
||||
case 7:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if ((PTR_00417218->fld_4 & 0x40) == 0 || (PTR_00417218->fld_4 & 8) != (arg1 & 8))
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
else
|
||||
vm->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
|
||||
ctx->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
|
||||
break;
|
||||
case 8:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
|
||||
break;
|
||||
case 9:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
|
||||
break;
|
||||
case 10:
|
||||
vm->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
|
||||
ctx->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
|
||||
break;
|
||||
case 11:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
|
||||
break;
|
||||
case 12:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
|
||||
break;
|
||||
case 13: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
Common::String str = vm->getString(regRef);
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
Common::String str = ctx->getString(regRef);
|
||||
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
|
||||
for(uint i = 0; i < str.size(); i++) {
|
||||
if (str[i] == RawKeyCode) {
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2396,79 +2391,79 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
}
|
||||
|
||||
case 14:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
loadModule(arg1);
|
||||
setNeedReload();
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
switchToGameScreen(arg1, false);
|
||||
setNeedReload();
|
||||
break;
|
||||
|
||||
case 16:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( scriptFunc16(arg1) );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( scriptFunc16(arg1) );
|
||||
break;
|
||||
|
||||
case 17:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
playSound(arg1);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
|
||||
break;
|
||||
|
||||
case 19:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( scriptFunc19(arg1) );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( scriptFunc19(arg1) );
|
||||
break;
|
||||
|
||||
case 20: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
for (const SubtitlePoint &d : _subtitlePoints[arg1]) {
|
||||
FUN_0040738c(d.sprId, d.x, d.y, true);
|
||||
}
|
||||
vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
|
||||
ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
|
||||
} break;
|
||||
|
||||
case 21: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
arg2 = vm->pop32();
|
||||
vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
arg2 = ctx->pop32();
|
||||
ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
|
||||
} break;
|
||||
|
||||
case 22: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
arg2 = vm->pop32();
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
arg2 = ctx->pop32();
|
||||
const SubtitlePoint &d = _subtitlePoints[arg2][0];
|
||||
vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
|
||||
ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
|
||||
} break;
|
||||
|
||||
case 23: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
arg2 = vm->pop32();
|
||||
addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
|
||||
vm->EAX.setVal(1);
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
arg2 = ctx->pop32();
|
||||
addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 24: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
arg2 = vm->pop32();
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
arg2 = ctx->pop32();
|
||||
const SubtitlePoint &d = _subtitlePoints[arg2][0];
|
||||
addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y);
|
||||
addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y);
|
||||
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 25: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (PTR_00417218->fld_5 != arg1) {
|
||||
PTR_00417218->fld_5 = arg1;
|
||||
if (PTR_00417218->x != -1) {
|
||||
@@ -2481,30 +2476,30 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
addDirtRectOnObject(&obj);
|
||||
}
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 26:
|
||||
removeSubtitles(PTR_00417218);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 27:
|
||||
FUN_004025d0();
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 28:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
FUN_0040279c(arg1, false);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
FUN_0040279c(arg1, true);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 30: {
|
||||
@@ -2517,29 +2512,29 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
} break;
|
||||
|
||||
case 31:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
setCursor(arg1, true);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
setCursor(0, false);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 33:
|
||||
PTR_00417218->fld_5 = _statesHeight - PTR_00417218->blk;
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 34: {
|
||||
VM::ValAddr regRef = vm->popReg();
|
||||
vm->setMem8(regRef, PTR_00417218->fld_5);
|
||||
vm->EAX.setVal(1);
|
||||
VM::ValAddr regRef = ctx->popReg();
|
||||
ctx->setMem8(regRef, PTR_00417218->fld_5);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 35: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
uint ret = 0;
|
||||
switch (arg1) {
|
||||
case 3:
|
||||
@@ -2581,12 +2576,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vm->EAX.setVal(ret);
|
||||
ctx->EAX.setVal(ret);
|
||||
} break;
|
||||
|
||||
case 36: {
|
||||
arg1 = vm->pop32();
|
||||
arg2 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
arg2 = ctx->pop32();
|
||||
|
||||
uint ret = 0;
|
||||
switch (arg1) {
|
||||
@@ -2637,12 +2632,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vm->EAX.setVal(ret);
|
||||
ctx->EAX.setVal(ret);
|
||||
} break;
|
||||
|
||||
case 37: {
|
||||
arg1 = vm->pop32();
|
||||
arg2 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
arg2 = ctx->pop32();
|
||||
|
||||
uint ret = 0;
|
||||
switch (arg1) {
|
||||
@@ -2693,43 +2688,43 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vm->EAX.setVal(ret);
|
||||
ctx->EAX.setVal(ret);
|
||||
} break;
|
||||
|
||||
case 38:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804 == 0 || (int32)arg1 != INT_00412ca0)
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
else
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 39:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804 == 0 || (int32)arg1 != INT_00412c9c)
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
else
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 40:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412ca0) != 0)
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
else
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
break;
|
||||
|
||||
case 41:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412c9c) != 0)
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
else
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
break;
|
||||
|
||||
case 42: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804 != 0) {
|
||||
if (arg1 == 0) {
|
||||
DAT_00417804 = 0;
|
||||
@@ -2752,11 +2747,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
FUN_00402a68(tmp);
|
||||
}
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 43: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804) {
|
||||
ActEntry tmp;
|
||||
tmp.value = arg1;
|
||||
@@ -2764,11 +2759,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
tmp.flags = 0;
|
||||
FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 44: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (DAT_00417804) {
|
||||
ActEntry tmp;
|
||||
tmp.value = arg1;
|
||||
@@ -2776,45 +2771,45 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
tmp.flags = 1;
|
||||
FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 45:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
|
||||
break;
|
||||
|
||||
case 46: {
|
||||
VM::ValAddr a1 = vm->popReg();
|
||||
VM::ValAddr a2 = vm->popReg();
|
||||
Common::String s = vm->getString(a1);
|
||||
VM::ValAddr a1 = ctx->popReg();
|
||||
VM::ValAddr a2 = ctx->popReg();
|
||||
Common::String s = ctx->getString(a1);
|
||||
for(int i = 0; i <= s.size(); i++) {
|
||||
vm->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
|
||||
ctx->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
|
||||
}
|
||||
} break;
|
||||
|
||||
case 47: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
|
||||
switch (arg1) {
|
||||
case 0:
|
||||
vm->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
|
||||
ctx->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
vm->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
|
||||
ctx->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
vm->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
|
||||
ctx->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
vm->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
|
||||
ctx->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
vm->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
|
||||
ctx->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2824,7 +2819,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
break;
|
||||
|
||||
case 48: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
|
||||
switch (arg1) {
|
||||
case 0:
|
||||
@@ -2866,51 +2861,51 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 49: {
|
||||
arg1 = vm->pop32();
|
||||
arg2 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
arg2 = ctx->pop32();
|
||||
|
||||
warning("Do save-load %d %d", arg1, arg2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 50:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
PTR_00417388 = _thing2[arg1].field_0.data();
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 51:
|
||||
PTR_00417388 = nullptr;
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 52:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
/* HELP */
|
||||
//FUN_0040c614(arg1);
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 53: {
|
||||
arg1 = vm->pop32();
|
||||
VM::ValAddr adr = vm->popReg();
|
||||
uint kode = vm->getMem8(adr);
|
||||
arg1 = ctx->pop32();
|
||||
VM::ValAddr adr = ctx->popReg();
|
||||
uint kode = ctx->getMem8(adr);
|
||||
_messageProc._keyCodes[arg1] = kode;
|
||||
vm->EAX.setVal(kode);
|
||||
ctx->EAX.setVal(kode);
|
||||
} break;
|
||||
|
||||
case 54:
|
||||
arg1 = vm->pop32();
|
||||
vm->EAX.setVal(rndRange16(arg1));
|
||||
arg1 = ctx->pop32();
|
||||
ctx->EAX.setVal(rndRange16(arg1));
|
||||
break;
|
||||
|
||||
case 55: {
|
||||
VM::ValAddr regRef = vm->popReg(); //implement
|
||||
Common::String str = vm->getString(regRef);
|
||||
VM::ValAddr regRef = ctx->popReg(); //implement
|
||||
Common::String str = ctx->getString(regRef);
|
||||
|
||||
char buffer[256];
|
||||
int a = 0, b = 0, c = 0, d = 0;
|
||||
@@ -2928,52 +2923,52 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
scriptFunc16(_midiTrack);
|
||||
}
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 56: {
|
||||
VM::ValAddr regRef = vm->popReg(); //implement
|
||||
Common::String str = vm->getString(regRef);
|
||||
VM::ValAddr regRef = ctx->popReg(); //implement
|
||||
Common::String str = ctx->getString(regRef);
|
||||
warning("Create process: %s", str.c_str());
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 57: {
|
||||
VM::ValAddr regRef = vm->popReg(); //implement
|
||||
Common::String str = vm->getString(regRef);
|
||||
VM::ValAddr regRef = ctx->popReg(); //implement
|
||||
Common::String str = ctx->getString(regRef);
|
||||
if (_keySeq.find(str) != Common::String::npos) {
|
||||
_keySeq.clear();
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} else
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
} break;
|
||||
|
||||
case 58: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
/* CD AUDIO */
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 59: {
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
/* CD AUDIO */
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
case 60:
|
||||
arg1 = vm->pop32();
|
||||
arg1 = ctx->pop32();
|
||||
if (arg1 == 0)
|
||||
_scrollTrackObj = -1;
|
||||
else
|
||||
_scrollTrackObj = _curObjIndex;
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
break;
|
||||
|
||||
case 61: {
|
||||
arg1 = vm->pop32();
|
||||
VM::ValAddr adr = vm->popReg();
|
||||
Common::String tmp = vm->getString(adr);
|
||||
arg1 = ctx->pop32();
|
||||
VM::ValAddr adr = ctx->popReg();
|
||||
Common::String tmp = ctx->getString(adr);
|
||||
|
||||
int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
|
||||
sscanf(tmp.c_str(), "%d %d %d %d", &val1, &val2, &val3, &val4);
|
||||
@@ -2988,19 +2983,19 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
|
||||
_scrollCutoff = val2;
|
||||
_scrollSpeedReduce = val3;
|
||||
}
|
||||
vm->EAX.setVal(1);
|
||||
ctx->EAX.setVal(1);
|
||||
} break;
|
||||
|
||||
default:
|
||||
warning("Call Dispatcher %d", funcID);
|
||||
vm->EAX.setVal(0);
|
||||
ctx->EAX.setVal(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GamosEngine::callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID) {
|
||||
void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint32 funcID) {
|
||||
GamosEngine *gamos = (GamosEngine *)engine;
|
||||
gamos->vmCallDispatcher(vm, funcID);
|
||||
gamos->vmCallDispatcher(ctx, funcID);
|
||||
}
|
||||
|
||||
uint32 GamosEngine::scriptFunc19(uint32 id) {
|
||||
@@ -3353,25 +3348,25 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
|
||||
void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
|
||||
removeSubtitles(PTR_00417218);
|
||||
PTR_00417218->fld_3 |= 2;
|
||||
|
||||
while (true) {
|
||||
uint8 ib = vm->getMem8(memtype, offset);
|
||||
uint8 ib = ctx->getMem8(memtype, offset);
|
||||
offset++;
|
||||
|
||||
if (ib == 0)
|
||||
break;
|
||||
|
||||
if (ib == 0xf) {
|
||||
byte flg = vm->getMem8(memtype, offset);
|
||||
byte flg = ctx->getMem8(memtype, offset);
|
||||
offset++;
|
||||
byte b2 = vm->getMem8(memtype, offset);
|
||||
byte b2 = ctx->getMem8(memtype, offset);
|
||||
offset++;
|
||||
|
||||
if ((flg & 0x70) == 0x20) {
|
||||
byte funcid = vm->getMem8(memtype, offset);
|
||||
byte funcid = ctx->getMem8(memtype, offset);
|
||||
offset++;
|
||||
warning("CHECKIT and write funcid %d", funcid);
|
||||
} else {
|
||||
@@ -3383,37 +3378,37 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
|
||||
btp = VM::REF_EBX;
|
||||
|
||||
if ((flg & 0x80) == 0) {
|
||||
boff = vm->getMem8(memtype, offset);
|
||||
boff = ctx->getMem8(memtype, offset);
|
||||
offset++;
|
||||
} else {
|
||||
boff = vm->getMem32(memtype, offset);
|
||||
boff = ctx->getMem32(memtype, offset);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
Common::String tmp;
|
||||
switch (flg & 7) {
|
||||
case 0:
|
||||
tmp = gamos_itoa((int32)(int8)vm->getMem8(btp, boff), 10);
|
||||
tmp = gamos_itoa((int32)(int8)ctx->getMem8(btp, boff), 10);
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
VM::ValAddr addr;
|
||||
addr.setVal( vm->getMem32(btp, boff) );
|
||||
tmp = vm->getString(addr, b2);
|
||||
addr.setVal( ctx->getMem32(btp, boff) );
|
||||
tmp = ctx->getString(addr, b2);
|
||||
} break;
|
||||
|
||||
case 2:
|
||||
tmp = vm->getString(btp, boff, b2);
|
||||
tmp = ctx->getString(btp, boff, b2);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
tmp = gamos_itoa(vm->getMem32(btp, boff), 10);
|
||||
tmp = gamos_itoa(ctx->getMem32(btp, boff), 10);
|
||||
break;
|
||||
|
||||
case 4: {
|
||||
VM::ValAddr addr;
|
||||
addr.setVal( vm->getMem32(btp, boff) );
|
||||
tmp = gamos_itoa(vm->getMem32(addr), 10);
|
||||
addr.setVal( ctx->getMem32(btp, boff) );
|
||||
tmp = gamos_itoa(ctx->getMem32(addr), 10);
|
||||
} break;
|
||||
|
||||
case 5:
|
||||
@@ -3457,27 +3452,27 @@ Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32
|
||||
|
||||
bool GamosEngine::FUN_00402bc4() {
|
||||
if (RawKeyCode == ACT_NONE) {
|
||||
VM::memory().setU8(_addrKeyCode, 0);
|
||||
VM::memory().setU8(_addrKeyDown, 0);
|
||||
_vm.memory().setU8(_addrKeyCode, 0);
|
||||
_vm.memory().setU8(_addrKeyDown, 0);
|
||||
} else {
|
||||
VM::memory().setU8(_addrKeyCode, RawKeyCode);
|
||||
VM::memory().setU8(_addrKeyDown, 1);
|
||||
_vm.memory().setU8(_addrKeyCode, RawKeyCode);
|
||||
_vm.memory().setU8(_addrKeyDown, 1);
|
||||
}
|
||||
|
||||
if (VM::memory().getU8(_addrBlk12) != 0)
|
||||
if (_vm.memory().getU8(_addrBlk12) != 0)
|
||||
return false;
|
||||
|
||||
uint32 frameval = VM::memory().getU32(_addrCurrentFrame);
|
||||
VM::memory().setU32(_addrCurrentFrame, frameval + 1);
|
||||
uint32 frameval = _vm.memory().getU32(_addrCurrentFrame);
|
||||
_vm.memory().setU32(_addrCurrentFrame, frameval + 1);
|
||||
|
||||
uint8 fpsval = VM::memory().getU8(_addrFPS);
|
||||
uint8 fpsval = _vm.memory().getU8(_addrFPS);
|
||||
|
||||
if (fpsval == 0) {
|
||||
fpsval = 1;
|
||||
VM::memory().setU8(_addrFPS, 1);
|
||||
_vm.memory().setU8(_addrFPS, 1);
|
||||
} else if (fpsval > 50) {
|
||||
fpsval = 50;
|
||||
VM::memory().setU8(_addrFPS, 50);
|
||||
_vm.memory().setU8(_addrFPS, 50);
|
||||
}
|
||||
|
||||
if (fpsval != _fps) {
|
||||
@@ -4201,7 +4196,7 @@ bool GamosEngine::FUN_0040705c(int a, int b) {
|
||||
return ((a + v * 2) & 7) == b;
|
||||
}
|
||||
|
||||
int GamosEngine::txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
|
||||
int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
|
||||
if (memtype != VM::REF_EDI) {
|
||||
error("Unsupported memtype");
|
||||
return 0;
|
||||
@@ -4242,7 +4237,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
}
|
||||
_txtInputActive = true;
|
||||
_txtInputTyped = false;
|
||||
ib = VM::memory().getU8(_txtInputVmOffset);
|
||||
ib = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
continue;
|
||||
} else if (ib == KeyCodes::WIN_BACK) {
|
||||
@@ -4260,7 +4255,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
VmTxtFmtAccess adr;
|
||||
VmTxtFmtAccess adr(_vm);
|
||||
adr.setVal( _txtInputVMAccess.getU32() );
|
||||
adr.write(_txtInputBuffer, _txtInputLength + 1);
|
||||
} break;
|
||||
@@ -4274,21 +4269,21 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
break;
|
||||
|
||||
case 4: {
|
||||
VmTxtFmtAccess adr;
|
||||
VmTxtFmtAccess adr(_vm);
|
||||
adr.setVal( _txtInputVMAccess.getU32() );
|
||||
adr.setU32( atoi((char *)_txtInputBuffer) );
|
||||
} break;
|
||||
}
|
||||
|
||||
_txtInputTyped = false;
|
||||
ib = VM::memory().getU8(_txtInputVmOffset);
|
||||
ib = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
continue;
|
||||
}
|
||||
} else if (ib == 0xf) {
|
||||
_txtInputFlags = VM::memory().getU8(_txtInputVmOffset);
|
||||
_txtInputFlags = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
_txtInputMaxLength = VM::memory().getU8(_txtInputVmOffset);
|
||||
_txtInputMaxLength = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
|
||||
if ((_txtInputFlags & 0x70) == 0 || (_txtInputFlags & 0x70) == 0x10) {
|
||||
@@ -4298,10 +4293,10 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
_txtInputVMAccess.objMem = PTR_004173e8;
|
||||
}
|
||||
if ( (_txtInputFlags & 0x80) == 0 ) {
|
||||
_txtInputVMAccess.setOffset( VM::memory().getU8(_txtInputVmOffset) );
|
||||
_txtInputVMAccess.setOffset( _vm.memory().getU8(_txtInputVmOffset) );
|
||||
_txtInputVmOffset++;
|
||||
} else {
|
||||
_txtInputVMAccess.setOffset( VM::memory().getU32(_txtInputVmOffset) );
|
||||
_txtInputVMAccess.setOffset( _vm.memory().getU32(_txtInputVmOffset) );
|
||||
_txtInputVmOffset += 4;
|
||||
}
|
||||
switch (_txtInputFlags & 7) {
|
||||
@@ -4335,7 +4330,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
}
|
||||
_txtInputActive = true;
|
||||
_txtInputTyped = false;
|
||||
ib = VM::memory().getU8(_txtInputVmOffset);
|
||||
ib = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
continue;
|
||||
}
|
||||
@@ -4357,7 +4352,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
|
||||
return;
|
||||
} else {
|
||||
addSubtitleImage(ib, _txtInputSpriteID, &_txtInputX, _txtInputY);
|
||||
ib = VM::memory().getU8(_txtInputVmOffset);
|
||||
ib = _vm.memory().getU8(_txtInputVmOffset);
|
||||
_txtInputVmOffset++;
|
||||
}
|
||||
}
|
||||
@@ -4422,12 +4417,12 @@ void GamosEngine::dumpActions() {
|
||||
for (ObjectAction &act : _objectActions) {
|
||||
f.writeString(Common::String::format("Act %d : %x\n", i, act.unk1));
|
||||
if (act.onCreateAddress != -1) {
|
||||
t = VM::disassembly(act.onCreateAddress);
|
||||
t = _vm.disassembly(act.onCreateAddress);
|
||||
f.writeString(Common::String::format("Script1 : \n%s\n", t.c_str()));
|
||||
}
|
||||
|
||||
if (act.onDeleteAddress != -1) {
|
||||
t = VM::disassembly(act.onDeleteAddress);
|
||||
t = _vm.disassembly(act.onDeleteAddress);
|
||||
f.writeString(Common::String::format("Script2 : \n%s\n", t.c_str()));
|
||||
}
|
||||
|
||||
@@ -4436,12 +4431,12 @@ void GamosEngine::dumpActions() {
|
||||
f.writeString(Common::String::format("subscript %d : \n", j));
|
||||
|
||||
if (sc.conditionAddress != -1) {
|
||||
t = VM::disassembly(sc.conditionAddress);
|
||||
t = _vm.disassembly(sc.conditionAddress);
|
||||
f.writeString(Common::String::format("condition : \n%s\n", t.c_str()));
|
||||
}
|
||||
|
||||
if (sc.functionAddress != -1) {
|
||||
t = VM::disassembly(sc.functionAddress);
|
||||
t = _vm.disassembly(sc.functionAddress);
|
||||
f.writeString(Common::String::format("action : \n%s\n", t.c_str()));
|
||||
}
|
||||
|
||||
@@ -4457,12 +4452,12 @@ void GamosEngine::dumpActions() {
|
||||
i = 0;
|
||||
for (const Actions &act : _subtitleActions) {
|
||||
if (act.flags & Actions::HAS_CONDITION) {
|
||||
t = VM::disassembly(act.conditionAddress);
|
||||
t = _vm.disassembly(act.conditionAddress);
|
||||
f.writeString(Common::String::format("SubAct %d condition : \n%s\n", i, t.c_str()));
|
||||
}
|
||||
|
||||
if (act.flags & Actions::HAS_FUNCTION) {
|
||||
t = VM::disassembly(act.functionAddress);
|
||||
t = _vm.disassembly(act.functionAddress);
|
||||
f.writeString(Common::String::format("SubAct %d action : \n%s\n", i, t.c_str()));
|
||||
}
|
||||
|
||||
|
||||
@@ -254,6 +254,8 @@ struct GameScreen {
|
||||
};
|
||||
|
||||
struct VmTxtFmtAccess : VM::ValAddr {
|
||||
VmTxtFmtAccess(VM &vm): _vm(vm) {};
|
||||
VM &_vm;
|
||||
byte *objMem = nullptr;
|
||||
|
||||
inline bool isObjMem() const { return getMemType() == VM::REF_EBX;}
|
||||
@@ -266,40 +268,40 @@ struct VmTxtFmtAccess : VM::ValAddr {
|
||||
return s;
|
||||
}
|
||||
|
||||
return VM::readMemString(getOffset(), maxLen);
|
||||
return _vm.readMemString(getOffset(), maxLen);
|
||||
}
|
||||
|
||||
inline uint8 getU8() const {
|
||||
if (isObjMem())
|
||||
return objMem[getOffset()];
|
||||
return VM::memory().getU8(getOffset());
|
||||
return _vm.memory().getU8(getOffset());
|
||||
}
|
||||
|
||||
inline uint32 getU32() const {
|
||||
if (isObjMem())
|
||||
return VM::getU32(objMem + getOffset());
|
||||
return VM::memory().getU32(getOffset());
|
||||
return _vm.getU32(objMem + getOffset());
|
||||
return _vm.memory().getU32(getOffset());
|
||||
}
|
||||
|
||||
inline void write(byte *src, uint len) {
|
||||
if (isObjMem())
|
||||
memcpy(objMem + getOffset(), src, len);
|
||||
else
|
||||
VM::writeMemory(getOffset(), src, len);
|
||||
_vm.writeMemory(getOffset(), src, len);
|
||||
}
|
||||
|
||||
inline void setU8(uint8 v) {
|
||||
if (isObjMem())
|
||||
objMem[getOffset()] = v;
|
||||
else
|
||||
VM::memory().setU8(getOffset(), v);
|
||||
_vm.memory().setU8(getOffset(), v);
|
||||
}
|
||||
|
||||
inline void setU32(uint32 v) {
|
||||
if (isObjMem())
|
||||
VM::setU32(objMem + getOffset(), v);
|
||||
_vm.setU32(objMem + getOffset(), v);
|
||||
else
|
||||
VM::memory().setU32(getOffset(), v);
|
||||
_vm.memory().setU32(getOffset(), v);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -534,6 +536,8 @@ private:
|
||||
|
||||
Common::Array<Common::Rect> _dirtyRects;
|
||||
|
||||
VM _vm;
|
||||
|
||||
bool _needReload = false;
|
||||
|
||||
protected:
|
||||
@@ -663,11 +667,11 @@ protected:
|
||||
|
||||
void setNeedReload() {
|
||||
_needReload = true;
|
||||
VM::_interrupt = true;
|
||||
_vm._interrupt = true;
|
||||
};
|
||||
|
||||
Object *addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y);
|
||||
void addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
|
||||
void addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
|
||||
|
||||
void FUN_00407db8(uint8 p);
|
||||
byte FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
|
||||
@@ -690,7 +694,7 @@ protected:
|
||||
void FUN_004025d0();
|
||||
bool FUN_0040705c(int a, int b);
|
||||
|
||||
int txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y);
|
||||
int txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int sprId, int32 x, int32 y);
|
||||
void txtInputProcess(uint8 c);
|
||||
void txtInputEraseBack(int n);
|
||||
|
||||
@@ -713,12 +717,12 @@ protected:
|
||||
bool loadStateFile();
|
||||
void loadStateData(Common::SeekableReadStream *stream);
|
||||
|
||||
void vmCallDispatcher(VM *vm, uint32 funcID);
|
||||
void vmCallDispatcher(VM::Context *ctx, uint32 funcID);
|
||||
|
||||
|
||||
void dumpActions();
|
||||
|
||||
static void callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID);
|
||||
static void callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint32 funcID);
|
||||
|
||||
|
||||
static Common::String gamos_itoa(int value, uint radix);
|
||||
|
||||
+3
-3
@@ -276,7 +276,7 @@ void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
|
||||
|
||||
void GamosEngine::writeVMData(Common::SeekableWriteStream *stream, const Common::Array<XorArg> &seq) {
|
||||
for (const XorArg &xarg : seq) {
|
||||
Common::Array<byte> tmp = VM::readMemBlocks(xarg.pos, xarg.len);
|
||||
Common::Array<byte> tmp = _vm.readMemBlocks(xarg.pos, xarg.len);
|
||||
|
||||
//xor data in tmp
|
||||
//...
|
||||
@@ -296,13 +296,13 @@ void GamosEngine::readVMData(Common::SeekableReadStream *stream, const Common::A
|
||||
//...
|
||||
|
||||
// and write it
|
||||
VM::writeMemory(xarg.pos, buf.data(), xarg.len);
|
||||
_vm.writeMemory(xarg.pos, buf.data(), xarg.len);
|
||||
}
|
||||
}
|
||||
|
||||
void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
|
||||
for (const XorArg &xarg : seq)
|
||||
VM::zeroMemory(xarg.pos, xarg.len);
|
||||
_vm.zeroMemory(xarg.pos, xarg.len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,23 +23,9 @@
|
||||
|
||||
namespace Gamos {
|
||||
|
||||
VM::CallDispatcher VM::_callFuncs = nullptr;
|
||||
void *VM::_callingObject = nullptr;
|
||||
|
||||
Common::HashMap<uint32, VM::MemoryBlock> VM::_memMap;
|
||||
bool VM::_interrupt = false;
|
||||
|
||||
VM VM::_threads[THREADS_COUNT];
|
||||
|
||||
VM::MemAccess VM::_memAccess;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint8 VM::MemAccess::getU8(uint32 address) {
|
||||
if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
|
||||
_currentBlock = findMemoryBlock(address);
|
||||
_currentBlock = _vm.findMemoryBlock(address);
|
||||
|
||||
if (!_currentBlock)
|
||||
return 0; // ERROR!
|
||||
@@ -49,7 +35,7 @@ uint8 VM::MemAccess::getU8(uint32 address) {
|
||||
|
||||
uint32 VM::MemAccess::getU32(uint32 address) {
|
||||
if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
|
||||
_currentBlock = findMemoryBlock(address);
|
||||
_currentBlock = _vm.findMemoryBlock(address);
|
||||
|
||||
if (!_currentBlock)
|
||||
return 0; // ERROR!
|
||||
@@ -63,7 +49,7 @@ uint32 VM::MemAccess::getU32(uint32 address) {
|
||||
for (int i = 1; i < 4; i++) {
|
||||
pos++;
|
||||
if (pos >= 0x100) {
|
||||
block = findMemoryBlock(address + i);
|
||||
block = _vm.findMemoryBlock(address + i);
|
||||
if (!block)
|
||||
break;
|
||||
pos = 0;
|
||||
@@ -76,20 +62,20 @@ uint32 VM::MemAccess::getU32(uint32 address) {
|
||||
|
||||
void VM::MemAccess::setU8(uint32 address, uint8 val) {
|
||||
if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
|
||||
_currentBlock = findMemoryBlock(address);
|
||||
_currentBlock = _vm.findMemoryBlock(address);
|
||||
|
||||
if (!_currentBlock)
|
||||
_currentBlock = createBlock(address);
|
||||
_currentBlock = _vm.createBlock(address);
|
||||
|
||||
_currentBlock->data[ address - _currentBlock->address ] = val;
|
||||
}
|
||||
|
||||
void VM::MemAccess::setU32(uint32 address, uint32 val) {
|
||||
if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
|
||||
_currentBlock = findMemoryBlock(address);
|
||||
_currentBlock = _vm.findMemoryBlock(address);
|
||||
|
||||
if (!_currentBlock)
|
||||
_currentBlock = createBlock(address);
|
||||
_currentBlock = _vm.createBlock(address);
|
||||
|
||||
uint32 pos = address - _currentBlock->address;
|
||||
|
||||
@@ -105,7 +91,7 @@ void VM::MemAccess::setU32(uint32 address, uint32 val) {
|
||||
for (int i = 1; i < 4; i++) {
|
||||
pos++;
|
||||
if (pos >= 0x100) {
|
||||
block = createBlock(address + i);
|
||||
block = _vm.createBlock(address + i);
|
||||
if (!block)
|
||||
break;
|
||||
pos = 0;
|
||||
@@ -118,7 +104,7 @@ void VM::MemAccess::setU32(uint32 address, uint32 val) {
|
||||
|
||||
|
||||
|
||||
uint32 VM::execute(uint32 scriptAddress, byte *storage) {
|
||||
uint32 VM::Context::execute(uint32 scriptAddress, byte *storage) {
|
||||
//Common::String disasm = disassembly(scriptAddress);
|
||||
|
||||
ESI = scriptAddress;
|
||||
@@ -133,7 +119,7 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
|
||||
|
||||
bool loop = true;
|
||||
while (loop) {
|
||||
if (_interrupt)
|
||||
if (_vm._interrupt)
|
||||
return 0;
|
||||
|
||||
byte op = _readAccess.getU8(ESI);
|
||||
@@ -415,8 +401,8 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
|
||||
case OP_CALL_FUNC:
|
||||
EAX.setVal( _readAccess.getU32(ESI) );
|
||||
ESI += 4;
|
||||
if (_callFuncs)
|
||||
_callFuncs(_callingObject, this, EAX.getVal());
|
||||
if (_vm._callFuncs)
|
||||
_vm._callFuncs(_vm._callingObject, this, EAX.getVal());
|
||||
break;
|
||||
|
||||
case OP_PUSH_ESI_SET_EDX_EDI:
|
||||
@@ -443,7 +429,7 @@ uint32 VM::doScript(uint32 scriptAddress, byte *storage) {
|
||||
}
|
||||
}
|
||||
|
||||
VM *tmpcontext = new VM();
|
||||
Context *tmpcontext = new Context(*this);
|
||||
uint32 res = tmpcontext->execute(scriptAddress, storage);
|
||||
delete tmpcontext;
|
||||
return res;
|
||||
@@ -469,30 +455,30 @@ void VM::setU32(void *mem, uint32 val) {
|
||||
mem8[3] = (val >> 24) & 0xff;
|
||||
}
|
||||
|
||||
void VM::push32(uint32 val) {
|
||||
void VM::Context::push32(uint32 val) {
|
||||
SP -= 4;
|
||||
setU32(_stack + SP, val);
|
||||
}
|
||||
|
||||
uint32 VM::pop32() {
|
||||
uint32 VM::Context::pop32() {
|
||||
uint32 val = getU32(_stack + SP);
|
||||
SP += 4;
|
||||
return val;
|
||||
}
|
||||
|
||||
void VM::pushReg(ValAddr reg) {
|
||||
void VM::Context::pushReg(ValAddr reg) {
|
||||
SP -= 4;
|
||||
setU32(_stack + SP, reg.getVal());
|
||||
}
|
||||
|
||||
VM::ValAddr VM::popReg() {
|
||||
VM::ValAddr VM::Context::popReg() {
|
||||
ValAddr tmp;
|
||||
tmp.setVal( getU32(_stack + SP) );
|
||||
SP += 4;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32 VM::getMem32(int memtype, uint32 offset) {
|
||||
uint32 VM::Context::getMem32(int memtype, uint32 offset) {
|
||||
switch (memtype) {
|
||||
default:
|
||||
case REF_UNK:
|
||||
@@ -509,11 +495,11 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 VM::getMem32(const ValAddr &addr) {
|
||||
uint32 VM::Context::getMem32(const ValAddr &addr) {
|
||||
return getMem32(addr.getMemType(), addr.getOffset());
|
||||
}
|
||||
|
||||
uint8 VM::getMem8(int memtype, uint32 offset) {
|
||||
uint8 VM::Context::getMem8(int memtype, uint32 offset) {
|
||||
switch (memtype) {
|
||||
default:
|
||||
case REF_UNK:
|
||||
@@ -530,11 +516,11 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8 VM::getMem8(const ValAddr &addr) {
|
||||
uint8 VM::Context::getMem8(const ValAddr &addr) {
|
||||
return getMem8(addr.getMemType(), addr.getOffset());
|
||||
}
|
||||
|
||||
void VM::setMem32(int memtype, uint32 offset, uint32 val) {
|
||||
void VM::Context::setMem32(int memtype, uint32 offset, uint32 val) {
|
||||
switch (memtype) {
|
||||
default:
|
||||
case REF_UNK:
|
||||
@@ -552,11 +538,11 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
|
||||
}
|
||||
}
|
||||
|
||||
void VM::setMem32(const ValAddr &addr, uint32 val) {
|
||||
void VM::Context::setMem32(const ValAddr &addr, uint32 val) {
|
||||
setMem32(addr.getMemType(), addr.getOffset(), val);
|
||||
}
|
||||
|
||||
void VM::setMem8(int memtype, uint32 offset, uint8 val) {
|
||||
void VM::Context::setMem8(int memtype, uint32 offset, uint8 val) {
|
||||
switch (memtype) {
|
||||
default:
|
||||
case REF_UNK:
|
||||
@@ -574,7 +560,7 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
|
||||
}
|
||||
}
|
||||
|
||||
void VM::setMem8(const ValAddr &addr, uint8 val) {
|
||||
void VM::Context::setMem8(const ValAddr &addr, uint8 val) {
|
||||
setMem8(addr.getMemType(), addr.getOffset(), val);
|
||||
}
|
||||
|
||||
@@ -706,7 +692,7 @@ Common::String VM::readMemString(uint32 address, uint32 maxLen) {
|
||||
return s;
|
||||
}
|
||||
|
||||
Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
|
||||
Common::String VM::Context::getString(int memtype, uint32 offset, uint32 maxLen) {
|
||||
switch (memtype) {
|
||||
default:
|
||||
case REF_UNK:
|
||||
@@ -726,11 +712,11 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
|
||||
}
|
||||
|
||||
case REF_EDI:
|
||||
return readMemString(offset, maxLen);
|
||||
return _vm.readMemString(offset, maxLen);
|
||||
}
|
||||
}
|
||||
|
||||
Common::String VM::getString(const ValAddr &addr, uint32 maxLen) {
|
||||
Common::String VM::Context::getString(const ValAddr &addr, uint32 maxLen) {
|
||||
return getString(addr.getMemType(), addr.getOffset(), maxLen);
|
||||
}
|
||||
|
||||
@@ -738,7 +724,7 @@ Common::String VM::getString(const ValAddr &addr, uint32 maxLen) {
|
||||
Common::String VM::decodeOp(uint32 address, int *size) {
|
||||
Common::String tmp;
|
||||
|
||||
MemAccess readmem;
|
||||
MemAccess readmem(*this);
|
||||
|
||||
int sz = 1;
|
||||
byte op = readmem.getU8(address);
|
||||
@@ -998,7 +984,7 @@ Common::String VM::disassembly(uint32 address) {
|
||||
Common::String tmp;
|
||||
|
||||
uint32 addr = address;
|
||||
MemAccess readmem;
|
||||
MemAccess readmem(*this);
|
||||
|
||||
while (true) {
|
||||
tmp += Common::String::format("%08x: ", addr);
|
||||
|
||||
@@ -117,8 +117,6 @@ public:
|
||||
inline void setAddress(uint tp, uint32 offset) { value = (offset & ADDRESS_MASK) | ((tp & 3) << MEMTYPE_SHIFT); };
|
||||
};
|
||||
|
||||
typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
|
||||
|
||||
struct MemoryBlock {
|
||||
uint32 address = 0;
|
||||
byte data[256];
|
||||
@@ -136,6 +134,9 @@ public:
|
||||
};
|
||||
|
||||
struct MemAccess {
|
||||
MemAccess(VM &vm): _vm(vm) {};
|
||||
|
||||
VM &_vm;
|
||||
MemoryBlock *_currentBlock = nullptr;
|
||||
|
||||
uint8 getU8(uint32 address);
|
||||
@@ -149,85 +150,100 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context(VM &vm): _vm(vm), _readAccess(vm), _writeAccess(vm) {};
|
||||
|
||||
Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
|
||||
Common::String getString(const ValAddr &addr, uint32 maxLen = 256);
|
||||
|
||||
uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
|
||||
|
||||
void push32(uint32 val);
|
||||
uint32 pop32();
|
||||
|
||||
void pushReg(ValAddr reg);
|
||||
ValAddr popReg();
|
||||
|
||||
uint32 getMem32(int memtype, uint32 offset);
|
||||
uint32 getMem32(const ValAddr& addr);
|
||||
uint8 getMem8(int memtype, uint32 offset);
|
||||
uint8 getMem8(const ValAddr& addr);
|
||||
|
||||
void setMem32(int memtype, uint32 offset, uint32 val);
|
||||
void setMem32(const ValAddr& addr, uint32 val);
|
||||
void setMem8(int memtype, uint32 offset, uint8 val);
|
||||
void setMem8(const ValAddr& addr, uint8 val);
|
||||
|
||||
public:
|
||||
VM &_vm;
|
||||
bool _inUse = false;
|
||||
|
||||
uint32 ESI = 0;
|
||||
byte *EBX = nullptr;
|
||||
ValAddr EAX;
|
||||
ValAddr EDX;
|
||||
ValAddr ECX;
|
||||
uint32 SP = 0;
|
||||
byte _stack[STACK_SIZE];
|
||||
|
||||
private:
|
||||
MemAccess _readAccess;
|
||||
MemAccess _writeAccess;
|
||||
};
|
||||
|
||||
typedef void (* CallDispatcher)(void *object, Context *state, uint32 funcID);
|
||||
|
||||
public:
|
||||
inline static MemAccess &memory() {
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
VM(void *obj, CallDispatcher dispatcher): _memAccess(*this), _threads{*this, *this}, _callFuncs(dispatcher), _callingObject(obj) {};
|
||||
|
||||
inline MemAccess &memory() {
|
||||
return _memAccess;
|
||||
};
|
||||
|
||||
static void clearMemory();
|
||||
static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
|
||||
void clearMemory();
|
||||
void writeMemory(uint32 address, const byte* data, uint32 dataSize);
|
||||
|
||||
static void zeroMemory(uint32 address, uint32 count);
|
||||
void zeroMemory(uint32 address, uint32 count);
|
||||
|
||||
static MemoryBlock *findMemoryBlock(uint32 address);
|
||||
MemoryBlock *findMemoryBlock(uint32 address);
|
||||
|
||||
static MemoryBlock *createBlock(uint32 address);
|
||||
MemoryBlock *createBlock(uint32 address);
|
||||
|
||||
static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
|
||||
static void readMemBlocks(byte *dst, uint32 address, uint32 count);
|
||||
Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
|
||||
void readMemBlocks(byte *dst, uint32 address, uint32 count);
|
||||
|
||||
static Common::String readMemString(uint32 address, uint32 maxLen = 256);
|
||||
Common::String readMemString(uint32 address, uint32 maxLen = 256);
|
||||
|
||||
Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
|
||||
Common::String getString(const ValAddr &addr, uint32 maxLen = 256);
|
||||
|
||||
uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
|
||||
|
||||
static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
|
||||
uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
|
||||
|
||||
static int32 getS32(const void *);
|
||||
static uint32 getU32(const void *);
|
||||
static void setU32(void *, uint32 val);
|
||||
|
||||
void push32(uint32 val);
|
||||
uint32 pop32();
|
||||
Common::String decodeOp(uint32 address, int *size = nullptr);
|
||||
Common::String disassembly(uint32 address);
|
||||
|
||||
void pushReg(ValAddr reg);
|
||||
ValAddr popReg();
|
||||
Common::String opLog(const Common::Array<OpLog> &log);
|
||||
|
||||
uint32 getMem32(int memtype, uint32 offset);
|
||||
uint32 getMem32(const ValAddr& addr);
|
||||
uint8 getMem8(int memtype, uint32 offset);
|
||||
uint8 getMem8(const ValAddr& addr);
|
||||
void printDisassembly(uint32 address);
|
||||
|
||||
void setMem32(int memtype, uint32 offset, uint32 val);
|
||||
void setMem32(const ValAddr& addr, uint32 val);
|
||||
void setMem8(int memtype, uint32 offset, uint8 val);
|
||||
void setMem8(const ValAddr& addr, uint8 val);
|
||||
protected:
|
||||
Common::HashMap<uint32, MemoryBlock> _memMap;
|
||||
|
||||
static Common::String decodeOp(uint32 address, int *size = nullptr);
|
||||
static Common::String disassembly(uint32 address);
|
||||
MemAccess _memAccess;
|
||||
|
||||
static Common::String opLog(const Common::Array<OpLog> &log);
|
||||
Context _threads[THREADS_COUNT];
|
||||
|
||||
static void printDisassembly(uint32 address);
|
||||
|
||||
private:
|
||||
CallDispatcher const _callFuncs = nullptr;
|
||||
void * const _callingObject = nullptr;
|
||||
|
||||
public:
|
||||
bool _inUse = false;
|
||||
|
||||
uint32 ESI = 0;
|
||||
byte *EBX = nullptr;
|
||||
ValAddr EAX;
|
||||
ValAddr EDX;
|
||||
ValAddr ECX;
|
||||
uint32 SP = 0;
|
||||
byte _stack[STACK_SIZE];
|
||||
|
||||
private:
|
||||
MemAccess _readAccess;
|
||||
MemAccess _writeAccess;
|
||||
|
||||
public:
|
||||
static CallDispatcher _callFuncs;
|
||||
static void *_callingObject;
|
||||
|
||||
static Common::HashMap<uint32, MemoryBlock> _memMap;
|
||||
static bool _interrupt;
|
||||
|
||||
static VM _threads[THREADS_COUNT];
|
||||
static MemAccess _memAccess;
|
||||
bool _interrupt = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user