From 4e2ffd8d9ed31ae2d9b42707d0c92cfc31aad3a7 Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Tue, 21 Oct 2003 09:05:16 +0000 Subject: WALK, GRAB_JOE, GRAB_DIR, USE_UNDERWEAR, USE_DRESS and USE_CLOTHES implementations svn-id: r10924 --- queen/defs.h | 32 ++++++- queen/logic.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++----- queen/logic.h | 30 +++++++ queen/walk.cpp | 42 +++++++--- queen/walk.h | 6 +- queen/xref.txt | 14 ++-- 6 files changed, 331 insertions(+), 45 deletions(-) (limited to 'queen') diff --git a/queen/defs.h b/queen/defs.h index 9d4dda98a7..13339946f2 100644 --- a/queen/defs.h +++ b/queen/defs.h @@ -48,7 +48,7 @@ enum { }; -enum { +enum Direction { DIR_LEFT = 1, DIR_RIGHT = 2, DIR_FRONT = 3, @@ -107,6 +107,27 @@ enum Language { }; +enum Verb { + VERB_OPEN = 1, + VERB_CLOSE = 2, + VERB_MOVE = 3, + VERB_GIVE = 5, + VERB_USE = 6, + VERB_PICK_UP = 7, + VERB_LOOK_AT = 9, + VERB_TALK_TO = 8, + VERB_WALK_TO = 10, + VERB_SCROLL_UP = 11, + VERB_SCROLL_DOWN = 12, + VERB_INV_ITEM1 = 13, + VERB_INV_ITEM2 = 14, + VERB_INV_ITEM3 = 15, + VERB_INV_ITEM4 = 16, + VERB_USE_JOURNAL = 20, + VERB_SKIP_TEXT = 101 +}; + + enum StateDirection { STATE_DIR_BACK = 0, STATE_DIR_RIGHT = 1, @@ -114,12 +135,21 @@ enum StateDirection { STATE_DIR_FRONT = 3 }; + enum StateTalk { STATE_TALK_TALK, STATE_TALK_MUTE }; +enum StateGrab { + STATE_GRAB_NONE, + STATE_GRAB_DOWN, + STATE_GRAB_UP, + STATE_GRAB_MID +}; + + } // End of namespace Queen #endif diff --git a/queen/logic.cpp b/queen/logic.cpp index 56c7b23371..ebad1160dd 100644 --- a/queen/logic.cpp +++ b/queen/logic.cpp @@ -21,6 +21,7 @@ #include "stdafx.h" #include "queen/logic.h" +#include "queen/cutaway.h" #include "queen/defs.h" #include "queen/display.h" #include "queen/graphics.h" @@ -1460,43 +1461,52 @@ StateDirection Logic::findStateDirection(uint16 state) { // of a STATE_DIR_*. Some (all ?) calls to FIND_STATE(, "DIR") // are often followed by a DIR_* constant. - // see queen.c l.4016-4023 - StateDirection sd = STATE_DIR_BACK; - switch ((state >> 2) & 3) { - case 0: - sd = STATE_DIR_BACK; - break; - case 1: - sd = STATE_DIR_RIGHT; - break; - case 2: - sd = STATE_DIR_LEFT; - break; - case 3: - sd = STATE_DIR_FRONT; - break; - } - return sd; + // queen.c l.4014-4021 + static const StateDirection sd[] = { + STATE_DIR_BACK, + STATE_DIR_RIGHT, + STATE_DIR_LEFT, + STATE_DIR_FRONT + }; + return sd[(state >> 2) & 3]; } StateTalk Logic::findStateTalk(uint16 state) { return (state & (1 << 9)) ? STATE_TALK_TALK : STATE_TALK_MUTE; } -void Logic::joeSetup() { - int i; +StateGrab Logic::findStateGrab(uint16 state) { - _graphics->bankLoad("joe_a.BBK", 13); + // queen.c l.4022-4029 + static const StateGrab gd[] = { + STATE_GRAB_NONE, + STATE_GRAB_DOWN, + STATE_GRAB_UP, + STATE_GRAB_MID + }; + return gd[state & 3]; +} + + +void Logic::joeSetupFromBanks(const char *bank1, const char* bank2) { + + int i; + _graphics->bankLoad(bank1, 13); for (i = 11; i <= 28 + FRAMES_JOE_XTRA; ++i) { _graphics->bankUnpack(i - 10, i, 13); } _graphics->bankErase(13); - _graphics->bankLoad("joe_b.BBK", 7); + _graphics->bankLoad(bank2, 7); _graphics->bankUnpack(1, 33 + FRAMES_JOE_XTRA, 7); _graphics->bankUnpack(3, 34 + FRAMES_JOE_XTRA, 7); _graphics->bankUnpack(5, 35 + FRAMES_JOE_XTRA, 7); +} + +void Logic::joeSetup() { + + joeSetupFromBanks("joe_a.BBK", "joe_b.BBK"); _joe.facing = DIR_FRONT; } @@ -1632,5 +1642,205 @@ uint16 Logic::joeFace() { } +int16 Logic::joeWalkTo(int16 x, int16 y, const Command *cmd, bool mustWalk) { + + // Check to see if object is actually an exit to another + // room. If so, then set up new room + + uint16 k = _roomData[_currentRoom]; + + ObjectData *objData = &_objectData[k + cmd->noun2]; + if (objData->x != 0 || objData->y != 0) { + x = objData->x; + y = objData->y; + } + + if (cmd->action2 == VERB_WALK_TO) { + _entryObj = objData->entryObj; + } + else { + _entryObj = 0; + } + + _newRoom = 0; + + if (_entryObj != 0 && cmd->action2 != VERB_CLOSE) { + // because this is an exit object, see if there is + // a walk off point and set (x,y) accordingly + WalkOffData *wod = walkOffPointForObject(k + cmd->noun2); + if (wod != NULL) { + x = wod->x; + y = wod->y; + } + } + + + // determine which way for Joe to face Object + uint16 facing = 0; + switch (findStateDirection(objData->state)) { + case STATE_DIR_BACK: + facing = DIR_BACK; + break; + case STATE_DIR_FRONT: + facing = DIR_FRONT; + break; + case STATE_DIR_LEFT: + facing = DIR_LEFT; + break; + case STATE_DIR_RIGHT: + facing = DIR_RIGHT; + break; + } + + int16 p = 0; + if (mustWalk) { + BobSlot *bobJoe = _graphics->bob(0); + if (x == bobJoe->x && y == bobJoe->y) { + joeFacing(facing); + joeFace(); + } + else { + // XXX inCutaway parameter + p = _walk->joeMove(facing, x, y, false); + // if(P != 0) P = FIND_VERB + } + } + return p; +} + + +void Logic::joeGrab(uint16 state, uint16 speed) { + + StateGrab sg = findStateGrab(state); + if (sg != STATE_GRAB_NONE) { + joeGrabDirection(sg, speed); + } +} + + +void Logic::joeGrabDirection(StateGrab grab, uint16 speed) { + + // if speed == 0, then keep Joe in position + + uint16 frame = 0; + BobSlot *bobJoe = _graphics->bob(0); + + switch (grab) { + case STATE_GRAB_NONE: + break; + + case STATE_GRAB_MID: + if (_joe.facing == DIR_BACK) { + frame = 4; + } + else if (_joe.facing == DIR_FRONT) { + frame = 6; + } + else { + frame = 2; + } + break; + + case STATE_GRAB_DOWN: + if (_joe.facing == DIR_BACK) { + frame = 9; + } + else { + frame = 8; + } + break; + + case STATE_GRAB_UP: + // turn back + _graphics->bankUnpack(5, 29 + FRAMES_JOE_XTRA, 7); + bobJoe->xflip = (_joe.facing == DIR_LEFT); + bobJoe->scale = _joe.scale; + _graphics->update(); + // grab up + _graphics->bankUnpack(7, 29 + FRAMES_JOE_XTRA, 7); + bobJoe->xflip = (_joe.facing == DIR_LEFT); + bobJoe->scale = _joe.scale; + _graphics->update(); + // turn back + if (speed == 0) { + frame = 7; + } + else { + frame = 5; + } + break; + } + + if (frame != 0) { + _graphics->bankUnpack(frame, 29 + FRAMES_JOE_XTRA, 7); + bobJoe->xflip = (_joe.facing == DIR_LEFT); + bobJoe->scale = _joe.scale; + _graphics->update(); + + // extra delay for grab down + if (grab == STATE_GRAB_DOWN) { + _graphics->update(); + _graphics->update(); + } + + if (speed > 0) { + joeFace(); + } + } +} + + +void Logic::joeUseDress(bool showCut) { + + if (showCut) { + joeFacing(DIR_FRONT); + joeFace(); + if (gameState(VAR_DRESSING_MODE) == 0) { + playCutaway("cdres.CUT"); + // XXX INS_ITEM_NUM(58); + } + else { + playCutaway("cudrs.CUT"); + } + } + _display->palSetJoe(JP_DRESS); + joeSetupFromBanks("JoeD_A.BBK", "JoeD_B.BBK"); + // XXX DEL_ITEM_NUM(56, 0); + // XXX INVENTORY(); + gameState(VAR_DRESSING_MODE, 2); +} + + +void Logic::joeUseClothes(bool showCut) { + + if (showCut) { + joeFacing(DIR_FRONT); + joeFace(); + playCutaway("cdclo.CUT"); + // XXX INS_ITEM_NUM(56); + } + _display->palSetJoe(JP_CLOTHES); + joeSetupFromBanks("Joe_A.BBK", "Joe_B.BBK"); + // XXX DEL_ITEM_NUM(58,0); + // XXX INVENTORY(); + gameState(VAR_DRESSING_MODE, 0); +} + + +void Logic::joeUseUnderwear() { + + _display->palSetJoe(JP_CLOTHES); + joeSetupFromBanks("JoeU_A.BBK", "JoeU_B.BBK"); + gameState(VAR_DRESSING_MODE, 1); +} + + +void Logic::playCutaway(const char* cutFile) { + + char next[20]; + Cutaway::run(cutFile, next, _graphics, this, _resource); +} + + } // End of namespace Queen diff --git a/queen/logic.h b/queen/logic.h index 71cdf65cac..10c33b5cf5 100644 --- a/queen/logic.h +++ b/queen/logic.h @@ -23,6 +23,7 @@ #define QUEENLOGIC_H #include "queen/queen.h" +#include "queen/defs.h" #include "queen/structs.h" namespace Queen { @@ -44,6 +45,12 @@ struct ZoneSlot { }; +struct Command { + Verb action, action2; + uint16 noun, noun2; +}; + + class Graphics; class Resource; class Display; @@ -135,11 +142,14 @@ public: StateDirection findStateDirection(uint16 state); // == FIND_STATE(state, "DIR"); StateTalk findStateTalk (uint16 state); // == FIND_STATE(state, "TALK"); + StateGrab findStateGrab (uint16 state); // == FIND_STATE(state, "GRAB"); Walk *walk() { return _walk; } int talkSpeed() { return _talkSpeed; } + void joeSetupFromBanks(const char *bank1, const char* bank2); + //! SETUP_JOE(), loads the various bobs needed to animate Joe void joeSetup(); @@ -149,6 +159,26 @@ public: //! FACE_JOE() uint16 joeFace(); + //! WALK() + int16 joeWalkTo(int16 x, int16 y, const Command *cmd, bool mustWalk); + + //! GRAB_JOE() + void joeGrab(uint16 state, uint16 speed); + + //! GRAB_DIR + void joeGrabDirection(StateGrab grab, uint16 speed); + + //! USE_DRESS + void joeUseDress(bool showCut); + + //! USE_CLOTHES + void joeUseClothes(bool showCut); + + //! USE_UNDERWEAR + void joeUseUnderwear(); + + void playCutaway(const char* cutFile); + Display *display() { return _display; } protected: diff --git a/queen/walk.cpp b/queen/walk.cpp index 4a68600016..3e8223e873 100644 --- a/queen/walk.cpp +++ b/queen/walk.cpp @@ -64,8 +64,6 @@ void Walk::joeMoveBlock(int facing, uint16 areaNum, uint16 walkDataNum) { warning("Walk::moveJoeBlock() partially implemented"); _graphics->bob(0)->animating = false; - // XXX CAN=-2; - // Make Joe face the right direction _joeMoveBlock = true; _logic->joeFacing(facing); @@ -120,7 +118,7 @@ void Walk::animateJoePrepare() { } -void Walk::animateJoe() { +bool Walk::animateJoe() { // queen.c l.2789-2835 uint16 lastDirection = 0; uint16 i; @@ -136,7 +134,7 @@ void Walk::animateJoe() { // area has been turned off, see if we should execute a cutaway if (pwd->area->mapNeighbours < 0) { joeMoveBlock(pwd->anim.facing, pwd->areaNum, i); - return; + return interrupted; } if (lastDirection != pwd->anim.facing) { _graphics->bobAnimNormal(0, pwd->anim.firstFrame, pwd->anim.lastFrame, 1, false, false); @@ -168,6 +166,7 @@ void Walk::animateJoe() { lastDirection = pwd->anim.facing; } _logic->joeFacing(lastDirection); + return interrupted; } @@ -306,9 +305,9 @@ void Walk::animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum, } -void Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) { +int16 Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) { -// CAN=0 + int16 can = 0; initWalkData(); uint16 oldx = _graphics->bob(0)->x; @@ -331,33 +330,46 @@ void Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) { if (_walkDataCount > 0) { animateJoePrepare(); - animateJoe(); + if(animateJoe()) { + can = -1; + } } else { -// SPEAK(JOE_RESPstr[4],"JOE",find_cd_desc(4)); + // path has been blocked, make Joe say so + // XXX SPEAK(JOE_RESPstr[4],"JOE",find_cd_desc(4)); + can = -1; } _graphics->bob(0)->animating = false; // XXX if ((CAN==-1) && (walkgameload==0)) NEW_ROOM=0; // XXX walkgameload=0; - if (!_joeMoveBlock && direction > 0) { + if (_joeMoveBlock) { + can = -2; + } + else if (direction > 0) { _logic->joeFacing(direction); } _logic->joePrevFacing(_logic->joeFacing()); _logic->joeFace(); + return can; } -void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction) { +int16 Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction) { if (endx == 0 && endy == 0) { warning("Walk::personMove() - endx == 0 && endy == 0"); - return; + return 0; } - // TODO: room 69 specific + // no longer walk characters in ending + if (_logic->currentRoom() == 69) { + if (strcmp(pp->name, "SPARKY") == 0 || strcmp(pp->name, "FAYE") == 0) { + return 0; + } + } - // CAN = 0; + int16 can = 0; initWalkData(); uint16 bobNum = pp->actor->bobNum; @@ -386,6 +398,9 @@ void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImag animatePersonPrepare(mpd, direction); animatePerson(mpd, curImage, bobNum, bankNum, direction); } + else { + can = -1; + } uint16 standingFrame = 0; if (bobNum <= 3) { @@ -416,6 +431,7 @@ void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImag pbs->xflip = false; } pbs->frameNum = standingFrame; + return can; } diff --git a/queen/walk.h b/queen/walk.h index 13e5802002..ef5dff7eba 100644 --- a/queen/walk.h +++ b/queen/walk.h @@ -75,10 +75,10 @@ public: Walk(Logic* logic, Graphics* graphics); //! MOVE_JOE() - void joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway); + int16 joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway); //! MOVE_OTHER - void personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction); + int16 personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction); private: @@ -86,7 +86,7 @@ private: void joeMoveBlock(int facing, uint16 areaNum, uint16 walkDataNum); void animateJoePrepare(); - void animateJoe(); + bool animateJoe(); void animatePersonPrepare(const MovePersonData *mpd, int direction); void animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum, uint16 bankNum, int direction); diff --git a/queen/xref.txt b/queen/xref.txt index a75fb540bc..b6c835dad8 100644 --- a/queen/xref.txt +++ b/queen/xref.txt @@ -168,15 +168,18 @@ INV1,INV2,INV3,INV4 JOE === FACE_JOE() Logic::joeFace -GRAB_DIR() -GRAB_JOE() +GRAB_DIR() Logic::joeGrabDirection +GRAB_JOE() Logic::joeGrab SETUP_HERO() Logic::joeSetupInRoom SETUP_JOE() Logic::joeSetup -WALK() +USE_UNDERWEAR() Logic::joeUseUnderwear +USE_CLOTHES() Logic::joeUseClothes +USE_DRESS() Logic::joeUseDress +WALK() Logic::joeWalk - JOE_RESPstr Logic::_joeResponse JOEF,JX,JY,JDIR Logic::_joe.* -JOEWALK // legal values = 0,1,2,3 +JOEWALK Logic::_joe.walk // legal values = 0,1,2,3 JOURNAL @@ -217,9 +220,6 @@ SETUP_ROOM() QueenEngine::roomChanged SETUP_SCREENS() *not needed* (only calls Graphics::loadPanel) SETUP_VARS() update() Graphics::update -USE_UNDERWEAR() -USE_CLOTHES() -USE_DRESS() - A_ANIMstr Logic::_aAnim A_ANIM_MAX Logic::_numAAnim -- cgit v1.2.3