aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--queen/command.cpp51
-rw-r--r--queen/command.h4
-rw-r--r--queen/logic.cpp92
-rw-r--r--queen/logic.h2
-rw-r--r--queen/xref.txt4
5 files changed, 120 insertions, 33 deletions
diff --git a/queen/command.cpp b/queen/command.cpp
index 8b2d052309..3174e3114e 100644
--- a/queen/command.cpp
+++ b/queen/command.cpp
@@ -217,8 +217,19 @@ void Command::executeCurrentAction(bool walk) {
return;
}
- // get the number of commands associated with Object/Item
- uint16 comMax = countAssociatedCommands(_selCmd.action, _curCmd.subject1, _curCmd.subject2);
+ uint16 i;
+
+ // get the commands associated with object/item
+ uint16 comMax = 0;
+ uint16 matchingCmds[MAX_MATCHING_CMDS];
+ CmdListData *cmdList = &_cmdList[1];
+ for (i = 1; i <= _numCmdList; ++i, ++cmdList) {
+ if (cmdList->match(_selCmd.action, _curCmd.subject1, _curCmd.subject2)) {
+ matchingCmds[comMax] = i;
+ ++comMax;
+ }
+ }
+
if (comMax == 0) {
// no command match was found, so exit
// pass ACTION2 as parameter, as a new Command (and a new ACTION2)
@@ -233,24 +244,18 @@ void Command::executeCurrentAction(bool walk) {
int16 cond = 0;
CmdListData *com = &_cmdList[0];
uint16 comId = 0;
- uint16 curCommand;
- for (curCommand = 1; curCommand <= comMax; ++curCommand) {
- ++com;
- ++comId;
- // try to find a match for the command in COM_LIST
- for (; comId <= _numCmdList; ++comId, ++com) {
- if (com->match(_selCmd.action, _curCmd.subject1, _curCmd.subject2)) {
- break;
- }
- }
+ for (i = 1; i <= comMax; ++i) {
+
+ comId = matchingCmds[i - 1];
+ com = &_cmdList[comId];
// check the Gamestates and set them if necessary
cond = 0;
if (com->setConditions) {
- cond = setConditions(comId, (curCommand == comMax));
+ cond = setConditions(comId, (i == comMax));
}
- if (cond == -1 && curCommand == comMax) {
+ if (cond == -1 && i == comMax) {
// only exit on a condition fail if at last command
// Joe hasnt spoken, so do normal LOOK command
if (_selCmd.action.value() == VERB_LOOK_AT) {
@@ -260,7 +265,7 @@ void Command::executeCurrentAction(bool walk) {
return;
}
}
- else if (cond == -2 && curCommand == comMax) {
+ else if (cond == -2 && i == comMax) {
// only exit on a condition fail if at last command
// Joe has spoken, so skip LOOK command
cleanupCurrentAction();
@@ -272,7 +277,7 @@ void Command::executeCurrentAction(bool walk) {
}
}
- debug(0, "Command::executeCurrentAction() - cond = %X, com = %X", cond, curCommand);
+ debug(0, "Command::executeCurrentAction() - cond = %X, com = %X", cond, comId);
if (com->setAreas) {
setAreas(comId);
@@ -868,20 +873,6 @@ bool Command::executeIfDialog(const char *description) {
}
-uint16 Command::countAssociatedCommands(const Verb& verb, int16 subj1, int16 subj2) {
-
- // l.145-150 execute.c
- uint16 comMax = 0;
- CmdListData *cmdList = &_cmdList[1];
- uint16 i;
- for (i = 1; i <= _numCmdList; ++i, ++cmdList) {
- if (cmdList->match(verb, subj1, subj2)) {
- ++comMax;
- }
- }
- return comMax;
-}
-
bool Command::handleBadCommand(bool walk) {
diff --git a/queen/command.h b/queen/command.h
index f055571aee..fd11cb63a1 100644
--- a/queen/command.h
+++ b/queen/command.h
@@ -104,6 +104,9 @@ public:
//! return true if command is ready to be executed
bool parse() const { return _parse; }
+ enum {
+ MAX_MATCHING_CMDS = 50
+ };
private:
@@ -118,7 +121,6 @@ private:
bool executeIfCutaway(const char *description);
bool executeIfDialog(const char *description);
- uint16 countAssociatedCommands(const Verb& verb, int16 subj1, int16 subj2);
bool handleBadCommand(bool walk);
void executeStandardStuff(const Verb& action, int16 subj1, int16 subj2);
void changeObjectState(const Verb& action, int16 obj, int16 song, bool cutDone);
diff --git a/queen/logic.cpp b/queen/logic.cpp
index 1a531a7ac5..bc92b7c0b3 100644
--- a/queen/logic.cpp
+++ b/queen/logic.cpp
@@ -2192,6 +2192,98 @@ void Logic::customMoveJoe(int facing, uint16 areaNum, uint16 walkDataNum) {
}
+void Logic::handlePinnacleRoom() {
+
+ // camera does not follow Joe anymore
+ _graphics->cameraBob(-1);
+ roomDisplay("m1", RDM_NOFADE_JOE, 100, 2, true);
+
+ BobSlot *joe = _graphics->bob(6);
+ BobSlot *piton = _graphics->bob(7);
+
+ // set scrolling value to mouse position to avoid glitch
+ _display->horizontalScroll(_input->mousePosX());
+
+ joe->x = piton->x = 3 * _input->mousePosX() / 4 + 200;
+
+ joe->frameNum = _input->mousePosX() / 36 + 43 + FRAMES_JOE_XTRA;
+
+ // adjust bounding box for fullscreen
+ joe->box.y2 = piton->box.y2 = GAME_SCREEN_HEIGHT - 1;
+
+ // bobs have been unpacked from animating objects, we don't need them
+ // to animate anymore ; so turn animating off
+ joe->animating = piton->animating = false;
+
+ update();
+ _display->palFadeIn(0, 223, ROOM_JUNGLE_PINNACLE);
+
+ _entryObj = 0;
+ uint16 prevObj = 0;
+ while (_input->mouseButton() == 0 || _entryObj == 0) {
+
+ update();
+ int mx = _input->mousePosX();
+ int my = _input->mousePosY();
+
+ // update screen scrolling
+ _display->horizontalScroll(_input->mousePosX());
+
+ // update bobs position / frame
+ joe->x = piton->x = 3 * mx / 4 + 200;
+ joe->frameNum = mx / 36 + 43 + FRAMES_JOE_XTRA;
+
+ uint16 curObj = findObjectUnderCursor(mx, my);
+ if (curObj != 0 && curObj != prevObj) {
+ _entryObj = 0;
+ curObj += _roomData[_currentRoom]; // global object number
+ ObjectData *objData = &_objectData[curObj];
+ if (objData->name > 0) {
+ _entryObj = objData->entryObj;
+ char textCmd[CmdText::MAX_COMMAND_LEN];
+ sprintf(textCmd, "%s %s", Verb(VERB_WALK_TO).name(), _objName[objData->name]);
+ _graphics->textCurrentColor(INK_MAP7);
+ _graphics->textSetCentered(5, textCmd);
+ }
+ prevObj = curObj;
+ }
+ }
+ _input->clearMouseButton();
+
+ _newRoom = _objectData[_entryObj].room;
+ joe->active = piton->active = false;
+ _graphics->textClear(5, 5);
+
+ // There is quite a hack in original source code to handle properly this
+ // special room. The main problem is described in executed.c l.334-339.
+ //
+ // Below is how room switching is handled
+ //
+ // ACTION2=10;
+ // SUBJECT[1]=NOUN+ROOM_DATA[ROOM];
+ // EXECUTE_ACTION(NO);
+ //
+ // None of the following commands updates gamestate/areas/objects/items :
+ //
+ // piton -> crash : 0x216
+ // piton -> floda : 0x217
+ // piton -> bob : 0x219
+ // piton -> embark : 0x218
+ // piton -> jungle : 0x20B
+ //
+ // But this list is surely not exhaustive...
+ //
+ // So basically, EXECUTE_ACTION only performs the playsong calls...
+ // XXX if (com->song > 0) { playsong(com->song); }
+
+ // camera follows Joe again
+ _graphics->cameraBob(0);
+
+ // XXX COMPANEL=1;
+ // XXX panelflag=1;
+}
+
+
void Logic::update() {
_graphics->update(_currentRoom);
_input->delay();
diff --git a/queen/logic.h b/queen/logic.h
index 5051718025..80ee67a3b2 100644
--- a/queen/logic.h
+++ b/queen/logic.h
@@ -263,6 +263,8 @@ public:
void customMoveJoe(int facing, uint16 areaNum, uint16 walkDataNum);
+ void handlePinnacleRoom();
+
void update();
diff --git a/queen/xref.txt b/queen/xref.txt
index 754a381b4c..0b71f5d273 100644
--- a/queen/xref.txt
+++ b/queen/xref.txt
@@ -221,7 +221,7 @@ FIND_GRAPHIC() Logic::graphicData
FIND_SCALE() Logic::findScale
FIND_VERB() Logic::findVerb
P3_COPY_FROM() Logic::objectCopy
-R_MAP() (handle map 'm1')
+R_MAP() Logic::handlePinnacleRoom
REDISP_OBJECT() Logic::roomRefreshObject
restart_game()
SETUP_BOBS() Graphics::bobSetupControl
@@ -403,7 +403,7 @@ MOVE_OTHER() Walk::personMove
-
AREALIST Walk::_areaList
AREASTRIKE Walk::_areaStrike
-movdata Walk::_moveData
+movdata Walk::MOVE_DATA
WALK_DATA Walk::_walkData
WALKI Walk::_walkDataCount