PRINCE: Remove readScript and LittleEndianReader templates from Script

Change all of READ_UINT16 to READ_LE_UINT16 and all READ_UINT32 to READ_LE_UINT32 for endian-safety
This commit is contained in:
lukaslw 2014-10-09 17:54:46 +02:00
parent f80d72d10a
commit 9db1d77d47
4 changed files with 111 additions and 106 deletions

View file

@ -462,18 +462,18 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) {
} }
//skip_line //skip_line
//next_line //next_line
if (READ_UINT16(shadowLineStart + 2) < READ_UINT16(shadowLineStart - 2)) { if (READ_LE_UINT16(shadowLineStart + 2) < READ_LE_UINT16(shadowLineStart - 2)) {
//minus_y //minus_y
shadBitAddr -= PrinceEngine::kMaxPicWidth / 8; shadBitAddr -= PrinceEngine::kMaxPicWidth / 8;
shadPosY--; shadPosY--;
diffY--; diffY--;
} else if (READ_UINT16(shadowLineStart + 2) > READ_UINT16(shadowLineStart - 2)) { } else if (READ_LE_UINT16(shadowLineStart + 2) > READ_LE_UINT16(shadowLineStart - 2)) {
shadBitAddr += PrinceEngine::kMaxPicWidth / 8; shadBitAddr += PrinceEngine::kMaxPicWidth / 8;
shadPosY++; shadPosY++;
diffY++; diffY++;
} }
//no_change_y //no_change_y
if (READ_UINT16(shadowLineStart) < READ_UINT16(shadowLineStart - 4)) { if (READ_LE_UINT16(shadowLineStart) < READ_LE_UINT16(shadowLineStart - 4)) {
//minus_x //minus_x
shadPosX--; shadPosX--;
//rol //rol
@ -484,7 +484,7 @@ void Hero::showHeroShadow(Graphics::Surface *screen, DrawNode *drawNode) {
shadBitMask <<= 1; shadBitMask <<= 1;
} }
diffX--; diffX--;
} else if (READ_UINT16(shadowLineStart) > READ_UINT16(shadowLineStart - 4)) { } else if (READ_LE_UINT16(shadowLineStart) > READ_LE_UINT16(shadowLineStart - 4)) {
shadPosX++; shadPosX++;
//ror //ror
if (shadBitMask == 1) { if (shadBitMask == 1) {
@ -752,9 +752,9 @@ void Hero::showHero() {
//go_for_it: //go_for_it:
while (1) { while (1) {
if (_currCoords != nullptr) { if (_currCoords != nullptr) {
if (READ_UINT32(_currCoords) != 0xFFFFFFFF) { if (READ_LE_UINT32(_currCoords) != 0xFFFFFFFF) {
x = READ_UINT16(_currCoords); x = READ_LE_UINT16(_currCoords);
y = READ_UINT16(_currCoords + 2); y = READ_LE_UINT16(_currCoords + 2);
_currCoords += 4; _currCoords += 4;
dir = *_currDirTab; dir = *_currDirTab;
_currDirTab++; _currDirTab++;
@ -801,8 +801,8 @@ void Hero::showHero() {
} }
} else { } else {
//finito //finito
_middleX = READ_UINT16(_currCoords - 4); _middleX = READ_LE_UINT16(_currCoords - 4);
_middleY = READ_UINT16(_currCoords - 2); _middleY = READ_LE_UINT16(_currCoords - 2);
selectZoom(); selectZoom();
if (_coords != nullptr) { if (_coords != nullptr) {

View file

@ -2160,8 +2160,8 @@ void PrinceEngine::prepareInventoryToView() {
tempMobItem._name = ""; tempMobItem._name = "";
tempMobItem._examText = ""; tempMobItem._examText = "";
int txtOffset = READ_UINT32(&_invTxt[itemNr * 8]); int txtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8]);
int examTxtOffset = READ_UINT32(&_invTxt[itemNr * 8 + 4]); int examTxtOffset = READ_LE_UINT32(&_invTxt[itemNr * 8 + 4]);
stream.seek(txtOffset); stream.seek(txtOffset);
while ((c = stream.readByte())) { while ((c = stream.readByte())) {
@ -2747,7 +2747,7 @@ void PrinceEngine::displayInventory() {
void PrinceEngine::createDialogBox(int dialogBoxNr) { void PrinceEngine::createDialogBox(int dialogBoxNr) {
_dialogLines = 0; _dialogLines = 0;
int amountOfDialogOptions = 0; int amountOfDialogOptions = 0;
int dialogDataValue = (int)READ_UINT32(_dialogData); int dialogDataValue = (int)READ_LE_UINT32(_dialogData);
byte c; byte c;
int sentenceNumber; int sentenceNumber;
@ -2799,7 +2799,7 @@ void PrinceEngine::runDialog() {
byte *dialogText = _dialogText; byte *dialogText = _dialogText;
byte *dialogCurrentText = nullptr; byte *dialogCurrentText = nullptr;
int dialogSelected = -1; int dialogSelected = -1;
int dialogDataValue = (int)READ_UINT32(_dialogData); int dialogDataValue = (int)READ_LE_UINT32(_dialogData);
while ((sentenceNumber = *dialogText) != 0xFF) { while ((sentenceNumber = *dialogText) != 0xFF) {
dialogText++; dialogText++;
@ -2871,7 +2871,7 @@ void PrinceEngine::dialogLeftMouseButton(byte *string, int dialogSelected) {
_interpreter->setString(string); _interpreter->setString(string);
talkHero(0); talkHero(0);
int dialogDataValue = (int)READ_UINT32(_dialogData); int dialogDataValue = (int)READ_LE_UINT32(_dialogData);
dialogDataValue |= (1u << dialogSelected); dialogDataValue |= (1u << dialogSelected);
WRITE_UINT32(_dialogData, dialogDataValue); WRITE_UINT32(_dialogData, dialogDataValue);
@ -3776,7 +3776,7 @@ int PrinceEngine::cpe() {
if ((*(_checkBitmap + kPBW) & _checkMask)) { if ((*(_checkBitmap + kPBW) & _checkMask)) {
switch (_checkMask) { switch (_checkMask) {
case 128: case 128:
value = READ_UINT16(_checkBitmap - 1); value = READ_LE_UINT16(_checkBitmap - 1);
value &= 0x4001; value &= 0x4001;
if (value != 0x4001) { if (value != 0x4001) {
return 0; return 0;
@ -3825,7 +3825,7 @@ int PrinceEngine::cpe() {
} }
break; break;
case 1: case 1:
value = READ_UINT16(_checkBitmap); value = READ_LE_UINT16(_checkBitmap);
value &= 0x8002; value &= 0x8002;
if (value != 0x8002) { if (value != 0x8002) {
return 0; return 0;
@ -4130,8 +4130,8 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) {
} else if (drawLineFlag == -1 && _traceLineLen >= 2) { } else if (drawLineFlag == -1 && _traceLineLen >= 2) {
byte *tempCorrds = bcad; byte *tempCorrds = bcad;
while (tempCorrds != _coords) { while (tempCorrds != _coords) {
x = READ_UINT16(tempCorrds); x = READ_LE_UINT16(tempCorrds);
y = READ_UINT16(tempCorrds + 2); y = READ_LE_UINT16(tempCorrds + 2);
tempCorrds += 4; tempCorrds += 4;
specialPlot2(x, y); specialPlot2(x, y);
} }
@ -4203,13 +4203,13 @@ bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) {
byte *tempCoords = _coords; byte *tempCoords = _coords;
tempCoords -= 4; tempCoords -= 4;
if (tempCoords > _coordsBuf) { if (tempCoords > _coordsBuf) {
int tempX = READ_UINT16(tempCoords); int tempX = READ_LE_UINT16(tempCoords);
int tempY = READ_UINT16(tempCoords + 2); int tempY = READ_LE_UINT16(tempCoords + 2);
if (_checkX == tempX && _checkY == tempY) { if (_checkX == tempX && _checkY == tempY) {
_coords = tempCoords; _coords = tempCoords;
} }
x = READ_UINT16(tempCoords); x = READ_LE_UINT16(tempCoords);
y = READ_UINT16(tempCoords + 2); y = READ_LE_UINT16(tempCoords + 2);
} else { } else {
return false; return false;
} }
@ -4261,10 +4261,10 @@ void PrinceEngine::approxPath() {
if (tempCoordsBuf != tempCoords) { if (tempCoordsBuf != tempCoords) {
tempCoords -= 4; // last point on path tempCoords -= 4; // last point on path
while (tempCoordsBuf != tempCoords) { while (tempCoordsBuf != tempCoords) {
x1 = READ_UINT16(tempCoords); x1 = READ_LE_UINT16(tempCoords);
y1 = READ_UINT16(tempCoords + 2); y1 = READ_LE_UINT16(tempCoords + 2);
x2 = READ_UINT16(tempCoordsBuf); x2 = READ_LE_UINT16(tempCoordsBuf);
y2 = READ_UINT16(tempCoordsBuf + 2); y2 = READ_LE_UINT16(tempCoordsBuf + 2);
tempCoordsBuf += 4; tempCoordsBuf += 4;
//TracePoint //TracePoint
oldCoords = _coords2; oldCoords = _coords2;
@ -4273,8 +4273,8 @@ void PrinceEngine::approxPath() {
WRITE_UINT16(_coords2 + 2, y1); WRITE_UINT16(_coords2 + 2, y1);
_coords2 += 4; _coords2 += 4;
} else { } else {
int testX = READ_UINT16(_coords2 - 4); int testX = READ_LE_UINT16(_coords2 - 4);
int testY = READ_UINT16(_coords2 - 2); int testY = READ_LE_UINT16(_coords2 - 2);
if (testX != x1 || testY != y1) { if (testX != x1 || testY != y1) {
WRITE_UINT16(_coords2, x1); WRITE_UINT16(_coords2, x1);
WRITE_UINT16(_coords2 + 2, y1); WRITE_UINT16(_coords2 + 2, y1);
@ -4315,8 +4315,8 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi
} }
while (1) { while (1) {
againPointX1 = READ_UINT16(tempCoordsBuf); againPointX1 = READ_LE_UINT16(tempCoordsBuf);
againPointY1 = READ_UINT16(tempCoordsBuf + 2); againPointY1 = READ_LE_UINT16(tempCoordsBuf + 2);
tempCoordsBuf += 4; tempCoordsBuf += 4;
if (tempCoordsBuf == _coords) { if (tempCoordsBuf == _coords) {
@ -4324,8 +4324,8 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi
break; break;
} }
dX = againPointX1 - READ_UINT16(tempCoordsBuf); dX = againPointX1 - READ_LE_UINT16(tempCoordsBuf);
dY = againPointY1 - READ_UINT16(tempCoordsBuf + 2); dY = againPointY1 - READ_LE_UINT16(tempCoordsBuf + 2);
if (dX != xDiff) { if (dX != xDiff) {
direction = tempY; direction = tempY;
@ -4352,14 +4352,14 @@ void PrinceEngine::scanDirections() {
int x1, y1, x2, y2, xDiff, yDiff; int x1, y1, x2, y2, xDiff, yDiff;
while (1) { while (1) {
x1 = READ_UINT16(tempCoordsBuf); x1 = READ_LE_UINT16(tempCoordsBuf);
y1 = READ_UINT16(tempCoordsBuf + 2); y1 = READ_LE_UINT16(tempCoordsBuf + 2);
tempCoordsBuf += 4; tempCoordsBuf += 4;
if (tempCoordsBuf == _coords) { if (tempCoordsBuf == _coords) {
break; break;
} }
x2 = READ_UINT16(tempCoordsBuf); x2 = READ_LE_UINT16(tempCoordsBuf);
y2 = READ_UINT16(tempCoordsBuf + 2); y2 = READ_LE_UINT16(tempCoordsBuf + 2);
xDiff = x1 - x2; xDiff = x1 - x2;
yDiff = y1 - y2; yDiff = y1 - y2;
@ -4420,8 +4420,8 @@ void PrinceEngine::moveShandria() {
_secondHero->freeHeroAnim(); _secondHero->freeHeroAnim();
_secondHero->freeOldMove(); _secondHero->freeOldMove();
byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4; byte *shanCoords = _mainHero->_currCoords + shanLen1 * 4 - 4;
int shanX = READ_UINT16(shanCoords - 4); int shanX = READ_LE_UINT16(shanCoords - 4);
int shanY = READ_UINT16(shanCoords - 2); int shanY = READ_LE_UINT16(shanCoords - 2);
int xDiff = shanX - _secondHero->_middleX; int xDiff = shanX - _secondHero->_middleX;
if (xDiff < 0) { if (xDiff < 0) {
xDiff *= -1; xDiff *= -1;
@ -4440,8 +4440,8 @@ void PrinceEngine::moveShandria() {
if (shanCoords == _mainHero->_currCoords) { if (shanCoords == _mainHero->_currCoords) {
break; break;
} }
int x = READ_UINT16(shanCoords); int x = READ_LE_UINT16(shanCoords);
int y = READ_UINT16(shanCoords + 2); int y = READ_LE_UINT16(shanCoords + 2);
int pointDiffX = x - shanX; int pointDiffX = x - shanX;
if (pointDiffX < 0) { if (pointDiffX < 0) {
pointDiffX *= -1; pointDiffX *= -1;
@ -4459,8 +4459,8 @@ void PrinceEngine::moveShandria() {
int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4; int pathSizeDiff = (shanCoords - _mainHero->_currCoords) / 4;
int destDir = *(_mainHero->_currDirTab + pathSizeDiff); int destDir = *(_mainHero->_currDirTab + pathSizeDiff);
_secondHero->_destDirection = destDir; _secondHero->_destDirection = destDir;
int destX = READ_UINT16(shanCoords); int destX = READ_LE_UINT16(shanCoords);
int destY = READ_UINT16(shanCoords + 2); int destY = READ_LE_UINT16(shanCoords + 2);
_secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY); _secondHero->_coords = makePath(kSecondHero, _secondHero->_middleX, _secondHero->_middleY, destX, destY);
if (_secondHero->_coords != nullptr) { if (_secondHero->_coords != nullptr) {
_secondHero->_currCoords = _secondHero->_coords; _secondHero->_currCoords = _secondHero->_coords;
@ -4571,15 +4571,15 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de
if (choosenLength) { if (choosenLength) {
if (chosenCoordsBuf != nullptr) { if (chosenCoordsBuf != nullptr) {
int tempXBegin = READ_UINT16(chosenCoordsBuf); int tempXBegin = READ_LE_UINT16(chosenCoordsBuf);
int tempYBegin = READ_UINT16(chosenCoordsBuf + 2); int tempYBegin = READ_LE_UINT16(chosenCoordsBuf + 2);
if (stX != tempXBegin || stY != tempYBegin) { if (stX != tempXBegin || stY != tempYBegin) {
SWAP(chosenCoordsBuf, choosenCoords); SWAP(chosenCoordsBuf, choosenCoords);
chosenCoordsBuf -= 4; chosenCoordsBuf -= 4;
int cord; int cord;
byte *tempCoordsBuf = _coordsBuf; byte *tempCoordsBuf = _coordsBuf;
while (1) { while (1) {
cord = READ_UINT32(chosenCoordsBuf); cord = READ_LE_UINT32(chosenCoordsBuf);
WRITE_UINT32(tempCoordsBuf, cord); WRITE_UINT32(tempCoordsBuf, cord);
tempCoordsBuf += 4; tempCoordsBuf += 4;
if (chosenCoordsBuf == choosenCoords) { if (chosenCoordsBuf == choosenCoords) {
@ -4611,10 +4611,10 @@ byte *PrinceEngine::makePath(int heroId, int currX, int currY, int destX, int de
newCoords = (byte *)malloc(normCoordsSize); newCoords = (byte *)malloc(normCoordsSize);
newCoordsBegin = newCoords; newCoordsBegin = newCoords;
while (tempCoordsBuf != tempCoords) { while (tempCoordsBuf != tempCoords) {
newValueX = READ_UINT16(tempCoordsBuf); newValueX = READ_LE_UINT16(tempCoordsBuf);
WRITE_UINT16(newCoords, newValueX * 2); WRITE_UINT16(newCoords, newValueX * 2);
newCoords += 2; newCoords += 2;
newValueY = READ_UINT16(tempCoordsBuf + 2); newValueY = READ_LE_UINT16(tempCoordsBuf + 2);
WRITE_UINT16(newCoords, newValueY * 2); WRITE_UINT16(newCoords, newValueY * 2);
newCoords += 2; newCoords += 2;
tempCoordsBuf += 4; tempCoordsBuf += 4;

View file

@ -135,16 +135,28 @@ bool Script::loadStream(Common::SeekableReadStream &stream) {
return true; return true;
} }
uint16 Script::readScript16(uint32 address) {
assert((_data + address + sizeof(uint16)) <= (_data + _dataSize));
uint16 data = READ_LE_UINT16(&_data[address]);
return data;
}
uint32 Script::readScript32(uint32 address) {
assert((_data + address + sizeof(uint32)) <= (_data + _dataSize));
uint32 data = READ_LE_UINT32(&_data[address]);
return data;
}
int16 Script::getLightX(int locationNr) { int16 Script::getLightX(int locationNr) {
return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8]); return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8]);
} }
int16 Script::getLightY(int locationNr) { int16 Script::getLightY(int locationNr) {
return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 2]); return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 2]);
} }
int32 Script::getShadowScale(int locationNr) { int32 Script::getShadowScale(int locationNr) {
return (int)READ_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 4]); return (int)READ_LE_UINT16(&_data[_scriptInfo.lightSources + locationNr * 8 + 4]);
} }
uint32 Script::getStartGameOffset() { uint32 Script::getStartGameOffset() {
@ -152,7 +164,7 @@ uint32 Script::getStartGameOffset() {
} }
uint32 Script::getLocationInitScript(int initRoomTableOffset, int roomNr) { uint32 Script::getLocationInitScript(int initRoomTableOffset, int roomNr) {
return (uint32)READ_UINT32(&_data[initRoomTableOffset + roomNr * 4]); return (uint32)READ_LE_UINT32(&_data[initRoomTableOffset + roomNr * 4]);
} }
byte Script::getMobVisible(int roomMobOffset, uint16 mob) { byte Script::getMobVisible(int roomMobOffset, uint16 mob) {
@ -193,7 +205,7 @@ uint8 *Script::getHeroAnimName(int offset) {
} }
uint32 Script::getBackAnimId(int roomBackAnimOffset, int slot) { uint32 Script::getBackAnimId(int roomBackAnimOffset, int slot) {
uint32 animId = READ_UINT32(&_data[roomBackAnimOffset + slot * 4]); uint32 animId = READ_LE_UINT32(&_data[roomBackAnimOffset + slot * 4]);
return animId; return animId;
} }
@ -215,9 +227,9 @@ int Script::scanMobEvents(int mobMask, int dataEventOffset) {
int16 mob; int16 mob;
int32 code; int32 code;
do { do {
mob = (int)READ_UINT16(&_data[dataEventOffset + i * 6]); mob = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 6]);
if (mob == mobMask) { if (mob == mobMask) {
code = (int)READ_UINT32(&_data[dataEventOffset + i * 6 + 2]); code = (int)READ_LE_UINT32(&_data[dataEventOffset + i * 6 + 2]);
debug("code: %d", code); debug("code: %d", code);
return code; return code;
} }
@ -233,11 +245,11 @@ int Script::scanMobEventsWithItem(int mobMask, int dataEventOffset, int itemMask
int16 item; int16 item;
int32 code; int32 code;
do { do {
mob = (int)READ_UINT16(&_data[dataEventOffset + i * 8]); mob = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 8]);
if (mob == mobMask) { if (mob == mobMask) {
item = (int)READ_UINT16(&_data[dataEventOffset + i * 8 + 2]); item = (int)READ_LE_UINT16(&_data[dataEventOffset + i * 8 + 2]);
if (item == itemMask) { if (item == itemMask) {
code = (int)READ_UINT32(&_data[dataEventOffset + i * 8 + 4]); code = (int)READ_LE_UINT32(&_data[dataEventOffset + i * 8 + 4]);
debug("itemMask: %d", item); debug("itemMask: %d", item);
debug("code: %d", code); debug("code: %d", code);
return code; return code;
@ -256,8 +268,8 @@ void Script::installSingleBackAnim(Common::Array<BackgroundAnim> &backAnimList,
BackgroundAnim newBackgroundAnim; // BackgroundAnim seq data and its array of Anim BackgroundAnim newBackgroundAnim; // BackgroundAnim seq data and its array of Anim
int animOffset = READ_UINT32(&_data[offset]); // pos of BackgroundAnim data in script int animOffset = READ_LE_UINT32(&_data[offset]); // pos of BackgroundAnim data in script
int anims = READ_UINT32(&_data[animOffset + 8]); // amount of Anim in BackgroundAnim int anims = READ_LE_UINT32(&_data[animOffset + 8]); // amount of Anim in BackgroundAnim
if (anims == 0) { if (anims == 0) {
anims = 1; // anims with 0 as amount in game data has just 1 animation anims = 1; // anims with 0 as amount in game data has just 1 animation
@ -463,7 +475,7 @@ uint32 Interpreter::step(uint32 opcodePC) {
_lastInstruction = _currentInstruction; _lastInstruction = _currentInstruction;
// Get the current opcode // Get the current opcode
_lastOpcode = readScript<uint16>(); _lastOpcode = readScript16();
if (_lastOpcode > kNumOpcodes) if (_lastOpcode > kNumOpcodes)
error( error(
@ -538,15 +550,20 @@ void Interpreter::setFgOpcodePC(uint32 value) {
_fgOpcodePC = value; _fgOpcodePC = value;
} }
template <typename T> uint16 Interpreter::readScript16() {
T Interpreter::readScript() { uint16 data = _script->readScript16(_currentInstruction);
T data = _script->read<T>(_currentInstruction); _currentInstruction += sizeof(uint16);
_currentInstruction += sizeof(data); return data;
}
uint32 Interpreter::readScript32() {
uint32 data = _script->readScript32(_currentInstruction);
_currentInstruction += sizeof(uint32);
return data; return data;
} }
int32 Interpreter::readScriptFlagValue() { int32 Interpreter::readScriptFlagValue() {
uint16 value = readScript<uint16>(); uint16 value = readScript16();
if (value & InterpreterFlags::kFlagMask) { if (value & InterpreterFlags::kFlagMask) {
return _flags->getFlagValue((Flags::Id)value); return _flags->getFlagValue((Flags::Id)value);
} }
@ -554,7 +571,7 @@ int32 Interpreter::readScriptFlagValue() {
} }
Flags::Id Interpreter::readScriptFlagId() { Flags::Id Interpreter::readScriptFlagId() {
return (Flags::Id)readScript<uint16>(); return (Flags::Id)readScript16();
} }
void Interpreter::O_WAITFOREVER() { void Interpreter::O_WAITFOREVER() {
@ -583,7 +600,7 @@ void Interpreter::O_INITROOM() {
void Interpreter::O_SETSAMPLE() { void Interpreter::O_SETSAMPLE() {
int32 sampleId = readScriptFlagValue(); int32 sampleId = readScriptFlagValue();
int32 sampleNameOffset = readScript<uint32>(); int32 sampleNameOffset = readScript32();
const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4); const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4);
_vm->loadSample(sampleId, sampleName); _vm->loadSample(sampleId, sampleName);
debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName);
@ -597,7 +614,7 @@ void Interpreter::O_FREESAMPLE() {
void Interpreter::O_PLAYSAMPLE() { void Interpreter::O_PLAYSAMPLE() {
int32 sampleId = readScriptFlagValue(); int32 sampleId = readScriptFlagValue();
uint16 loopType = readScript<uint16>(); uint16 loopType = readScript16();
_vm->playSample(sampleId, loopType); _vm->playSample(sampleId, loopType);
debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType); debugInterpreter("O_PLAYSAMPLE sampleId %d loopType %d", sampleId, loopType);
} }
@ -697,7 +714,7 @@ void Interpreter::O_CHECKANIMFRAME() {
void Interpreter::O_PUTBACKANIM() { void Interpreter::O_PUTBACKANIM() {
int32 roomId = readScriptFlagValue(); int32 roomId = readScriptFlagValue();
int32 slot = readScriptFlagValue(); int32 slot = readScriptFlagValue();
int32 animId = readScript<uint32>(); int32 animId = readScript32();
Room *room = new Room(); Room *room = new Room();
room->loadRoom(_script->getRoomOffset(roomId)); room->loadRoom(_script->getRoomOffset(roomId));
_vm->_script->setBackAnimId(room->_backAnim, slot, animId); _vm->_script->setBackAnimId(room->_backAnim, slot, animId);
@ -738,7 +755,7 @@ void Interpreter::O_FREEALLSAMPLES() {
} }
void Interpreter::O_SETMUSIC() { void Interpreter::O_SETMUSIC() {
uint16 musicId = readScript<uint16>(); uint16 musicId = readScript16();
_vm->loadMusic(musicId); _vm->loadMusic(musicId);
debugInterpreter("O_SETMUSIC musicId %d", musicId); debugInterpreter("O_SETMUSIC musicId %d", musicId);
} }
@ -787,7 +804,7 @@ void Interpreter::O_CLS() {
} }
void Interpreter::O__CALL() { void Interpreter::O__CALL() {
int32 address = readScript<uint32>(); int32 address = readScript32();
_stack[_stacktop] = _currentInstruction; _stack[_stacktop] = _currentInstruction;
_stacktop++; _stacktop++;
_currentInstruction += address - 4; _currentInstruction += address - 4;
@ -805,7 +822,7 @@ void Interpreter::O_RETURN() {
} }
void Interpreter::O_GO() { void Interpreter::O_GO() {
int32 opPC = readScript<uint32>(); int32 opPC = readScript32();
_currentInstruction += opPC - 4; _currentInstruction += opPC - 4;
debugInterpreter("O_GO 0x%04X", opPC); debugInterpreter("O_GO 0x%04X", opPC);
} }
@ -854,7 +871,7 @@ void Interpreter::O_COMPARE() {
} }
void Interpreter::O_JUMPZ() { void Interpreter::O_JUMPZ() {
int32 offset = readScript<uint32>(); int32 offset = readScript32();
if (!_result) { if (!_result) {
_currentInstruction += offset - 4; _currentInstruction += offset - 4;
} }
@ -862,7 +879,7 @@ void Interpreter::O_JUMPZ() {
} }
void Interpreter::O_JUMPNZ() { void Interpreter::O_JUMPNZ() {
int32 offset = readScript<uint32>(); int32 offset = readScript32();
if (_result) { if (_result) {
_currentInstruction += offset - 4; _currentInstruction += offset - 4;
} }
@ -913,7 +930,7 @@ void Interpreter::O_SUBFLAG() {
} }
void Interpreter::O_SETSTRING() { void Interpreter::O_SETSTRING() {
int32 offset = readScript<uint32>(); int32 offset = readScript32();
_currentString = offset; _currentString = offset;
if (offset >= 80000) { if (offset >= 80000) {
_string = _vm->_variaTxt->getString(offset - 80000); _string = _vm->_variaTxt->getString(offset - 80000);
@ -1073,7 +1090,7 @@ void Interpreter::O_CLSTEXT() {
void Interpreter::O_CALLTABLE() { void Interpreter::O_CALLTABLE() {
Flags::Id flagId = readScriptFlagId(); Flags::Id flagId = readScriptFlagId();
int roomNr = _flags->getFlagValue(flagId); int roomNr = _flags->getFlagValue(flagId);
int32 tableOffset = readScript<uint32>(); int32 tableOffset = readScript32();
int initLocationScript = _script->getLocationInitScript(tableOffset, roomNr); int initLocationScript = _script->getLocationInitScript(tableOffset, roomNr);
if (initLocationScript) { if (initLocationScript) {
_stack[_stacktop] = _currentInstruction; _stack[_stacktop] = _currentInstruction;
@ -1214,7 +1231,7 @@ void Interpreter::O_WAITTEXT() {
void Interpreter::O_SETHEROANIM() { void Interpreter::O_SETHEROANIM() {
int32 heroId = readScriptFlagValue(); int32 heroId = readScriptFlagValue();
int32 offset = readScript<uint32>(); int32 offset = readScript32();
Hero *hero = nullptr; Hero *hero = nullptr;
if (!heroId) { if (!heroId) {
hero = _vm->_mainHero; hero = _vm->_mainHero;
@ -1323,7 +1340,7 @@ void Interpreter::O_GETANIMDATA() {
} }
void Interpreter::O_SETBGCODE() { void Interpreter::O_SETBGCODE() {
int32 offset = readScript<uint32>(); int32 offset = readScript32();
_bgOpcodePC = _currentInstruction + offset - 4; _bgOpcodePC = _currentInstruction + offset - 4;
debugInterpreter("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset); debugInterpreter("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset);
} }
@ -1340,7 +1357,7 @@ void Interpreter::O_SETBACKFRAME() {
void Interpreter::O_GETRND() { void Interpreter::O_GETRND() {
Flags::Id flag = readScriptFlagId(); Flags::Id flag = readScriptFlagId();
uint16 rndSeed = readScript<uint16>(); uint16 rndSeed = readScript16();
int value = _vm->_randomSource.getRandomNumber(rndSeed - 1); int value = _vm->_randomSource.getRandomNumber(rndSeed - 1);
_flags->setFlagValue(flag, value); _flags->setFlagValue(flag, value);
debugInterpreter("O_GETRND flag %d, rndSeed %d, value %d", flag, rndSeed, value); debugInterpreter("O_GETRND flag %d, rndSeed %d, value %d", flag, rndSeed, value);
@ -1355,7 +1372,7 @@ void Interpreter::O_TALKBACKANIM() {
// Simplifying, because used only once in Location 20 // Simplifying, because used only once in Location 20
void Interpreter::O_LOADPATH() { void Interpreter::O_LOADPATH() {
readScript<uint32>(); readScript32();
_vm->loadPath("path2"); _vm->loadPath("path2");
debugInterpreter("O_LOADPATH - path2"); debugInterpreter("O_LOADPATH - path2");
} }
@ -1369,7 +1386,7 @@ void Interpreter::O_GETCHAR() {
void Interpreter::O_SETDFLAG() { void Interpreter::O_SETDFLAG() {
Flags::Id flagId = readScriptFlagId(); Flags::Id flagId = readScriptFlagId();
int32 address = readScript<uint32>(); int32 address = readScript32();
_flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4); _flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4);
debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4); debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4);
} }
@ -1482,7 +1499,7 @@ void Interpreter::O_INITDIALOG() {
byte *stringCurrOff = _string; byte *stringCurrOff = _string;
byte *string = _string; byte *string = _string;
stringCurrOff++; stringCurrOff++;
int32 adressOfFirstSequence = (int)READ_UINT16(stringCurrOff); int32 adressOfFirstSequence = (int)READ_LE_UINT16(stringCurrOff);
stringCurrOff += 2; stringCurrOff += 2;
_string = string + adressOfFirstSequence; _string = string + adressOfFirstSequence;
@ -1499,7 +1516,7 @@ void Interpreter::O_INITDIALOG() {
byte *line = nullptr; byte *line = nullptr;
int dialogBox = 0; int dialogBox = 0;
while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
stringCurrOff += 2; stringCurrOff += 2;
if (off) { if (off) {
line = string + off; line = string + off;
@ -1510,7 +1527,7 @@ void Interpreter::O_INITDIALOG() {
stringCurrOff += 2; stringCurrOff += 2;
int dialogOpt = 0; int dialogOpt = 0;
while ((off = (int)READ_UINT16(stringCurrOff)) != -1) { while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
stringCurrOff += 2; stringCurrOff += 2;
if (off) { if (off) {
line = string + off; line = string + off;
@ -1548,7 +1565,7 @@ void Interpreter::O_INITDIALOG() {
void Interpreter::O_ENABLEDIALOGOPT() { void Interpreter::O_ENABLEDIALOGOPT() {
int32 opt = readScriptFlagValue(); int32 opt = readScriptFlagValue();
int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData);
dialogDataValue &= ~(1u << opt); dialogDataValue &= ~(1u << opt);
WRITE_UINT32(_vm->_dialogData, dialogDataValue); WRITE_UINT32(_vm->_dialogData, dialogDataValue);
debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt); debugInterpreter("O_ENABLEDIALOGOPT opt %d", opt);
@ -1556,7 +1573,7 @@ void Interpreter::O_ENABLEDIALOGOPT() {
void Interpreter::O_DISABLEDIALOGOPT() { void Interpreter::O_DISABLEDIALOGOPT() {
int32 opt = readScriptFlagValue(); int32 opt = readScriptFlagValue();
int dialogDataValue = (int)READ_UINT32(_vm->_dialogData); int dialogDataValue = (int)READ_LE_UINT32(_vm->_dialogData);
dialogDataValue |= (1u << opt); dialogDataValue |= (1u << opt);
WRITE_UINT32(_vm->_dialogData, dialogDataValue); WRITE_UINT32(_vm->_dialogData, dialogDataValue);
debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt); debugInterpreter("O_DISABLEDIALOGOPT opt %d", opt);
@ -1584,7 +1601,7 @@ void Interpreter::O_STOPSAMPLE() {
void Interpreter::O_BACKANIMRANGE() { void Interpreter::O_BACKANIMRANGE() {
int32 slotId = readScriptFlagValue(); int32 slotId = readScriptFlagValue();
uint16 animId = readScript<uint16>(); uint16 animId = readScript16();
int32 low = readScriptFlagValue(); int32 low = readScriptFlagValue();
int32 high = readScriptFlagValue(); int32 high = readScriptFlagValue();
if (animId != 0xFFFF) { if (animId != 0xFFFF) {
@ -1672,7 +1689,7 @@ void Interpreter::O_POPSTRING() {
} }
void Interpreter::O_SETFGCODE() { void Interpreter::O_SETFGCODE() {
int32 offset = readScript<uint32>(); int32 offset = readScript32();
_fgOpcodePC = _currentInstruction + offset - 4; _fgOpcodePC = _currentInstruction + offset - 4;
debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset); debugInterpreter("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset);
} }
@ -1723,8 +1740,8 @@ void Interpreter::O_RUNHERO() {
} }
void Interpreter::O_SETBACKANIMDATA() { void Interpreter::O_SETBACKANIMDATA() {
uint16 animNumber = readScript<uint16>(); uint16 animNumber = readScript16();
uint16 animDataOffset = readScript<uint16>(); uint16 animDataOffset = readScript16();
Flags::Id flagId = readScriptFlagId(); Flags::Id flagId = readScriptFlagId();
uint16 value = _flags->getFlagValue((Flags::Id)(flagId)); uint16 value = _flags->getFlagValue((Flags::Id)(flagId));
int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative; int currAnim = _vm->_backAnimList[animNumber]._seq._currRelative;

View file

@ -39,13 +39,6 @@ struct Anim;
struct BackgroundAnim; struct BackgroundAnim;
struct Mask; struct Mask;
// TODO - change this to sth else?
namespace Detail {
template <typename T> T LittleEndianReader(void *data);
template <> inline uint16 LittleEndianReader<uint16>(void *data) { return READ_LE_UINT16(data); }
template <> inline uint32 LittleEndianReader<uint32>(void *data) { return READ_LE_UINT32(data); }
}
class Room { class Room {
public: public:
Room(); Room();
@ -125,11 +118,8 @@ public:
bool loadStream(Common::SeekableReadStream &stream); bool loadStream(Common::SeekableReadStream &stream);
template <typename T> uint16 readScript16(uint32 address);
T read(uint32 address) { uint32 readScript32(uint32 address);
assert((_data + address + sizeof(T)) <= (_data + _dataSize));
return Detail::LittleEndianReader<T>(&_data[address]);
}
uint32 getStartGameOffset(); uint32 getStartGameOffset();
uint32 getLocationInitScript(int initRoomTableOffset, int roomNr); uint32 getLocationInitScript(int initRoomTableOffset, int roomNr);
@ -240,14 +230,12 @@ private:
// Helper functions // Helper functions
uint32 step(uint32 opcodePC); uint32 step(uint32 opcodePC);
uint16 readScript16();
uint32 readScript32();
int32 readScriptFlagValue(); int32 readScriptFlagValue();
Flags::Id readScriptFlagId(); Flags::Id readScriptFlagId();
int checkSeq(byte *string); int checkSeq(byte *string);
// instantiation not needed here
template <typename T> T readScript();
void debugInterpreter(const char *s, ...); void debugInterpreter(const char *s, ...);
typedef void (Interpreter::*OpcodeFunc)(); typedef void (Interpreter::*OpcodeFunc)();