GAMOS: Change of VM class for eliminating global objects

This commit is contained in:
Marisa-Chan
2025-11-10 14:55:18 +07:00
parent 48d0a9c19d
commit 19871cfeea
5 changed files with 327 additions and 326 deletions
+204 -209
View File
@@ -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()));
}
+17 -13
View File
@@ -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
View File
@@ -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);
}
}
+30 -44
View File
@@ -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);
+73 -57
View File
@@ -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;
};