From ee62d6c1cfce009331050fb9bf8bfecbb8f51472 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Aug 2014 23:21:17 -0400 Subject: ACCESS: In progress inventory display screen --- engines/access/asurface.cpp | 3 + engines/access/asurface.h | 2 + engines/access/events.cpp | 88 ++++++++++--------- engines/access/events.h | 10 ++- engines/access/files.cpp | 8 ++ engines/access/files.h | 3 + engines/access/inventory.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++- engines/access/inventory.h | 41 +++++++++ engines/access/resources.cpp | 29 +++++++ engines/access/resources.h | 2 + engines/access/room.cpp | 27 ++---- engines/access/room.h | 12 ++- 12 files changed, 363 insertions(+), 64 deletions(-) diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp index 138978f9d9..ce977f6d83 100644 --- a/engines/access/asurface.cpp +++ b/engines/access/asurface.cpp @@ -265,6 +265,9 @@ void ASurface::copyTo(ASurface *dest, const Common::Rect &bounds) { } } +void ASurface::copyTo(ASurface *dest) { + copyTo(dest, Common::Point()); +} void ASurface::plotF(SpriteFrame *frame, const Common::Point &pt) { sPlotF(frame, Common::Rect(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h)); diff --git a/engines/access/asurface.h b/engines/access/asurface.h index 62e292334d..f5e5f48e7b 100644 --- a/engines/access/asurface.h +++ b/engines/access/asurface.h @@ -92,6 +92,8 @@ public: void copyTo(ASurface *dest, const Common::Rect &bounds); + void copyTo(ASurface *dest); + void saveBlock(const Common::Rect &bounds); void restoreBlock(); diff --git a/engines/access/events.cpp b/engines/access/events.cpp index 78bbdbf1ea..15c8f8cff0 100644 --- a/engines/access/events.cpp +++ b/engines/access/events.cpp @@ -41,11 +41,11 @@ EventsManager::EventsManager(AccessEngine *vm): _vm(vm) { _priorFrameTime = 0; _leftButton = _rightButton = false; _mouseCol = _mouseRow = 0; - _mouseMode = 0; _cursorExitFlag = false; } EventsManager::~EventsManager() { + _invCursor.free(); } void EventsManager::setCursor(CursorType cursorId) { @@ -53,50 +53,56 @@ void EventsManager::setCursor(CursorType cursorId) { return; _cursorId = cursorId; - if (_mouseMode == 1 && cursorId == CURSOR_ARROW) - _mouseMode = 2; - else if (_mouseMode == 2 && cursorId != CURSOR_ARROW) - _mouseMode = 1; - - // Get a pointer to the mouse data to use, and get the cursor hotspot - const byte *srcP = Amazon::CURSORS[cursorId]; - int hotspotX = (int16)READ_LE_UINT16(srcP); - int hotspotY = (int16)READ_LE_UINT16(srcP + 2); - srcP += 4; - - // Create a surface to build up the cursor on - Graphics::Surface cursorSurface; - cursorSurface.create(16, 16, Graphics::PixelFormat::createFormatCLUT8()); - byte *destP = (byte *)cursorSurface.getPixels(); - Common::fill(destP, destP + CURSOR_WIDTH * CURSOR_HEIGHT, 0); - - // Loop to build up the cursor - for (int y = 0; y < CURSOR_HEIGHT; ++y) { - destP = (byte *)cursorSurface.getBasePtr(0, y); - int width = CURSOR_WIDTH; - int skip = *srcP++; - int plot = *srcP++; - if (skip >= width) - break; + if (cursorId == CURSOR_INVENTORY) { + // Set the cursor + CursorMan.replaceCursor(_invCursor.getPixels(), _invCursor.w, _invCursor.h, + 0, 0, 0); + } else { + // Get a pointer to the mouse data to use, and get the cursor hotspot + const byte *srcP = Amazon::CURSORS[cursorId]; + int hotspotX = (int16)READ_LE_UINT16(srcP); + int hotspotY = (int16)READ_LE_UINT16(srcP + 2); + srcP += 4; + + // Create a surface to build up the cursor on + Graphics::Surface cursorSurface; + cursorSurface.create(16, 16, Graphics::PixelFormat::createFormatCLUT8()); + byte *destP = (byte *)cursorSurface.getPixels(); + Common::fill(destP, destP + CURSOR_WIDTH * CURSOR_HEIGHT, 0); + + // Loop to build up the cursor + for (int y = 0; y < CURSOR_HEIGHT; ++y) { + destP = (byte *)cursorSurface.getBasePtr(0, y); + int width = CURSOR_WIDTH; + int skip = *srcP++; + int plot = *srcP++; + if (skip >= width) + break; + + // Skip over pixels + destP += skip; + width -= skip; + + // Write out the pixels to plot + while (plot > 0 && width > 0) { + *destP++ = *srcP++; + --plot; + --width; + } + } - // Skip over pixels - destP += skip; - width -= skip; + // Set the cursor + CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT, + hotspotX, hotspotY, 0); - // Write out the pixels to plot - while (plot > 0 && width > 0) { - *destP++ = *srcP++; - --plot; - --width; - } + // Free the cursor surface + cursorSurface.free(); } +} - // Set the cursor - CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT, - hotspotX, hotspotY, 0); - - // Free the cursor surface - cursorSurface.free(); +void EventsManager::setCursorData(Graphics::Surface *src, const Common::Rect &r) { + _invCursor.create(r.width(), r.height(), Graphics::PixelFormat::createFormatCLUT8()); + _invCursor.copyRectToSurface(*src, 0, 0, r); } void EventsManager::showCursor() { diff --git a/engines/access/events.h b/engines/access/events.h index 2ced71f50e..fdfb0a5043 100644 --- a/engines/access/events.h +++ b/engines/access/events.h @@ -32,7 +32,8 @@ namespace Access { enum CursorType { CURSOR_NONE = -1, CURSOR_ARROW = 0, CURSOR_CROSSHAIRS, CURSOR_2, CURSOR_3, CURSOR_LOOK, - CURSOR_USE, CURSOR_TAKE, CURSOR_CLIMB, CURSOR_TALK, CURSOR_HELP + CURSOR_USE, CURSOR_TAKE, CURSOR_CLIMB, CURSOR_TALK, CURSOR_HELP, + CURSOR_INVENTORY = 99 }; #define GAME_FRAME_RATE 100 @@ -45,6 +46,7 @@ private: AccessEngine *_vm; uint32 _frameCounter; uint32 _priorFrameTime; + Graphics::Surface _invCursor; bool checkForNextFrameCounter(); @@ -55,7 +57,6 @@ public: bool _leftButton, _rightButton; Common::Point _mousePos; int _mouseCol, _mouseRow; - int _mouseMode; bool _cursorExitFlag; Common::FixedStack _keypresses; public: @@ -74,6 +75,11 @@ public: */ void setCursor(CursorType cursorId); + /** + * Set the image for the inventory cursor + */ + void setCursorData(Graphics::Surface *src, const Common::Rect &r); + /** * Return the current cursor Id */ diff --git a/engines/access/files.cpp b/engines/access/files.cpp index da3842492c..230d2a8715 100644 --- a/engines/access/files.cpp +++ b/engines/access/files.cpp @@ -39,6 +39,14 @@ void FileIdent::load(Common::SeekableReadStream &s) { /*------------------------------------------------------------------------*/ +CellIdent::CellIdent(int cell, int fileNum, int subfile) { + _cell = cell; + _fileNum = fileNum; + _subfile = subfile; +} + +/*------------------------------------------------------------------------*/ + FileManager::FileManager(AccessEngine *vm): _vm(vm) { switch (vm->getGameID()) { case GType_Amazon: diff --git a/engines/access/files.h b/engines/access/files.h index b91da7d6ff..d1a4d5aafd 100644 --- a/engines/access/files.h +++ b/engines/access/files.h @@ -43,6 +43,9 @@ struct FileIdent { struct CellIdent : FileIdent { byte _cell; + + CellIdent() {} + CellIdent(int cell, int fileNum, int subfile); }; class FileManager { diff --git a/engines/access/inventory.cpp b/engines/access/inventory.cpp index e90ad62344..6c56f6b90b 100644 --- a/engines/access/inventory.cpp +++ b/engines/access/inventory.cpp @@ -22,6 +22,7 @@ #include "access/inventory.h" #include "access/access.h" +#include "access/resources.h" #include "access/amazon/amazon_resources.h" #include "access/martian/martian_resources.h" @@ -35,6 +36,7 @@ InventoryManager::InventoryManager(AccessEngine *vm) : Manager(vm) { _invModeFlag = false; _startAboutItem = 0; _startTravelItem = 0; + _iconDisplayFlag = false; const char *const *names; switch (vm->getGameID()) { @@ -74,9 +76,205 @@ void InventoryManager::refreshInventory() { } int InventoryManager::newDisplayInv() { - warning("TODO: newDisplayInv"); - return 0; + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + Room &room = *_vm->_room; + FileManager &files = *_vm->_files; + + _invModeFlag = true; + _vm->_timers.saveTimers(); + + if (room._tile && !_invRefreshFlag) { + _vm->_buffer1.copyTo(&_savedBuffer1); + screen.copyTo(&_savedScreen); + } + + savedFields(); + screen.setPanel(1); + events._cursorExitFlag = false; + getList(); + initFields(); + + files.loadScreen(99, 0); + _vm->_buffer1.copyTo(&_vm->_buffer2); + _vm->copyBF2Vid(); + + // Set cells + Common::Array cells; + cells.push_back(CellIdent(99, 99, 1)); + _vm->loadCells(cells); + + showAllItems(); + + if (!_invRefreshFlag) { + chooseItem(); + if (_vm->_useItem != -1) { + int savedScale = _vm->_scale; + _vm->_scale = 153; + _vm->_screen->setScaleTable(_vm->_scale); + _vm->_buffer1.clearBuffer(); + + SpriteResource *spr = _vm->_objectsTable[99]; + SpriteFrame *frame = spr->getFrame(_vm->_useItem); + + int w = screen._scaleTable1[46]; + int h = screen._scaleTable1[35]; + _vm->_buffer1.sPlotF(frame, Common::Rect(0, 0, w, h)); + events.setCursorData(&_vm->_buffer1, Common::Rect(0, 0, w, h)); + + _vm->_scale = savedScale; + screen.setScaleTable(_vm->_scale); + } + } + + freeInvCells(); + screen.setPanel(0); + events.debounceLeft(); + + restoreFields(); + screen.restorePalette(); + if (!screen._vesaMode && !_invRefreshFlag) { + screen.clearBuffer(); + screen.setPalette(); + } + + if (!room._tile && !_invRefreshFlag) { + _savedBuffer1.copyTo(&_vm->_buffer1); + _savedScreen.copyTo(_vm->_screen); + } else { + screen.setBufferScan(); + room.buildScreen(); + + if (!screen._vesaMode) { + screen.fadeOut(); + _vm->copyBF2Vid(); + } + } + + events._cursorExitFlag = false; + screen._screenChangeFlag = false; + _invModeFlag = false; + events.debounceLeft(); + _vm->_timers.restoreTimers(); + _vm->_startup = 1; + + int result = 0; + if (!_invRefreshFlag) { + if (_vm->_useItem == -1) { + result = 2; + } + } + + _invRefreshFlag = false; + _invChangeFlag = false; + return result; +} + +void InventoryManager::savedFields() { + Screen &screen = *_vm->_screen; + Room &room = *_vm->_room; + + _fields._vWindowHeight = screen._vWindowHeight; + _fields._vWindowLinesTall = screen._vWindowLinesTall; + _fields._vWindowWidth = screen._vWindowWidth; + _fields._vWindowBytesWide = screen._vWindowBytesWide; + _fields._playFieldHeight = room._playFieldHeight; + _fields._playFieldWidth = room._playFieldWidth; + _fields._windowXAdd = screen._windowXAdd; + _fields._windowYAdd = screen._windowYAdd; + _fields._screenYOff = screen._screenYOff; + _fields._scrollX = screen._scrollX; + _fields._scrollY = screen._scrollY; + _fields._clipWidth = screen._clipWidth; + _fields._clipHeight = screen._clipHeight; + _fields._bufferStart = screen._bufferStart; + _fields._scrollCol = screen._scrollCol; + _fields._scrollRow = screen._scrollRow; +} + +void InventoryManager::restoreFields() { + Screen &screen = *_vm->_screen; + Room &room = *_vm->_room; + + screen._vWindowHeight = _fields._vWindowHeight; + screen._vWindowLinesTall = _fields._vWindowLinesTall; + screen._vWindowWidth = _fields._vWindowWidth; + screen._vWindowBytesWide = _fields._vWindowBytesWide; + room._playFieldHeight = _fields._playFieldHeight; + room._playFieldWidth = _fields._playFieldWidth; + screen._windowXAdd = _fields._windowXAdd; + screen._windowYAdd = _fields._windowYAdd; + screen._screenYOff = _fields._screenYOff; + screen._scrollX = _fields._scrollX; + screen._scrollY = _fields._scrollY; + screen._clipWidth = _fields._clipWidth; + screen._clipHeight = _fields._clipHeight; + screen._bufferStart = _fields._bufferStart; + screen._scrollCol = _fields._scrollCol; + screen._scrollRow = _fields._scrollRow; +} + +void InventoryManager::initFields() { + Screen &screen = *_vm->_screen; + Room &room = *_vm->_room; + + screen._vWindowHeight = screen.h; + room._playFieldHeight = screen.h; + screen._vWindowLinesTall = screen.h; + screen._clipHeight = screen.h; + room._playFieldWidth = screen.w; + screen._vWindowWidth = screen.w; + screen._vWindowBytesWide = screen.w; + screen._clipWidth = screen.w; + + screen._windowXAdd = 0; + screen._windowYAdd = 0; + screen._screenYOff = 0; + screen._scrollX = screen._scrollY = 0; + screen._bufferStart.x = 0; + screen._bufferStart.y = 0; + + _vm->_buffer1.clearBuffer(); + _vm->_buffer2.clearBuffer(); + if (!_invRefreshFlag && !screen._vesaMode) + screen.clearBuffer(); + + screen.savePalette(); +} + +void InventoryManager::getList() { + _items.clear(); + for (uint i = 0; i < _inv.size(); ++i) { + if (_inv[i]) + _items.push_back(i); + } +} + +void InventoryManager::showAllItems() { + for (uint i = 0; i < _items.size(); ++i) + putInvIcon(i, _items[i]); +} + +void InventoryManager::putInvIcon(int itemIndex, int itemId) { + SpriteResource *spr = _vm->_objectsTable[99]; + assert(spr); + Common::Point pt((itemIndex % 6) * 46 + 23, (itemIndex / 6) * 35 + 15); + _vm->_buffer2.plotImage(spr, itemId, pt); + + if (_iconDisplayFlag) { + _vm->_buffer1.copyBlock(&_vm->_buffer2, Common::Rect(pt.x, pt.y, pt.x + 46, pt.y + 35)); + } +} + +void InventoryManager::chooseItem() { + _vm->_useItem = -1; + + error("TODO: chooseItem"); } +void InventoryManager::freeInvCells() { + delete _vm->_objectsTable[99]; + _vm->_objectsTable[99] = nullptr; +} } // End of namespace Access diff --git a/engines/access/inventory.h b/engines/access/inventory.h index dddfe2eda1..019d7f4215 100644 --- a/engines/access/inventory.h +++ b/engines/access/inventory.h @@ -28,10 +28,51 @@ #include "common/rect.h" #include "common/str-array.h" #include "access/data.h" +#include "access/asurface.h" namespace Access { class InventoryManager : public Manager { + struct SavedFields { + int _vWindowHeight; + int _vWindowLinesTall; + int _vWindowWidth; + int _vWindowBytesWide; + int _playFieldHeight; + int _playFieldWidth; + int _windowXAdd; + int _windowYAdd; + int _screenYOff; + int _scrollX; + int _scrollY; + int _clipWidth; + int _clipHeight; + Common::Point _bufferStart; + int _scrollCol; + int _scrollRow; + }; +private: + Common::Array _items; + ASurface _savedBuffer1; + ASurface _savedScreen; + SavedFields _fields; + bool _iconDisplayFlag; + + void savedFields(); + + void restoreFields(); + + void initFields(); + + void getList(); + + void showAllItems(); + + void putInvIcon(int itemIndex, int itemId); + + void chooseItem(); + + void freeInvCells(); public: Common::Array _inv; Common::StringArray _names; diff --git a/engines/access/resources.cpp b/engines/access/resources.cpp index f0d74ccd2a..e5a27a8ba1 100644 --- a/engines/access/resources.cpp +++ b/engines/access/resources.cpp @@ -89,4 +89,33 @@ const char *const GENERAL_MESSAGES[] = { GO_MESSAGE, TALK_MESSAGE, HELP_MESSAGE, HELP_MESSAGE, USE_MESSAGE }; +const int INVCOORDS[][4] = { + { 23, 68, 15, 49 }, + { 69, 114, 15, 49 }, + { 115, 160, 15, 49 }, + { 161, 206, 15, 49 }, + { 207, 252, 15, 49 }, + { 253, 298, 15, 49 }, + { 23, 68, 50, 84 }, + { 69, 114, 50, 84 }, + { 115, 160, 50, 84 }, + { 161, 206, 50, 84 }, + { 207, 252, 50, 84 }, + { 253, 298, 50, 84 }, + { 23, 68, 85, 119 }, + { 69, 114, 85, 119 }, + { 115, 160, 85, 119 }, + { 161, 206, 85, 119 }, + { 207, 252, 85, 119 }, + { 253, 298, 85, 119 }, + { 23, 68, 120, 154 }, + { 69, 114, 120, 154 }, + { 115, 160, 120, 154 }, + { 161, 206, 120, 154 }, + { 207, 252, 120, 154 }, + { 253, 298, 120, 154 }, + { 237, 298, 177, 193 }, + { 25, 85, 177, 193 } +}; + } // End of namespace Access diff --git a/engines/access/resources.h b/engines/access/resources.h index 241ed3a636..6fb781e0d1 100644 --- a/engines/access/resources.h +++ b/engines/access/resources.h @@ -58,6 +58,8 @@ extern const int RMOUSE[10][2]; extern const char *const GENERAL_MESSAGES[]; +extern const int INVCOORDS[][4]; + } // End of namespace Access #endif /* ACCESS_RESOURCES_H */ diff --git a/engines/access/room.cpp b/engines/access/room.cpp index 90ef3470db..a4be02d263 100644 --- a/engines/access/room.cpp +++ b/engines/access/room.cpp @@ -451,34 +451,28 @@ void Room::executeCommand(int commandId) { switch (commandId) { case 0: - _vm->_events->_normalMouse = CURSOR_LOOK; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_LOOK); break; case 2: - _vm->_events->_normalMouse = CURSOR_USE; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_USE); break; case 3: - _vm->_events->_normalMouse = CURSOR_TAKE; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_TAKE); break; case 4: - _vm->_events->_normalMouse = CURSOR_CROSSHAIRS; _vm->_events->setCursor(CURSOR_ARROW); if (_vm->_inventory->newDisplayInv() == 2) { commandOff(); return; } else { - warning("TODO: al = _useItem"); + // TODO: al = _useItem? } break; case 5: - _vm->_events->_normalMouse = CURSOR_CLIMB; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_CLIMB); break; case 6: - _vm->_events->_normalMouse = CURSOR_TALK; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_TALK); break; case 7: _vm->_events->_normalMouse = CURSOR_CROSSHAIRS; @@ -486,8 +480,7 @@ void Room::executeCommand(int commandId) { _vm->_scripts->searchForSequence(); roomMenu(); _selectCommand = -1; - _vm->_events->_normalMouse = CURSOR_CROSSHAIRS; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_CROSSHAIRS); _conFlag = true; while (_conFlag && !_vm->shouldQuit()) { @@ -497,8 +490,7 @@ void Room::executeCommand(int commandId) { _vm->_boxSelect = true; break; case 8: - _vm->_events->_normalMouse = CURSOR_HELP; - _vm->_events->_mouseMode = 0; + _vm->_events->setCursor(CURSOR_HELP); break; default: break; @@ -524,8 +516,7 @@ void Room::executeCommand(int commandId) { void Room::commandOff() { _selectCommand = -1; - _vm->_events->_normalMouse = CURSOR_CROSSHAIRS; - _vm->_events->_mouseMode = 4; + _vm->_events->setCursor(CURSOR_CROSSHAIRS); roomMenu(); } diff --git a/engines/access/room.h b/engines/access/room.h index d876a30875..6cd3b8cad0 100644 --- a/engines/access/room.h +++ b/engines/access/room.h @@ -76,7 +76,6 @@ private: protected: void loadRoomData(const byte *roomData); void setupRoom(); - void buildScreen(); /** * Free the playfield data @@ -141,8 +140,19 @@ public: */ void clearRoom(); + /** + * Builds up a game screen + */ + void buildScreen(); + + /** + * Draw a column of a game scene + */ void buildColumn(int playX, int screenX); + /** + * Draw a row of a game scene + */ void buildRow(int playY, int screenY); void init4Quads(); -- cgit v1.2.3