diff options
| -rw-r--r-- | queen/graphics.cpp | 35 | ||||
| -rw-r--r-- | queen/graphics.h | 4 | ||||
| -rw-r--r-- | queen/logic.cpp | 202 | ||||
| -rw-r--r-- | queen/logic.h | 16 | ||||
| -rw-r--r-- | queen/walk.cpp | 16 | ||||
| -rw-r--r-- | queen/walk.h | 2 |
6 files changed, 260 insertions, 15 deletions
diff --git a/queen/graphics.cpp b/queen/graphics.cpp index 06eb2ce802..bbf969db8d 100644 --- a/queen/graphics.cpp +++ b/queen/graphics.cpp @@ -675,7 +675,12 @@ void Graphics::bobClear(uint32 bobnum) { pbs->box.x1 = 0; pbs->box.y1 = 0; pbs->box.x2 = GAME_SCREEN_WIDTH - 1; - pbs->box.y2 = (bobnum == 16) ? GAME_SCREEN_HEIGHT - 1 : ROOM_ZONE_HEIGHT - 1; // FIXME: does bob number 16 really used ? + if (_fullscreen || bobnum == 16) { // FIXME: does bob number 16 really used ? + pbs->box.y2 = GAME_SCREEN_HEIGHT - 1; + } + else { + pbs->box.y2 = ROOM_ZONE_HEIGHT - 1; + } } @@ -1008,12 +1013,17 @@ void Graphics::journalBobPreDraw() { // GameSettings* pgs void Graphics::update() { // FIXME: incomplete ! bobSortAll(); - panelDraw(); + if (_panelFlag) { + panelDraw(); + } + else if (!_fullscreen) { + panelClear(); + } backdropDraw(); bobDrawAll(); textDrawAll(); displayScreen(); - g_system->delay_msecs(100); + g_system->delay_msecs(100); // TEMP: move to Logic::update() } @@ -1124,5 +1134,24 @@ void Graphics::displayScreen() { } +void Graphics::setScreenMode(int comPanel, bool inCutaway) { + if (comPanel == 2 && inCutaway) { + if (_backdropHeight == GAME_SCREEN_HEIGHT) { + _fullscreen = true; + _panelFlag = false; + } + else { + _fullscreen = false; + _panelFlag = true; + } + } + else { + _fullscreen = 0; + _panelFlag = (comPanel == 1); + } +} + + + } // End of namespace Queen diff --git a/queen/graphics.h b/queen/graphics.h index 3f29d98652..6911d85486 100644 --- a/queen/graphics.h +++ b/queen/graphics.h @@ -158,6 +158,8 @@ public: void displaySetPal(uint8 *pal, int start, int end); void displayScreen(); + void setScreenMode(int comPanel, bool inCutaway); + private: enum { @@ -206,6 +208,8 @@ private: bool _fullscreen; + bool _panelFlag; + uint16 _horizontalScroll; uint8 *_palette; diff --git a/queen/logic.cpp b/queen/logic.cpp index c0e9fae986..8884edf76f 100644 --- a/queen/logic.cpp +++ b/queen/logic.cpp @@ -21,18 +21,23 @@ #include "queen/logic.h" #include "queen/defs.h" +#include "queen/graphics.h" +#include "queen/walk.h" +#include "common/str.h" namespace Queen { Logic::Logic(Resource *resource, Graphics *graphics) - : _maxAnimatedFrame(0), _maxStaticFrame(0), _resource(resource), _graphics(graphics) { + : _resource(resource), _graphics(graphics) { _jas = _resource->loadFile("QUEEN.JAS", 20); _joe.x = _joe.y = 0; + _walk = new Walk(this, _graphics); initialise(); } Logic::~Logic() { delete[] _jas; + delete _walk; //free(_graphicData); } @@ -214,6 +219,7 @@ void Logic::initialise() { memset(_zones, 0, sizeof(_zones)); + _oldRoom = 0; } uint16 Logic::currentRoom() { @@ -345,17 +351,16 @@ uint16 Logic::findBob(uint16 obj) { ++idxAnimated; } } - // FIXME: _max*Frame variables should be initialized in SETUP_FURNITURE and DISP_ROOM if(bobtype == 0) { // static bob if(idxStatic > 0) { - bobnum = 19 + _maxStaticFrame + idxStatic; + bobnum = 19 + _numFurnitureStatic + idxStatic; } } else { // animated bob if(idxAnimated > 0) { - bobnum = 4 + _maxAnimatedFrame + idxAnimated; + bobnum = 4 + _numFurnitureAnimated + _numFurnitureAnimatedLen; } } } @@ -434,7 +439,7 @@ uint16 Logic::findFrame(uint16 obj) { // calculate only if there are person frames if(idx > 0) { - framenum = 36 + _maxStaticFrame + _maxAnimatedFrameLen + idx + FRAMES_JOE_XTRA; + framenum = 36 + _numFurnitureStatic + _numFurnitureAnimatedLen + idx + FRAMES_JOE_XTRA; } } return framenum; @@ -590,6 +595,193 @@ void Logic::zoneSetup() { uint16 maxAreaRoom = _areaMax[_currentRoom]; for (zoneNum = 1; zoneNum <= maxAreaRoom; ++zoneNum) { zoneSet(ZONE_ROOM, maxObjRoom + zoneNum, _area[_currentRoom][zoneNum].box); + _graphics->boxDraw(_area[_currentRoom][zoneNum].box, 18); + } +} + + +void Logic::roomErase() { + + _graphics->frameEraseAll(false); + _graphics->bankErase(15); + _graphics->bankErase(11); + _graphics->bankErase(10); + _graphics->bankErase(12); + + // TODO: TALKHEAD=0; + // TODO: _display->fadeOut(); + // TODO: credits system + // TODO: person animations + + uint16 cur = _roomData[_oldRoom] + 1; + uint16 last = _roomData[_oldRoom + 1]; + while (cur <= last) { + ObjectData *pod = &_objectData[cur]; + if (pod->name == 0) { + // object has been deleted, invalidate image + pod->image = 0; + } + else if (pod->image > -4000 && pod->image <= -10) { + if (_graphicData[ABS(pod->image + 10)].lastFrame == 0) { + // static Bob + pod->image = -1; + } + else { + // animated Bob + pod->image = -2; + } + } + ++cur; + } +} + + +uint16 Logic::roomSetupFurniture(uint16 frames) { + _numFurnitureStatic = 0; + _numFurnitureAnimated = 0; + _numFurnitureAnimatedLen = 0; + uint16 curImage = 36 + FRAMES_JOE_XTRA; + + // count the furniture and update gameState + uint16 furnitureTotal = 0; + uint16 i; + // FIXME: uncomment when Array< FurnitureData > available in Logic +// for (i = 1; i <= _numFurnitureData; ++i) { +// if (_furnitureData[i].room == _currentRoom) { +// ++furnitureTotal; +// _gameState[furnitureTotal] = _furnitureData[i].gameStateValue; +// } +// } +// if (furnitureTotal == 0) { +// return; +// } + + // unpack the furniture from the bank 15 + // there are 3 kinds : + // - static (paste downs), gamestate range = ]0;5000] + // - animated (bobs), gamestate range = ]0;5000] + // - static (overlaying paste downs), gamestate range = [5000; [ + + // unpack the paste downs + for (i = 1; i <= furnitureTotal; ++i) { + int16 obj = _gameState[i]; + if (obj > 0 && obj <= 5000) { + GraphicData *pgd = &_graphicData[obj]; + if (pgd->lastFrame == 0) { + ++_numFurnitureStatic; + ++curImage; + _graphics->bankUnpack(pgd->firstFrame, curImage, 15); + ++frames; + BobSlot *pbs = _graphics->bob(19 + _numFurnitureStatic); + pbs->active = true; + pbs->x = pgd->x; + pbs->y = pgd->y; + pbs->frameNum = curImage; + warning("Logic::roomSetupFurniture() : static furniture instead of animated"); + } + } + } + + // unpack the animated bobs + uint16 curBob = 0; + for (i = 1; i <= furnitureTotal; ++i) { + int16 obj = _gameState[i]; + if (obj > 0 && obj <= 5000) { + GraphicData *pgd = &_graphicData[obj]; + + bool rebound = false; + int16 lastFrame = pgd->lastFrame; + if (lastFrame < 0) { + rebound = true; + lastFrame = -lastFrame; + } + + if (lastFrame > 0) { + _numFurnitureAnimatedLen += lastFrame - pgd->firstFrame + 1; + ++_numFurnitureAnimated; + uint16 image = curImage + 1; + int k; + for (k = pgd->firstFrame; k <= pgd->lastFrame; ++k) { + ++curImage; + _graphics->bankUnpack(k, curImage, 15); + ++frames; + } + _graphics->bobAnimNormal(5 + curBob, image, curImage, pgd->speed / 4, rebound, false); + BobSlot *pbs = _graphics->bob(5 + curBob); + pbs->x = pgd->x; + pbs->y = pgd->y; + ++curBob; + } + } + } + + // unpack the overlaying paste downs + ++curImage; + for (i = 1; i <= furnitureTotal; ++i) { + int16 obj = _gameState[i]; + if (obj > 5000) { + obj -= 5000; + GraphicData *pgd = &_graphicData[obj]; + _graphics->bankUnpack(pgd->firstFrame, curImage, 15); + _graphics->bobPaste(curImage, pgd->x, pgd->y); + } + } + + return frames; +} + + +void Logic::roomSetupObjects() { + warning("Logic::roomSetupObjects() unimplemented"); +} + + +void Logic::roomSetup(const char* room, int comPanel, bool inCutaway) { + + // loads background image + Common::String bdFile(room); + bdFile += ".PCX"; + _graphics->backdropLoad(bdFile.c_str(), _currentRoom); + + // setup graphics to enter fullscreen/panel mode + _graphics->setScreenMode(comPanel, inCutaway); + + // reset sprites table (bounding box...) + _graphics->bobClearAll(); + + // setup any hard-coded palette effect + // TODO: graphics->check_colors(_currentRoom); + + // load/setup objects associated to this room + Common::String bkFile(room); + bkFile += ".BBK"; + _graphics->bankLoad(bkFile.c_str(), 15); + roomSetupFurniture(37 + FRAMES_JOE_XTRA); + roomSetupObjects(); +} + + +void Logic::roomDisplay(const char* room, int state, uint16 scale, int comPanel, bool inCutaway) { + // STATE = 0, Fade in, no Joe + // = 1, if Joe is to be displayed + // = 2, Screen does not dissolve into view + // = 3, Display Joe at the current X, Y coords + + roomErase(); + // TODO: _sound->loadSFX(SFXNAME[_currentRoom]); + roomSetup(room, comPanel, inCutaway); + zoneSetup(); + ObjectData *pod = NULL; + if (state != 0) { + _entryObj = _roomData[70] + 1; // TEMP + pod = _walk->joeSetupInRoom(state, scale, _entryObj); + } + if (state != 2) { + _graphics->update(); + // TODO: _display->fadeIn(); + } + if (pod != NULL) { + _walk->joeMove(0, pod->x, pod->y, inCutaway); } } diff --git a/queen/logic.h b/queen/logic.h index b4d48c58da..86934b3dd6 100644 --- a/queen/logic.h +++ b/queen/logic.h @@ -37,6 +37,9 @@ enum Language { ITALIAN = 'I' }; +enum RoomDisplayMode { + +}; struct ZoneSlot { bool valid; @@ -46,6 +49,7 @@ struct ZoneSlot { class Graphics; class Resource; +class Walk; class Logic { @@ -97,6 +101,12 @@ public: void zoneClearAll(uint16 screen); void zoneSetup(); + void roomErase(); + uint16 roomSetupFurniture(uint16 frames); // SETUP_FURNITURE() + void roomSetupObjects(); // DISP_OBJECTS + void roomSetup(const char* room, int comPanel, bool inCutaway); + void roomDisplay(const char* room, int state, uint16 joeScale, int comPanel, bool inCutaway); // DISP_ROOM + uint16 findScale(uint16 x, uint16 y); @@ -129,6 +139,7 @@ protected: Area (*_area)[11]; WalkOffData *_walkOffData; ZoneSlot _zones[2][MAX_ZONES_NUMBER]; + uint16 _entryObj; enum { GAME_STATE_COUNT = 211 @@ -143,10 +154,13 @@ protected: int16 _gameState[GAME_STATE_COUNT]; - uint16 _maxAnimatedFrame, _maxStaticFrame, _maxAnimatedFrameLen; // FMAXA, FMAX, FMAXALEN + uint16 _numFurnitureAnimated; // FMAXA + uint16 _numFurnitureStatic; // FMAX + uint16 _numFurnitureAnimatedLen; // FMAXLEN Resource *_resource; Graphics *_graphics; + Walk *_walk; void initialise(); }; diff --git a/queen/walk.cpp b/queen/walk.cpp index 17fcb3f2c5..6b060d85d7 100644 --- a/queen/walk.cpp +++ b/queen/walk.cpp @@ -136,7 +136,6 @@ void Walk::animateJoePrepare() { } if (ABS(pwd->dx) < k) { - printf("pwd->dy=%d ds=%d\n", pwd->dy, ds); if (pwd->dy < 0) { if (ds < 0) { pwd->anim.set(17 + FRAMES_JOE_XTRA, 22 + FRAMES_JOE_XTRA, DIR_FRONT); @@ -365,8 +364,8 @@ void Walk::joeSetup() { } -void Walk::joeSetupInRoom(int state, uint16 scale, uint16 entryObj) { - // queen.c SETUP_HERO() + l.633-640 +ObjectData *Walk::joeSetupInRoom(int state, uint16 scale, uint16 entryObj) { + // queen.c SETUP_HERO() uint16 oldx; uint16 oldy; @@ -432,8 +431,9 @@ void Walk::joeSetupInRoom(int state, uint16 scale, uint16 entryObj) { if (pwo != NULL) { // entryObj has a walk off point, then walk from there to object x,y -// joeMove(0, pod->x, pod->y, false); + return pod; } + return NULL; } @@ -594,7 +594,13 @@ uint16 Walk::calcC(uint16 c1, uint16 c2, uint16 c3, uint16 c4, uint16 lastc) { int16 Walk::findAreaPosition(uint16 *x, uint16 *y, bool recalibrate) { - + // In order to locate the nearest available area, the original algorithm + // computes the X (or Y) closest face distance for each available area. We + // simply added the case where the pointer is neither lying in the X range + // nor in the Y one. + // To get an example of this in action, in the room D1, make Joe walking + // to the wall at the right of the window (just above the radiator). On the + // original game, Joe will go to the left door... uint16 i; uint16 pos = 1; uint32 minDist = ~0; diff --git a/queen/walk.h b/queen/walk.h index 43911cf199..f1f9615eef 100644 --- a/queen/walk.h +++ b/queen/walk.h @@ -86,7 +86,7 @@ public: void joeSetup(); //! SETUP_HERO(), places Joe at the right place when entering a room - void joeSetupInRoom(int state, uint16 scale, uint16 entryObj); + ObjectData *joeSetupInRoom(int state, uint16 scale, uint16 entryObj); //! MOVE_JOE() void joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway); |
