mirror of
https://github.com/scummvm/gamos.git
synced 2026-05-21 05:40:53 +00:00
GAMOS: Add support loading games with engine version 0x12 and 0x0b
This commit is contained in:
@@ -37,7 +37,9 @@ bool Archive::open(const Common::Path &name) {
|
||||
|
||||
seek(-12, SEEK_END);
|
||||
|
||||
_dirOffset = 12 + readUint32LE();
|
||||
const uint32 dirInfSize = readUint32LE();
|
||||
|
||||
_dirOffset = 12 + dirInfSize;
|
||||
skip(4);
|
||||
uint32 magic = readUint32LE();
|
||||
|
||||
@@ -46,8 +48,16 @@ bool Archive::open(const Common::Path &name) {
|
||||
|
||||
seek(-_dirOffset, SEEK_END);
|
||||
|
||||
_dirCount = readUint32LE();
|
||||
_dataOffset = readUint32LE();
|
||||
byte tmpbuf[8] = {0, 0 ,0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* read it into buffer firs, because it's can be less than 8 bytes */
|
||||
if (dirInfSize > 8)
|
||||
read(tmpbuf, 8);
|
||||
else
|
||||
read(tmpbuf, dirInfSize);
|
||||
|
||||
_dirCount = READ_LE_UINT32(tmpbuf);
|
||||
_dataOffset = READ_LE_UINT32(tmpbuf + 4);
|
||||
|
||||
seek(-(_dirOffset + _dirCount * 5), SEEK_END);
|
||||
|
||||
@@ -141,12 +151,17 @@ bool Archive::readCompressedData(RawData *out) {
|
||||
/* read size */
|
||||
const byte szsize = (t & 3) + 1;
|
||||
|
||||
if (_version == 0xb)
|
||||
skip(szsize);
|
||||
|
||||
/* big data size */
|
||||
for (uint i = 0; i < szsize; ++i)
|
||||
_lastReadSize |= readByte() << (i << 3);
|
||||
|
||||
/* is compressed */
|
||||
if (t & 0xC) {
|
||||
if (_version == 0xb) {
|
||||
skip(szsize + 1);
|
||||
} else if (t & 0xC) {
|
||||
for (uint i = 0; i < szsize; ++i)
|
||||
_lastReadDecompressedSize |= readByte() << (i << 3);
|
||||
}
|
||||
@@ -159,7 +174,7 @@ bool Archive::readCompressedData(RawData *out) {
|
||||
out->resize(_lastReadSize);
|
||||
read(out->data(), _lastReadSize);
|
||||
|
||||
if (!_lastReadDecompressedSize)
|
||||
if (!_lastReadDecompressedSize || _version != 0x18)
|
||||
return true;
|
||||
|
||||
/* looks hacky but we just allocate array for decompressed and swap it with compressed */
|
||||
|
||||
@@ -61,6 +61,10 @@ public:
|
||||
|
||||
static void decompress(RawData const *in, RawData *out);
|
||||
|
||||
void setVersion(int v) {
|
||||
_version = v;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
uint32 _lastReadSize = 0;
|
||||
@@ -76,6 +80,8 @@ private:
|
||||
|
||||
Common::Array<ArchiveDir> _directories;
|
||||
|
||||
int _version = 0x18;
|
||||
|
||||
//bool _error;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,6 +86,10 @@ Common::Error GamosEngine::run() {
|
||||
else
|
||||
setCP1252();
|
||||
|
||||
_engineVersion = getEngineVersion() & 0xFF;
|
||||
|
||||
_arch.setVersion(_engineVersion);
|
||||
|
||||
init(getRunFile());
|
||||
|
||||
Common::Event e;
|
||||
@@ -564,30 +568,43 @@ bool GamosEngine::initMainDatas() {
|
||||
}
|
||||
|
||||
/* skip count of pages 1kb size */
|
||||
dataStream.skip(4);
|
||||
/* skip read buffer size */
|
||||
dataStream.skip(4);
|
||||
_width = dataStream.readUint32LE();
|
||||
_height = dataStream.readUint32LE();
|
||||
_gridCellW = dataStream.readSint32LE();
|
||||
_gridCellH = dataStream.readSint32LE();
|
||||
_movieCount = dataStream.readUint32LE();
|
||||
dataStream.skip(3); // skip unknown unused
|
||||
_fps = dataStream.readByte();
|
||||
dataStream.skip(1); // skip unknown unused
|
||||
_drawCursor = dataStream.readByte();
|
||||
_fadeEffectID = dataStream.readByte();
|
||||
_playIntro = dataStream.readByte();
|
||||
dataStream.skip(4); // 4
|
||||
if (_engineVersion >= 0x12) {
|
||||
/* skip read buffer size */
|
||||
dataStream.skip(4); // 8
|
||||
}
|
||||
_width = dataStream.readUint32LE(); // c
|
||||
_height = dataStream.readUint32LE(); // 10
|
||||
_gridCellW = dataStream.readSint32LE(); // 14
|
||||
_gridCellH = dataStream.readSint32LE(); // 18
|
||||
_movieCount = dataStream.readUint32LE(); // 1c
|
||||
dataStream.skip(3); // skip unknown unused 20
|
||||
_fps = dataStream.readByte(); // 23
|
||||
dataStream.skip(1); // skip unknown unused 24
|
||||
_drawCursor = dataStream.readByte(); // 25
|
||||
|
||||
_introPos.x = dataStream.readSint32LE();
|
||||
_introPos.y = dataStream.readSint32LE();
|
||||
_introSize.x = dataStream.readSint32LE();
|
||||
_introSize.y = dataStream.readSint32LE();
|
||||
if (_engineVersion >= 0x12) {
|
||||
_fadeEffectID = dataStream.readByte(); // 26
|
||||
_playIntro = dataStream.readByte(); // 27
|
||||
} else {
|
||||
_playIntro = dataStream.readByte();
|
||||
_fadeEffectID = dataStream.readByte();
|
||||
}
|
||||
|
||||
int64 pos = dataStream.pos();
|
||||
_string1 = dataStream.readString(0, 64);
|
||||
dataStream.seek(pos + 64);
|
||||
_winCaption = dataStream.readString(0, 9);
|
||||
if (_engineVersion >= 0x12) {
|
||||
_introPos.x = dataStream.readSint32LE(); // 28
|
||||
_introPos.y = dataStream.readSint32LE(); // 2c
|
||||
_introSize.x = dataStream.readSint32LE(); // 30
|
||||
_introSize.y = dataStream.readSint32LE(); // 34
|
||||
|
||||
int64 pos = dataStream.pos();
|
||||
_string1 = dataStream.readString(0, 64); // 38
|
||||
dataStream.seek(pos + 64);
|
||||
} else {
|
||||
_string1 = "";
|
||||
}
|
||||
|
||||
_winCaption = dataStream.readString(0, 32); // 78
|
||||
|
||||
if (!_screen) {
|
||||
initGraphics(_width, _height);
|
||||
@@ -1085,7 +1102,7 @@ void GamosEngine::readData2(const RawData &data) {
|
||||
|
||||
//warning("Game data size %d", data.size());
|
||||
|
||||
if (getEngineVersion() == 0x80000018) {
|
||||
if (_engineVersion == 0x18) {
|
||||
_stateExt = dataStream.readString(0, 4); // FIX ME
|
||||
dataStream.seek(4);
|
||||
_messageProc._inputFlags = dataStream.readByte(); //4
|
||||
@@ -1121,7 +1138,7 @@ void GamosEngine::readData2(const RawData &data) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
_messageProc._keyCodes[i] = dataStream.readByte();
|
||||
}
|
||||
} else if (getEngineVersion() == 0x80000016) {
|
||||
} else if (_engineVersion >= 0x12 && _engineVersion <= 0x16) {
|
||||
_stateExt = dataStream.readString(0, 4); // FIX ME
|
||||
dataStream.seek(4);
|
||||
_messageProc._inputFlags = dataStream.readByte(); //4
|
||||
@@ -1156,6 +1173,52 @@ void GamosEngine::readData2(const RawData &data) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
_messageProc._keyCodes[i] = dataStream.readByte();
|
||||
}
|
||||
} else if (_engineVersion == 0xb) {
|
||||
_stateExt = dataStream.readString(0, 4); // FIX ME
|
||||
dataStream.seek(4);
|
||||
_messageProc._inputFlags = dataStream.readByte(); //4
|
||||
dataStream.seek(8);
|
||||
_svModuleId = dataStream.readSint32LE(); // 8
|
||||
_svGameScreen = dataStream.readSint32LE(); // c
|
||||
_d2_fld10 = dataStream.readUint32LE(); // 10
|
||||
_enableSounds = dataStream.readByte() != 0 ? true : false; // x14
|
||||
_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
|
||||
_enableInput = dataStream.readByte() != 0 ? true : false; // x16
|
||||
_enableMovie = dataStream.readByte() != 0 ? true : false; // x17
|
||||
_enableCDAudio = false;
|
||||
_cdAudioTrack = -1;
|
||||
_scrollX = 0;
|
||||
_scrollY = 0;
|
||||
_scrollTrackObj = -1;
|
||||
_scrollSpeed = 16;
|
||||
_scrollCutoff = 80;
|
||||
_scrollSpeedReduce = -1;
|
||||
_scrollBorderL = 0;
|
||||
_scrollBorderR = 0;
|
||||
_scrollBorderU = 0;
|
||||
_scrollBorderB = 0;
|
||||
_sndChannels = dataStream.readByte(); // x18
|
||||
_sndVolume = dataStream.readByte(); // x19
|
||||
_midiVolume = dataStream.readByte(); // x1a
|
||||
_svFps = dataStream.readByte(); // x1b
|
||||
_svFrame = dataStream.readSint32LE(); // x1c
|
||||
_midiTrack = dataStream.readUint32LE(); // x20
|
||||
_mouseCursorImgId = dataStream.readSint32LE(); // x24
|
||||
//0x28
|
||||
|
||||
_messageProc._keyCodes[0] = KeyCodes::WIN_UP;
|
||||
_messageProc._keyCodes[1] = KeyCodes::WIN_PRIOR;
|
||||
_messageProc._keyCodes[2] = KeyCodes::WIN_RIGHT;
|
||||
_messageProc._keyCodes[3] = KeyCodes::WIN_NEXT;
|
||||
_messageProc._keyCodes[4] = KeyCodes::WIN_DOWN;
|
||||
_messageProc._keyCodes[5] = KeyCodes::WIN_END;
|
||||
_messageProc._keyCodes[6] = KeyCodes::WIN_LEFT;
|
||||
_messageProc._keyCodes[7] = KeyCodes::WIN_HOME;
|
||||
_messageProc._keyCodes[8] = KeyCodes::WIN_SPACE;
|
||||
_messageProc._keyCodes[9] = KeyCodes::WIN_RETURN;
|
||||
_messageProc._keyCodes[10] = KeyCodes::WIN_TAB;
|
||||
_messageProc._keyCodes[11] = KeyCodes::WIN_INVALID;
|
||||
_messageProc._keyCodes[12] = KeyCodes::WIN_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2292,6 +2355,9 @@ uint32 GamosEngine::doScript(uint32 scriptAddress) {
|
||||
void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
|
||||
uint32 arg1 = 0, arg2 = 0;
|
||||
|
||||
if (_engineVersion <= 0x12 && funcID >= 47) // skip 47 func for old versions
|
||||
funcID++;
|
||||
|
||||
switch (funcID) {
|
||||
case 0:
|
||||
_restartUpdateObject = true;
|
||||
|
||||
@@ -594,6 +594,8 @@ private:
|
||||
|
||||
bool _needReload = false;
|
||||
|
||||
uint32 _engineVersion = 0x18;
|
||||
|
||||
protected:
|
||||
// Engine APIs
|
||||
Common::Error run() override;
|
||||
|
||||
@@ -45,36 +45,38 @@ void SystemProc::processMessage(const Common::Event &ev) {
|
||||
if (_rawKeyCode == 0)
|
||||
_rawKeyCode = ACT_NONE;
|
||||
|
||||
if (winKey == _keyCodes[0])
|
||||
_act1 = 0;
|
||||
else if (winKey == _keyCodes[1])
|
||||
_act1 = 1;
|
||||
else if (winKey == _keyCodes[2])
|
||||
_act1 = 2;
|
||||
else if (winKey == _keyCodes[3])
|
||||
_act1 = 3;
|
||||
else if (winKey == _keyCodes[4])
|
||||
_act1 = 4;
|
||||
else if (winKey == _keyCodes[5])
|
||||
_act1 = 5;
|
||||
else if (winKey == _keyCodes[6])
|
||||
_act1 = 6;
|
||||
else if (winKey == _keyCodes[7])
|
||||
_act1 = 7;
|
||||
else {
|
||||
if (winKey == _keyCodes[8])
|
||||
_act2 = ACT2_MOUSEUP_L;
|
||||
else if (winKey == _keyCodes[9])
|
||||
_act2 = ACT2_MOUSEUP_R;
|
||||
else if (winKey == _keyCodes[10])
|
||||
_act2 = ACT2_TAB;
|
||||
else if (winKey == _keyCodes[11])
|
||||
_act2 = ACT2_HELP;
|
||||
else
|
||||
return;
|
||||
if (winKey != KeyCodes::WIN_INVALID) {
|
||||
if (winKey == _keyCodes[0])
|
||||
_act1 = 0;
|
||||
else if (winKey == _keyCodes[1])
|
||||
_act1 = 1;
|
||||
else if (winKey == _keyCodes[2])
|
||||
_act1 = 2;
|
||||
else if (winKey == _keyCodes[3])
|
||||
_act1 = 3;
|
||||
else if (winKey == _keyCodes[4])
|
||||
_act1 = 4;
|
||||
else if (winKey == _keyCodes[5])
|
||||
_act1 = 5;
|
||||
else if (winKey == _keyCodes[6])
|
||||
_act1 = 6;
|
||||
else if (winKey == _keyCodes[7])
|
||||
_act1 = 7;
|
||||
else {
|
||||
if (winKey == _keyCodes[8])
|
||||
_act2 = ACT2_MOUSEUP_L;
|
||||
else if (winKey == _keyCodes[9])
|
||||
_act2 = ACT2_MOUSEUP_R;
|
||||
else if (winKey == _keyCodes[10])
|
||||
_act2 = ACT2_TAB;
|
||||
else if (winKey == _keyCodes[11])
|
||||
_act2 = ACT2_HELP;
|
||||
else
|
||||
return;
|
||||
|
||||
_rawKeyCode = winKey;
|
||||
return;
|
||||
_rawKeyCode = winKey;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((_act1 < 8) && (ev.kbd.flags & Common::KBD_SHIFT))
|
||||
|
||||
Reference in New Issue
Block a user