aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2005-12-09 23:02:16 +0000
committerJohannes Schickel2005-12-09 23:02:16 +0000
commitb57f03697541b21c981dcf153354163671773720 (patch)
tree5cad701f25ab12996c8dc860ff8355758741724a
parent775386459972b43308de3f82edf75660ad5e2161 (diff)
downloadscummvm-rg350-b57f03697541b21c981dcf153354163671773720.tar.gz
scummvm-rg350-b57f03697541b21c981dcf153354163671773720.tar.bz2
scummvm-rg350-b57f03697541b21c981dcf153354163671773720.zip
Fixed bug with wrongly used shapes of items in a room.
Also implemented usage of NPC.EMC in the input function. And implemented following opcodes: - cmd_getCharactersLocation - cmd_setBrandonStatusBit - cmd_queryScenePhasingFlag - cmd_resetScenePhasingFlag - cmd_setScenePhasingFlag - cmd_phaseInSameScene - cmd_popMobileNPCIntoScene - cmd_setCharactersMovementDelay - cmd_queryBrandonStatusBit And a fix for the pathfinder and various other functions using the character positions values so they are now able to handle negative positions. svn-id: r19769
-rw-r--r--kyra/debugger.cpp11
-rw-r--r--kyra/debugger.h1
-rw-r--r--kyra/kyra.cpp139
-rw-r--r--kyra/kyra.h9
-rw-r--r--kyra/script_v1.cpp58
5 files changed, 189 insertions, 29 deletions
diff --git a/kyra/debugger.cpp b/kyra/debugger.cpp
index 989f7f1eba..036c884af6 100644
--- a/kyra/debugger.cpp
+++ b/kyra/debugger.cpp
@@ -43,6 +43,7 @@ Debugger::Debugger(KyraEngine *vm)
DCmd_Register("queryflag", &Debugger::cmd_queryFlag);
DCmd_Register("timers", &Debugger::cmd_listTimers);
DCmd_Register("settimercountdown", &Debugger::cmd_setTimerCountdown);
+ DCmd_Register("give", &Debugger::cmd_giveItem);
}
void Debugger::preEnter() {
@@ -176,4 +177,14 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) {
return true;
}
+bool Debugger::cmd_giveItem(int argc, const char **argv) {
+ if (argc) {
+ int item = atoi(argv[1]);
+ _vm->setMouseItem(item);
+ _vm->_itemInHand = item;
+ } else
+ DebugPrintf("Syntax: give <itemid>\n");
+
+ return true;
+}
} // End of namespace Kyra
diff --git a/kyra/debugger.h b/kyra/debugger.h
index b764e2a303..ea7f1aba7c 100644
--- a/kyra/debugger.h
+++ b/kyra/debugger.h
@@ -48,6 +48,7 @@ protected:
bool cmd_queryFlag(int argc, const char **argv);
bool cmd_listTimers(int argc, const char **argv);
bool cmd_setTimerCountdown(int argc, const char **argv);
+ bool cmd_giveItem(int argc, const char **argv);
};
} // End of namespace Kyra
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index 2a44a11a34..b83c9d5c86 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -298,6 +298,10 @@ int KyraEngine::init(GameDetector &detector) {
_npcScriptData = new ScriptData;
memset(_npcScriptData, 0, sizeof(ScriptData));
assert(_npcScriptData);
+ _npcScript = new ScriptState;
+ assert(_npcScript);
+ memset(_npcScript, 0, sizeof(ScriptState));
+
_scriptMain = new ScriptState;
assert(_scriptMain);
memset(_scriptMain, 0, sizeof(ScriptState));
@@ -352,6 +356,7 @@ int KyraEngine::init(GameDetector &detector) {
_handleInput = false;
_currentRoom = 0xFFFF;
+ _scenePhasingFlag = 0;
_lastProcessedItem = 0;
_lastProcessedItemHeight = 16;
@@ -1265,13 +1270,28 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int
}
}
+void KyraEngine::transcendScenes(int roomIndex, int roomName) {
+ debug(9, "transcendScenes(%d, %d, %d, %d)", roomIndex, roomName);
+ assert(roomIndex < _roomTableSize);
+ _roomTable[roomIndex].nameIndex = roomName;
+ // _game_unkScreenVar2 = 1;
+ // _game_unkScreenVar3 = 1;
+ // _game_unkScreenVar1 = 0;
+ _brandonPosX = _currentCharacter->x1;
+ _brandonPosY = _currentCharacter->y1;
+ enterNewScene(roomIndex, _currentCharacter->facing, 0, 0, 0);
+ // _game_unkScreenVar1 = 1;
+ // _game_unkScreenVar2 = 0;
+ // _game_unkScreenVar3 = 0;
+}
+
void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypos) {
debug(9, "moveCharacterToPos(%d, %d, %d, %d)", character, facing, xpos, ypos);
Character *ch = &_characterList[character];
ch->facing = facing;
_screen->hideMouse();
- xpos &= 0xFFFC;
- ypos &= 0xFFFE;
+ xpos = (int16)(xpos & 0xFFFC);
+ ypos = (int16)(ypos & 0xFFFE);
disableTimer(19);
disableTimer(14);
disableTimer(18);
@@ -1710,10 +1730,10 @@ void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) {
}
}
- xpos2 &= 0xFFFC;
- ypos2 &= 0xFFFE;
- xpos &= 0xFFFC;
- ypos &= 0xFFFE;
+ xpos2 = (int16)(xpos2 & 0xFFFC);
+ ypos2 = (int16)(ypos2 & 0xFFFE);
+ xpos = (int16)(xpos & 0xFFFC);
+ ypos = (int16)(ypos & 0xFFFE);
_currentCharacter->facing = facing;
_currentCharacter->x1 = xpos;
_currentCharacter->x2 = xpos;
@@ -1909,7 +1929,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
byte curItem = curRoom->itemsTable[i];
if (curItem != 0xFF) {
curAnimState->drawY = curRoom->itemsYPos[i];
- curAnimState->sceneAnimPtr = _shapes[220+i];
+ curAnimState->sceneAnimPtr = _shapes[220+curItem];
curAnimState->animFrameNumber = 0xFFFF;
curAnimState->y1 = curRoom->itemsYPos[i];
curAnimState->x1 = curRoom->itemsXPos[i];
@@ -3492,6 +3512,30 @@ void KyraEngine::animAddGameItem(int index, uint16 sceneId) {
animObj->bkgdChangeFlag = 1;
}
+void KyraEngine::animAddNPC(int character) {
+ debug(9, "animAddNPC(%d)", character);
+ restoreAllObjectBackgrounds();
+ AnimObject *animObj = &_charactersAnimState[character];
+ const Character *ch = &_characterList[character];
+
+ animObj->active = 1;
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+ animObj->drawY = ch->y1;
+ animObj->sceneAnimPtr = _shapes[4+ch->currentAnimFrame];
+ animObj->x1 = animObj->x2 = ch->x1 + _defaultShapeTable[ch->currentAnimFrame-7].xOffset;
+ animObj->y1 = animObj->y2 = ch->y1 + _defaultShapeTable[ch->currentAnimFrame-7].yOffset;
+ if (ch->facing >= 1 && ch->facing <= 3) {
+ animObj->flags |= 1;
+ } else if (ch->facing >= 5 && ch->facing <= 7) {
+ animObj->flags &= 0xFFFFFFFE;
+ }
+ _objectQueue = objectQueue(_objectQueue, animObj);
+ preserveAnyChangedBackgrounds();
+ animObj->refreshFlag = 1;
+ animObj->bkgdChangeFlag = 1;
+}
+
#pragma mark -
#pragma mark - Queue handling
#pragma mark -
@@ -3662,6 +3706,7 @@ int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int move
debug(9, "findWay(%d, %d, %d, %d, 0x%X, %d)", x, y, toX, toY, moveTable, moveTableSize);
x &= 0xFFFC; toX &= 0xFFFC;
y &= 0xFFFE; toY &= 0xFFFE;
+ x = (int16)x; y = (int16)y; toX = (int16)toX; toY = (int16)toY;
if (x == toY && y == toY) {
moveTable[0] = 8;
@@ -4092,10 +4137,10 @@ int KyraEngine::handleSceneChange(int xpos, int ypos, int unk1, int frameReset)
}
}
- int x = _currentCharacter->x1 & 0xFFFC;
- int y = _currentCharacter->y1 & 0xFFFE;
- xpos &= 0xFFFC;
- ypos &= 0xFFFE;
+ int x = (int16)(_currentCharacter->x1 & 0xFFFC);
+ int y = (int16)(_currentCharacter->y1 & 0xFFFE);
+ xpos = (int16)(xpos & 0xFFFC);
+ ypos = (int16)(ypos & 0xFFFE);
int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150);
_pathfinderFlag = 0;
if (ret >= _lastFindWayRet) {
@@ -4572,6 +4617,11 @@ void KyraEngine::processInput(int xpos, int ypos) {
handleSceneChange(xpos, ypos, 1, 1);
return;
} else {
+ int script = checkForNPCScriptRun(xpos, ypos);
+ if (script >= 0) {
+ runNpcScript(script);
+ return;
+ }
if (_itemInHand != -1) {
if (ypos < 155) {
if (hasClickedOnExit(xpos, ypos)) {
@@ -4769,4 +4819,71 @@ void KyraEngine::clickEventHandler2() {
}
}
+int KyraEngine::checkForNPCScriptRun(int xpos, int ypos) {
+ debug(9, "checkForNPCScriptRun(%d, %d)", xpos, ypos);
+ int returnValue = -1;
+ const Character *currentChar = _currentCharacter;
+ int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0;
+
+ int scaleFactor = _scaleTable[currentChar->y1];
+ int addX = (((scaleFactor*8)*3)>>8)>>1;
+ int addY = ((scaleFactor*3)<<4)>>8;
+
+ charLeft = currentChar->x1 - addX;
+ charRight = currentChar->x1 + addX;
+ charTop = currentChar->y1 - addY;
+ charBottom = currentChar->y1;
+
+ if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) {
+ return 0;
+ }
+
+ if (xpos > 304 || xpos < 16) {
+ return -1;
+ }
+
+ for (int i = 1; i < 5; ++i) {
+ currentChar = &_characterList[i];
+
+ if (currentChar->sceneId != _currentCharacter->sceneId)
+ continue;
+
+ charLeft = currentChar->x1 - 12;
+ charRight = currentChar->x1 + 11;
+ charTop = currentChar->y1 - 48;
+ // if (!i) {
+ // charBottom = currentChar->y2 - 16;
+ // } else {
+ charBottom = currentChar->y1;
+ // }
+
+ if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) {
+ continue;
+ }
+
+ if (returnValue != -1) {
+ if (currentChar->y1 >= _characterList[returnValue].y1) {
+ returnValue = i;
+ }
+ } else {
+ returnValue = i;
+ }
+ }
+
+ return returnValue;
+}
+
+void KyraEngine::runNpcScript(int func) {
+ debug(9, "runNpcScript(%d)", func);
+ _scriptInterpreter->initScript(_npcScript, _npcScriptData);
+ _scriptInterpreter->startScript(_npcScript, func);
+ _npcScript->variables[0] = _currentCharacter->sceneId;
+ _npcScript->variables[4] = _itemInHand;
+ _npcScript->variables[5] = func;
+
+ while (_scriptInterpreter->validScript(_npcScript)) {
+ _scriptInterpreter->runScript(_npcScript);
+ }
+}
+
} // End of namespace Kyra
diff --git a/kyra/kyra.h b/kyra/kyra.h
index c85ac18c14..db9d912bc5 100644
--- a/kyra/kyra.h
+++ b/kyra/kyra.h
@@ -419,6 +419,7 @@ protected:
int resetGameFlag(int flag);
void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive);
+ void transcendScenes(int roomIndex, int roomName);
void moveCharacterToPos(int character, int facing, int xpos, int ypos);
void setCharacterPositionWithUpdate(int character);
int setCharacterPosition(int character, int *facingTable);
@@ -470,6 +471,8 @@ protected:
void clickEventHandler2();
void updateMousePointer();
bool hasClickedOnExit(int xpos, int ypos);
+ int checkForNPCScriptRun(int xpos, int ypos);
+ void runNpcScript(int func);
int countItemsInScene(uint16 sceneId);
int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2);
@@ -484,6 +487,7 @@ protected:
void animRemoveGameItem(int index);
void animAddGameItem(int index, uint16 sceneId);
+ void animAddNPC(int character);
AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem);
AnimObject *objectAddHead(AnimObject *queue, AnimObject *head);
@@ -603,6 +607,7 @@ protected:
int16 _exitList[11];
SceneExits _sceneExits;
uint16 _currentRoom;
+ int _scenePhasingFlag;
uint8 *_maskBuffer;
int _sceneChangeState;
@@ -640,9 +645,11 @@ protected:
Debugger *_debugger;
ScriptState *_scriptMain;
+
+ ScriptState *_npcScript;
ScriptData *_npcScriptData;
- ScriptState *_scriptClick; // TODO: rename to a better name
+ ScriptState *_scriptClick;
ScriptData *_scriptClickData;
Character *_characterList;
diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp
index 966625faa8..db0b0643cb 100644
--- a/kyra/script_v1.cpp
+++ b/kyra/script_v1.cpp
@@ -421,7 +421,7 @@ int KyraEngine::cmd_dropItemInScene(ScriptState *script) {
room->itemsYPos[freeItem] = ypos;
room->itemsTable[freeItem] = item;
- animAddGameItem(sceneId, freeItem);
+ animAddGameItem(freeItem, sceneId);
updateAllObjectShapes();
} else {
if (item == 43) {
@@ -526,23 +526,26 @@ int KyraEngine::cmd_playAdlibScore(ScriptState *script) {
}
int KyraEngine::cmd_phaseInSameScene(ScriptState *script) {
- warning("STUB: cmd_phaseInSameScene");
+ debug(3, "cmd_phaseInSameScene(0x%X) (%d, %d)", script, stackPos(0), stackPos(1));
+ transcendScenes(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine::cmd_setScenePhasingFlag(ScriptState *script) {
- warning("STUB: cmd_setScenePhasingFlag");
- return 0;
+ debug(3, "cmd_setScenePhasingFlag(0x%X) ()");
+ _scenePhasingFlag = 1;
+ return 1;
}
int KyraEngine::cmd_resetScenePhasingFlag(ScriptState *script) {
- warning("STUB: cmd_resetScenePhasingFlag");
+ debug(3, "cmd_resetScenePhasingFlag(0x%X) ()");
+ _scenePhasingFlag = 0;
return 0;
}
int KyraEngine::cmd_queryScenePhasingFlag(ScriptState *script) {
- warning("STUB: cmd_queryScenePhasingFlag");
- return 0;
+ debug(3, "cmd_queryScenePhasingFlag(0x%X) ()");
+ return _scenePhasingFlag;
}
int KyraEngine::cmd_sceneToDirection(ScriptState *script) {
@@ -567,7 +570,8 @@ int KyraEngine::cmd_placeItemInGenericMapScene(ScriptState *script) {
}
int KyraEngine::cmd_setBrandonStatusBit(ScriptState *script) {
- warning("STUB: cmd_setBrandonStatusBit");
+ debug(3, "cmd_setBrandonStatusBit(0x%X) (%d)", script, stackPos(0));
+ _brandonStatusBit |= stackPos(0);
return 0;
}
@@ -579,8 +583,8 @@ int KyraEngine::cmd_pauseSeconds(ScriptState *script) {
}
int KyraEngine::cmd_getCharactersLocation(ScriptState *script) {
- warning("STUB: cmd_getCharactersLocation");
- return 0;
+ debug(3, "cmd_getCharactersLocation(0x%X) (%d)", script, stackPos(0));
+ return _characterList[stackPos(0)].sceneId;
}
int KyraEngine::cmd_runNPCSubscript(ScriptState *script) {
@@ -709,8 +713,8 @@ int KyraEngine::cmd_runWSAFrames(ScriptState *script) {
int KyraEngine::cmd_popBrandonIntoScene(ScriptState *script) {
debug(3, "cmd_popBrandonIntoScene(0x%X) (%d, %d, %d, %d)", script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int changeScaleMode = stackPos(3);
- int xpos = stackPos(0) & 0xFFFC;
- int ypos = stackPos(1) & 0xFFFE;
+ int xpos = (int16)(stackPos(0) & 0xFFFC);
+ int ypos = (int16)(stackPos(1) & 0xFFFE);
int facing = stackPos(2);
_currentCharacter->x1 = _currentCharacter->x2 = xpos;
_currentCharacter->y1 = _currentCharacter->y2 = ypos;
@@ -997,8 +1001,8 @@ int KyraEngine::cmd_placeCharacterInOtherScene(ScriptState *script) {
debug(3, "cmd_placeCharacterInOtherScene(0x%X) (%d, %d, %d, %d, %d, %d)", script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int id = stackPos(0);
int sceneId = stackPos(1);
- int xpos = stackPos(2) & 0xFFFC;
- int ypos = stackPos(3) & 0xFE;
+ int xpos = (int16)(stackPos(2) & 0xFFFC);
+ int ypos = (int16)(stackPos(3) & 0xFFFE);
int facing = stackPos(4);
int animFrame = stackPos(5);
@@ -1021,7 +1025,23 @@ int KyraEngine::cmd_specificItemInInventory(ScriptState *script) {
}
int KyraEngine::cmd_popMobileNPCIntoScene(ScriptState *script) {
- warning("STUB: cmd_popMobileNPCIntoScene");
+ debug(3, "cmd_popMobileNPCIntoScene(0x%X) (%d, %d, %d, %d, %d, %d)", script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE));
+ int character = stackPos(0);
+ int sceneId = stackPos(1);
+ int animFrame = stackPos(2);
+ int facing = stackPos(3);
+ int16 xpos = (int16)(stackPos(4) & 0xFFFC);
+ int8 ypos = (int16)(stackPos(5) & 0xFFFE);
+ Character *curChar = &_characterList[character];
+
+ curChar->sceneId = sceneId;
+ curChar->currentAnimFrame = animFrame;
+ curChar->facing = facing;
+ curChar->x1 = curChar->x2 = xpos;
+ curChar->y1 = curChar->y2 = ypos;
+
+ animAddNPC(character);
+ updateAllObjectShapes();
return 0;
}
@@ -1169,7 +1189,8 @@ int KyraEngine::cmd_sceneAnimationActive(ScriptState *script) {
}
int KyraEngine::cmd_setCharactersMovementDelay(ScriptState *script) {
- warning("STUB: cmd_setCharactersMovementDelay");
+ debug(3, "cmd_setCharactersMovementDelay(0x%X) (%d, %d)", script, stackPos(0), stackPos(1));
+ setTimerCountdown(stackPos(0)+5, stackPos(1));
return 0;
}
@@ -1297,7 +1318,10 @@ int KyraEngine::cmd_getBirthstoneGem(ScriptState *script) {
}
int KyraEngine::cmd_queryBrandonStatusBit(ScriptState *script) {
- warning("STUB: cmd_queryBrandonStatusBit");
+ debug(3, "cmd_queryBrandonStatusBit(0x%X) (%d)", script, stackPos(0));
+ if (_brandonStatusBit & stackPos(0)) {
+ return 1;
+ }
return 0;
}