diff options
-rw-r--r-- | engines/hopkins/anim.cpp | 5 | ||||
-rw-r--r-- | engines/hopkins/graphics.cpp | 2 | ||||
-rw-r--r-- | engines/hopkins/hopkins.h | 6 | ||||
-rw-r--r-- | engines/hopkins/objects.cpp | 8 | ||||
-rw-r--r-- | engines/hopkins/script.cpp | 187 | ||||
-rw-r--r-- | engines/hopkins/talk.cpp | 19 |
6 files changed, 137 insertions, 90 deletions
diff --git a/engines/hopkins/anim.cpp b/engines/hopkins/anim.cpp index ec256eb05d..a492d0a5ac 100644 --- a/engines/hopkins/anim.cpp +++ b/engines/hopkins/anim.cpp @@ -629,8 +629,7 @@ void AnimationManager::searchAnim(const byte *data, int animIndex, int count) { v7 = 0; bool innerLoopCond = false; do { - if (READ_BE_UINT32(&data[v6]) == MKTAG('A', 'N', 'I', 'M') || - (data[v6] == 'F' && data[v6 + 1] == 'I' && data[v6 + 2] == 'N')) + if (READ_BE_UINT32(&data[v6]) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(&data[v6]) == MKTAG24('F', 'I', 'N')) innerLoopCond = true; if (count < v6) { _vm->_globals.Bqe_Anim[animIndex]._enabledFl = false; @@ -678,7 +677,7 @@ void AnimationManager::searchAnim(const byte *data, int animIndex, int count) { loopCond = true; } } - if (data[v21] == 'F' && data[v21 + 1] == 'I' && data[v21 + 2] == 'N') + if (READ_BE_UINT24(&data[v21]) == MKTAG24('F', 'I', 'N')) loopCond = true; ++v21; } while (v21 <= count && !loopCond); diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp index 3203749cf8..a81ce9db41 100644 --- a/engines/hopkins/graphics.cpp +++ b/engines/hopkins/graphics.cpp @@ -1768,7 +1768,7 @@ void GraphicsManager::OPTI_INI(const Common::String &file, int mode, bool initia } } } - if (ptr[0] != 'I' || ptr[1] != 'N' || ptr[2] != 'I') { + if (READ_BE_UINT24(ptr) != MKTAG24('I', 'N', 'I')) { error("Error, file not ini"); } else { bool doneFlag = false; diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h index 4ab356be9a..04b3558963 100644 --- a/engines/hopkins/hopkins.h +++ b/engines/hopkins/hopkins.h @@ -75,6 +75,12 @@ enum { #define MAX_LINES 400 +/** + * A wrapper macro used around three character constants, like 'END', to + * ensure portability. Typical usage: MKTAG24('E','N','D'). + */ +#define MKTAG24(a0,a1,a2) ((uint32)((a2) | (a1) << 8 | ((a0) << 16))) + struct HopkinsGameDescription; class HopkinsEngine : public Engine { diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp index 62d02238f5..7f94c8d92c 100644 --- a/engines/hopkins/objects.cpp +++ b/engines/hopkins/objects.cpp @@ -1198,7 +1198,7 @@ void ObjectsManager::addStaticSprite(const byte *spriteData, Common::Point pos, _sprite[idx].field14 = a9; _sprite[idx]._animationType = 0; - if (spriteData[0] == 'R' && spriteData[1] == 'L' && spriteData[2] == 'E') { + if (READ_BE_UINT24(spriteData) == MKTAG24('R', 'L', 'E')) { _sprite[idx]._rleFl = true; _sprite[idx]._zoomFactor = 0; _sprite[idx]._flipFl = false; @@ -2615,7 +2615,7 @@ void ObjectsManager::OPTI_OBJET() { error("INI file %s not found", file.c_str()); } - if (data[0] != 'I' || data[1] != 'N' || data[2] != 'I') + if (READ_BE_UINT24(data) != MKTAG24('I', 'N', 'I')) error("File %s is not an INI file", file.c_str()); for (;;) { @@ -3139,7 +3139,7 @@ void ObjectsManager::INILINK(const Common::String &file) { _vm->_linesManager.resetLines(); for (size_t idx = 0; idx < nbytes; idx++) { - if (ptr[idx] == 'O' && ptr[idx + 1] == 'B' && ptr[idx + 2] == '2') { + if (READ_BE_UINT24(&ptr[idx]) == MKTAG24('O', 'B', '2')) { v16 = ptr + idx + 4; v32 = 0; v34 = 0; @@ -3165,7 +3165,7 @@ void ObjectsManager::INILINK(const Common::String &file) { if (!OBSSEUL) { for (size_t idx = 0; idx < nbytes; idx++) { - if (ptr[idx] == 'Z' && ptr[idx + 1] == 'O' && ptr[idx + 2] == '2') { + if (READ_BE_UINT24(&ptr[idx]) == MKTAG24('Z', 'O', '2')) { v17 = &ptr[idx + 4]; v33 = 0; for (int i = 1; i <= 100; i++) { diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp index 87f2410330..a662a3755c 100644 --- a/engines/hopkins/script.cpp +++ b/engines/hopkins/script.cpp @@ -43,12 +43,15 @@ void ScriptManager::setParent(HopkinsEngine *vm) { } int ScriptManager::handleOpcode(byte *dataP) { - if (dataP[0] != 'F' || dataP[1] != 'C') + if (READ_BE_UINT16(dataP) != MKTAG16('F', 'C')) return 0; int opcodeType = 0; int vbobFrameIndex = 0; - if (dataP[2] == 'T' && dataP[3] == 'X' && dataP[4] == 'T') { + + uint32 signature24 = READ_BE_UINT24(&dataP[2]); + switch (signature24) { + case MKTAG24('T', 'X', 'T'): { vbobFrameIndex = dataP[6]; int mesgId = (int16)READ_LE_UINT16(dataP + 13); opcodeType = 1; @@ -161,7 +164,9 @@ int ScriptManager::handleOpcode(byte *dataP) { _vm->_soundManager.mixVoice(mesgId, 5); } } - } else if (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'B') { + break; + } + case MKTAG24('B', 'O', 'B'): if (!_vm->_objectsManager._disableFl) { int vbobIdx = dataP[5]; vbobFrameIndex = dataP[6]; @@ -190,7 +195,8 @@ int ScriptManager::handleOpcode(byte *dataP) { warning("Former AFFICHE_SPEED1: %d %d %d", vbobPosX, vbobPosY, vbobFrameIndex); } opcodeType = 1; - } else if (dataP[2] == 'S' && dataP[3] == 'T' && dataP[4] == 'P') { + break; + case MKTAG24('S', 'T', 'P'): if (!_vm->_objectsManager._disableFl) { _vm->_objectsManager._twoCharactersFl = false; _vm->_objectsManager._characterPos.x = (int16)READ_LE_UINT16(dataP + 6); @@ -249,7 +255,8 @@ int ScriptManager::handleOpcode(byte *dataP) { } opcodeType = 1; _vm->_objectsManager._changeHeadFl = false; - } else if (dataP[2] == 'S' && dataP[3] == 'T' && dataP[4] == 'E') { + break; + case MKTAG24('S', 'T', 'E'): if (!_vm->_objectsManager._disableFl) { _vm->_globals._prevScreenId = _vm->_globals._screenId; _vm->_globals._saveData->_data[svField6] = _vm->_globals._screenId; @@ -257,11 +264,13 @@ int ScriptManager::handleOpcode(byte *dataP) { vbobFrameIndex = dataP[6]; } opcodeType = 1; - } else if (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'F') { + break; + case MKTAG24('B', 'O', 'F'): if (!_vm->_objectsManager._disableFl) _vm->_objectsManager.VBOB_OFF((int16)READ_LE_UINT16(dataP + 5)); opcodeType = 1; - } else if (dataP[2] == 'P' && dataP[3] == 'E' && dataP[4] == 'R') { + break; + case MKTAG24('P', 'E', 'R'): { int specialOpcode = (int16)READ_LE_UINT16(dataP + 5); if (!_vm->_globals._saveData->_data[svField122] && !_vm->_globals._saveData->_data[svField356]) { vbobFrameIndex = 0; @@ -440,49 +449,64 @@ int ScriptManager::handleOpcode(byte *dataP) { } } opcodeType = 1; - } else if (dataP[2] == 'M' && dataP[3] == 'U' && dataP[4] == 'S') { + break; + } + case MKTAG24('M', 'U', 'S'): opcodeType = 1; - } else if (dataP[2] == 'W' && dataP[3] == 'A' && dataP[4] == 'I') { - uint v74 = READ_LE_UINT16(dataP + 5) / _vm->_globals._speed; - if (!v74) - v74 = 1; - for (uint v10 = 0; v10 < v74 + 1; v10++) { + break; + case MKTAG24('W', 'A', 'I'): { + uint frameNumb = READ_LE_UINT16(dataP + 5) / _vm->_globals._speed; + if (!frameNumb) + frameNumb = 1; + for (uint i = 0; i < frameNumb + 1; i++) { if (_vm->shouldQuit()) return -1; // Exiting game _vm->_eventsManager.VBL(); } opcodeType = 1; - } else if (dataP[2] == 'O' && dataP[3] == 'B' && dataP[4] == 'P') { + break; + } + case MKTAG24('O', 'B', 'P'): opcodeType = 1; _vm->_objectsManager.addObject((int16)READ_LE_UINT16(dataP + 5)); - } else if (dataP[2] == 'O' && dataP[3] == 'B' && dataP[4] == 'M') { + break; + case MKTAG24('O', 'B', 'M'): opcodeType = 1; _vm->_objectsManager.removeObject((int16)READ_LE_UINT16(dataP + 5)); - } else if (dataP[2] == 'G' && dataP[3] == 'O' && dataP[4] == 'T') { + break; + case MKTAG24('G', 'O', 'T'): opcodeType = 2; - } else if (dataP[2] == 'Z' && dataP[3] == 'O' && dataP[4] == 'N') { + break; + case MKTAG24('Z', 'O', 'N'): _vm->_objectsManager.enableZone((int16)READ_LE_UINT16(dataP + 5)); opcodeType = 1; - } else if (dataP[2] == 'Z' && dataP[3] == 'O' && dataP[4] == 'F') { + break; + case MKTAG24('Z', 'O', 'F'): _vm->_objectsManager.disableZone((int16)READ_LE_UINT16(dataP + 5)); opcodeType = 1; - } else if (dataP[2] == 'E' && dataP[3] == 'X' && dataP[4] == 'I') { + break; + case MKTAG24('E', 'X', 'I'): opcodeType = 5; - } else if (dataP[2] == 'S' && dataP[3] == 'O' && dataP[4] == 'R') { + break; + case MKTAG24('S', 'O', 'R'): _vm->_globals._exitId = (int16)READ_LE_UINT16(dataP + 5); opcodeType = 5; - } else if (dataP[2] == 'B' && dataP[3] == 'C' && dataP[4] == 'A') { + break; + case MKTAG24('B', 'C', 'A'): _vm->_globals.CACHE_OFF((int16)READ_LE_UINT16(dataP + 5)); opcodeType = 1; - } else if (dataP[2] == 'A' && dataP[3] == 'N' && dataP[4] == 'I') { - int v75 = (int16)READ_LE_UINT16(dataP + 5); - if (v75 <= 100) - _vm->_objectsManager.setBobAnimation(v75); + break; + case MKTAG24('A', 'N', 'I'): { + int animId = (int16)READ_LE_UINT16(dataP + 5); + if (animId <= 100) + _vm->_objectsManager.setBobAnimation(animId); else - _vm->_objectsManager.stopBobAnimation(v75 - 100); + _vm->_objectsManager.stopBobAnimation(animId - 100); opcodeType = 1; - } else if (dataP[2] == 'S' && dataP[3] == 'P' && dataP[4] == 'E') { + break; + } + case MKTAG24('S', 'P', 'E'): switch ((int16)READ_LE_UINT16(dataP + 5)) { case 6: _vm->_objectsManager.removeSprite(0); @@ -2344,40 +2368,56 @@ int ScriptManager::handleOpcode(byte *dataP) { break; } opcodeType = 1; - } else if (dataP[2] == 'E' && dataP[3] == 'I' && dataP[4] == 'F') { + break; + case MKTAG24('E', 'I', 'F'): opcodeType = 4; - } else if (dataP[2] == 'V' && dataP[3] == 'A' && dataP[4] == 'L') { + break; + case MKTAG24('V', 'A', 'L'): { opcodeType = 1; int idx = (int16)READ_LE_UINT16(dataP + 5); assert(idx >= 0 && idx < 2050); _vm->_globals._saveData->_data[idx] = dataP[7]; - } else if (dataP[2] == 'A' && dataP[3] == 'D' && dataP[4] == 'D') { + break; + } + case MKTAG24('A', 'D', 'D'): opcodeType = 1; _vm->_globals._saveData->_data[(int16)READ_LE_UINT16(dataP + 5)] += dataP[7]; - } else if (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'S') { + break; + case MKTAG24('B', 'O', 'S'): opcodeType = 1; _vm->_objectsManager.BOB_OFFSET((int16)READ_LE_UINT16(dataP + 5), (int16)READ_LE_UINT16(dataP + 7)); - } else if (dataP[2] == 'V' && dataP[3] == 'O' && dataP[4] == 'N') { + break; + case MKTAG24('V', 'O', 'N'): _vm->_objectsManager.enableVerb((int16)READ_LE_UINT16(dataP + 5), (int16)READ_LE_UINT16(dataP + 7)); opcodeType = 1; - } else if (dataP[2] == 'Z' && dataP[3] == 'C' && dataP[4] == 'H') { + break; + case MKTAG24('Z', 'C', 'H'): _vm->_globals.ZONEP[(int16)READ_LE_UINT16(dataP + 5)].field12 = (int16)READ_LE_UINT16(dataP + 7); opcodeType = 1; - } else if (dataP[2] == 'J' && dataP[3] == 'U' && dataP[4] == 'M') { + break; + case MKTAG24('J', 'U', 'M'): _vm->_objectsManager._jumpZone = (int16)READ_LE_UINT16(dataP + 5); _vm->_objectsManager._jumpVerb = (int16)READ_LE_UINT16(dataP + 7); opcodeType = 6; - } else if (dataP[2] == 'S' && dataP[3] == 'O' && dataP[4] == 'U') { + break; + case MKTAG24('S', 'O', 'U'): { int soundNum = (int16)READ_LE_UINT16(dataP + 5); Common::String file = Common::String::format("SOUND%d.WAV", soundNum); _vm->_soundManager.playSound(file); opcodeType = 1; - } else if (dataP[2] == 'V' && dataP[3] == 'O' && dataP[4] == 'F') { + break; + } + case MKTAG24('V', 'O', 'F'): _vm->_objectsManager.disableVerb((int16)READ_LE_UINT16(dataP + 5), (int16)READ_LE_UINT16(dataP + 7)); opcodeType = 1; - } else if (dataP[2] == 'I' && dataP[3] == 'I' && dataP[4] == 'F') { + break; + case MKTAG24('I', 'I', 'F'): opcodeType = 3; + break; + default: + warning("Unhandled opcode %c%c%c", dataP[2], dataP[3], dataP[4]); + break; } return opcodeType; @@ -2466,48 +2506,51 @@ LABEL_2: } int ScriptManager::checkOpcode(const byte *dataP) { - if (dataP[0] != 'F' || dataP[1] != 'C') { - return 0; - } - int result = 0; - - if ((dataP[2] == 'A' && dataP[3] == 'N' && dataP[4] == 'I') || - (dataP[2] == 'B' && dataP[3] == 'C' && dataP[4] == 'A') || - (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'B') || - (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'F') || - (dataP[2] == 'B' && dataP[3] == 'O' && dataP[4] == 'S') || - (dataP[2] == 'M' && dataP[3] == 'U' && dataP[4] == 'S') || - (dataP[2] == 'O' && dataP[3] == 'B' && dataP[4] == 'M') || - (dataP[2] == 'O' && dataP[3] == 'B' && dataP[4] == 'P') || - (dataP[2] == 'P' && dataP[3] == 'E' && dataP[4] == 'R') || - (dataP[2] == 'S' && dataP[3] == 'O' && dataP[4] == 'U') || - (dataP[2] == 'S' && dataP[3] == 'P' && dataP[4] == 'E') || - (dataP[2] == 'T' && dataP[3] == 'X' && dataP[4] == 'T') || - (dataP[2] == 'V' && dataP[3] == 'A' && dataP[4] == 'L') || - (dataP[2] == 'V' && dataP[3] == 'O' && dataP[4] == 'F') || - (dataP[2] == 'V' && dataP[3] == 'O' && dataP[4] == 'N') || - (dataP[2] == 'Z' && dataP[3] == 'C' && dataP[4] == 'H') || - (dataP[2] == 'Z' && dataP[3] == 'O' && dataP[4] == 'F') || - (dataP[2] == 'Z' && dataP[3] == 'O' && dataP[4] == 'N')) + if (READ_BE_UINT16(dataP) != MKTAG16('F', 'C')) + return result; + + uint32 signature24 = READ_BE_UINT24(&dataP[2]); + switch (signature24) { + case MKTAG24('A', 'N', 'I'): + case MKTAG24('B', 'C', 'A'): + case MKTAG24('B', 'O', 'B'): + case MKTAG24('B', 'O', 'F'): + case MKTAG24('B', 'O', 'S'): + case MKTAG24('M', 'U', 'S'): + case MKTAG24('O', 'B', 'M'): + case MKTAG24('O', 'B', 'P'): + case MKTAG24('P', 'E', 'R'): + case MKTAG24('S', 'O', 'U'): + case MKTAG24('S', 'P', 'E'): + case MKTAG24('T', 'X', 'T'): + case MKTAG24('V', 'A', 'L'): + case MKTAG24('V', 'O', 'F'): + case MKTAG24('V', 'O', 'N'): + case MKTAG24('Z', 'C', 'H'): + case MKTAG24('Z', 'O', 'F'): + case MKTAG24('Z', 'O', 'N'): result = 1; - - if (dataP[2] == 'G' && dataP[3] == 'O' && dataP[4] == 'T') + break; + case MKTAG24('G', 'O', 'T'): result = 2; - - if (dataP[2] == 'I' && dataP[3] == 'I' && dataP[4] == 'F') + break; + case MKTAG24('I', 'I', 'F'): result = 3; - - if (dataP[2] == 'E' && dataP[3] == 'I' && dataP[4] == 'F') + break; + case MKTAG24('E', 'I', 'F'): result = 4; - - if ((dataP[2] == 'E' && dataP[3] == 'X' && dataP[4] == 'I') || - (dataP[2] == 'S' && dataP[3] == 'O' && dataP[4] == 'R')) + break; + case MKTAG24('E', 'X', 'I'): + case MKTAG24('S', 'O', 'R'): result = 5; - - if (dataP[2] == 'J' && dataP[3] == 'U' && dataP[4] == 'M') + break; + case MKTAG24('J', 'U', 'M'): result = 6; - + break; +// default: +// warning("Unhandled opcode %c%c%c", dataP[2], dataP[3], dataP[4]); + } return result; } diff --git a/engines/hopkins/talk.cpp b/engines/hopkins/talk.cpp index 5e265dbeff..d655b95822 100644 --- a/engines/hopkins/talk.cpp +++ b/engines/hopkins/talk.cpp @@ -436,7 +436,7 @@ void TalkManager::searchCharacterPalette(int startIdx, bool dark) { int palettePos = 0; size_t curIdx = startIdx; for (;;) { - if (_characterBuffer[curIdx] == 'P' && _characterBuffer[curIdx + 1] == 'A' && _characterBuffer[curIdx + 2] == 'L') { + if (READ_BE_UINT24(&_characterBuffer[curIdx]) == MKTAG24('P', 'A', 'L')) { palettePos = curIdx; break; } @@ -719,8 +719,7 @@ bool TalkManager::searchCharacterAnim(int idx, const byte *bufPerso, int animId, int animLength = 0; bool loopCond = false; do { - if (READ_BE_UINT32(curPtr) == MKTAG('A', 'N', 'I', 'M') || - (curPtr[0] == 'F' && curPtr[1] == 'I' && curPtr[2] == 'N')) + if (READ_BE_UINT32(curPtr) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(curPtr) == MKTAG24('F', 'I', 'N')) loopCond = true; if (bufIndx > bufferSize) { _vm->_globals.Bqe_Anim[idx]._enabledFl = false; @@ -758,7 +757,7 @@ bool TalkManager::searchCharacterAnim(int idx, const byte *bufPerso, int animId, } result = true; } - if (bufPerso[bufPos] == 'F' && bufPerso[bufPos + 1] == 'I' && bufPerso[bufPos + 2] == 'N') + if (READ_BE_UINT24(&bufPerso[bufPos]) == MKTAG24('F', 'I', 'N')) result = true; if (result) @@ -789,9 +788,9 @@ LABEL_2: byte *curAnswerBuf = _vm->_globals._answerBuffer; for (;;) { - if (curAnswerBuf[0] == 'F' && curAnswerBuf[1] == 'I' && curAnswerBuf[2] == 'N') + if (READ_BE_UINT24(curAnswerBuf) == MKTAG24('F', 'I', 'N')) return; - if (curAnswerBuf[0] == 'C' && curAnswerBuf[1] == 'O' && curAnswerBuf[2] == 'D') { + if (READ_BE_UINT24(curAnswerBuf) == MKTAG24('C', 'O', 'D')) { if (curAnswerBuf[3] == zoneObj && curAnswerBuf[4] == verbObj) tagFound = true; } @@ -811,7 +810,7 @@ LABEL_2: loopCond = false; do { v16 = false; - if (curAnswerBuf[v7] == 'F' && curAnswerBuf[v7 + 1] == 'C') { + if (READ_BE_UINT16(&curAnswerBuf[v7]) == MKTAG16('F', 'C')) { ++v12; assert(v12 < (620 / 20)); @@ -820,7 +819,7 @@ LABEL_2: do { assert(v11 < 20); v8[v11++] = curAnswerBuf[v7++]; - if (curAnswerBuf[v7] == 'F' && curAnswerBuf[v7 + 1] == 'F') { + if (READ_BE_UINT16(&curAnswerBuf[v7]) == MKTAG16('F', 'F')) { v16 = true; v8[v11] = 'F'; v8[v11 + 1] = 'F'; @@ -829,8 +828,8 @@ LABEL_2: } while (!v16); } if (!v16) { - if ((curAnswerBuf[v7] == 'C' && curAnswerBuf[v7 + 1] == 'O' && curAnswerBuf[v7 + 2] == 'D') || - (curAnswerBuf[v7] == 'F' && curAnswerBuf[v7 + 1] == 'I' && curAnswerBuf[v7 + 2] == 'N')) + uint32 signature24 = READ_BE_UINT24(&curAnswerBuf[v7]); + if (signature24 == MKTAG24('C', 'O', 'D') || signature24 == MKTAG24('F', 'I', 'N')) loopCond = true; } curAnswerBuf += v7 + 1; |