From c55ff57fc6111a3e67c598a3cca579392ce70d16 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sun, 7 Nov 2004 14:15:41 +0000 Subject: Initial inventory support. svn-id: r15723 --- saga/interface.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++-- saga/interface.h | 51 +++++++++++++++++-- saga/module.mk | 1 + saga/objectdata.cpp | 77 +++++++++++++++++++++++++++++ saga/objectdata.h | 46 ++++++++++++++++++ saga/resnames.h | 1 + saga/saga.cpp | 2 + saga/saga.h | 5 +- saga/sfuncs.cpp | 22 ++++++--- 9 files changed, 326 insertions(+), 17 deletions(-) create mode 100644 saga/objectdata.cpp create mode 100644 saga/objectdata.h (limited to 'saga') diff --git a/saga/interface.cpp b/saga/interface.cpp index fb6c550606..5b3a59f24d 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -31,6 +31,7 @@ #include "saga/console.h" #include "saga/font.h" #include "saga/objectmap.h" +#include "saga/objectdata.h" #include "saga/rscfile_mod.h" #include "saga/scene.h" #include "saga/script.h" @@ -69,7 +70,18 @@ static INTERFACE_DESC ITE_interface = { ITE_LPORTRAIT_X, ITE_LPORTRAIT_Y, ITE_RPORTRAIT_X, - ITE_RPORTRAIT_Y + ITE_RPORTRAIT_Y, + + ITE_INVENTORY_XSTART, + ITE_INVENTORY_YSTART, + ITE_INVENTORY_ROWS, + ITE_INVENTORY_COLUMNS, + ITE_INVENTORY_ICON_WIDTH, + ITE_INVENTORY_ICON_HEIGHT, + ITE_INVENTORY_ICON_XOFFSET, + ITE_INVENTORY_ICON_YOFFSET, + ITE_INVENTORY_XSPACING, + ITE_INVENTORY_YSPACING }; static INTERFACE_BUTTON ITE_c_buttons[] = { @@ -113,7 +125,18 @@ static INTERFACE_DESC IHNM_interface = { IHNM_LPORTRAIT_X, IHNM_LPORTRAIT_Y, IHNM_RPORTRAIT_X, - IHNM_RPORTRAIT_Y + IHNM_RPORTRAIT_Y, + + IHNM_INVENTORY_XSTART, + IHNM_INVENTORY_YSTART, + IHNM_INVENTORY_ROWS, + IHNM_INVENTORY_COLUMNS, + IHNM_INVENTORY_ICON_WIDTH, + IHNM_INVENTORY_ICON_HEIGHT, + IHNM_INVENTORY_ICON_XOFFSET, + IHNM_INVENTORY_ICON_YOFFSET, + IHNM_INVENTORY_XSPACING, + IHNM_INVENTORY_YSPACING }; static INTERFACE_BUTTON IHNM_c_buttons[] = { @@ -221,10 +244,19 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { _panelMode = kPanelNone; *_statusText = 0; + _inventoryCount = 0; + _inventorySize = ITE_INVENTORY_SIZE; + + _inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16)); + if (_inventory == NULL) { + return; + } + _initialized = true; } Interface::~Interface(void) { + free(_inventory); _initialized = false; } @@ -344,6 +376,8 @@ int Interface::draw() { _vm->_sprite->draw(back_buf, _scenePortraits, _rightPortrait, rportrait_x, rportrait_y); } + drawInventory(); + return SUCCESS; } @@ -480,6 +514,13 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { int color; int i; + hit_button = inventoryTest(imousePt, &ibutton_num); + + if (hit_button == SUCCESS) { + // Hovering over an inventory object + return SUCCESS; + } + hit_button = hitTest(imousePt, &ibutton_num); if (hit_button == SUCCESS) { @@ -575,7 +616,6 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) { } object_flags = _vm->_scene->_objectMap->getFlags(objectNum); - object_name = _vm->_scene->_objectMap->getName(objectNum); if (object_flags & OBJECT_EXIT) { // FIXME. This is wrong @@ -619,4 +659,96 @@ int Interface::hitTest(const Point& imousePt, int *ibutton) { return FAILURE; } +void Interface::addToInventory(int sprite) { + if (_inventoryCount < _inventorySize) { + for (int i = _inventoryCount; i > 0; i--) { + _inventory[i] = _inventory[i - 1]; + } + + _inventory[0] = sprite; + _inventoryCount++; + draw(); + } +} + +void Interface::removeFromInventory(int sprite) { + for (int i = 0; i < _inventoryCount; i++) { + if (_inventory[i] == sprite) { + int j; + + for (j = i; i < _inventoryCount; j++) { + _inventory[j] = _inventory[j + 1]; + } + + _inventory[j] = 0; + _inventoryCount--; + draw(); + return; + } + } +} + +void Interface::drawInventory() { + if (_panelMode != kPanelCommand) + return; + + SURFACE *back_buf = _vm->_gfx->getBackBuffer(); + + // TODO: Inventory scrolling + + int row = 0; + int col = 0; + + int x = _iDesc.inv_xstart + _iDesc.inv_icon_xoffset; + int y = _iDesc.inv_ystart + _iDesc.inv_icon_yoffset; + int width = _iDesc.inv_icon_width + _iDesc.inv_xspacing; + int height = _iDesc.inv_icon_height + _iDesc.inv_yspacing; + + for (int i = 0; i < _inventoryCount; i++) { + if (_inventory[i] >= ARRAYSIZE(ObjectTable)) { + continue; + } + + _vm->_sprite->draw(back_buf, _vm->_mainSprites, + ObjectTable[_inventory[i]].spritelistRn, + x + col * width, y + row * height); + + if (++col >= _iDesc.inv_columns) { + if (++row >= _iDesc.inv_rows) { + break; + } + col = 0; + } + } +} + +int Interface::inventoryTest(const Point& imousePt, int *ibutton) { + int row = 0; + int col = 0; + + int xbase = _iDesc.inv_xstart; + int ybase = _iDesc.inv_ystart; + int width = _iDesc.inv_icon_width + _iDesc.inv_xspacing; + int height = _iDesc.inv_icon_height + _iDesc.inv_yspacing; + + for (int i = 0; i < _inventoryCount; i++) { + int x = xbase + col * width; + int y = ybase + row * height; + + if (imousePt.x >= x && imousePt.x < x + _iDesc.inv_icon_width && imousePt.y >= y && imousePt.y < y + _iDesc.inv_icon_height) { + *ibutton = i; + return SUCCESS; + } + + if (++col >= _iDesc.inv_columns) { + if (++row >= _iDesc.inv_rows) { + break; + } + col = 0; + } + } + + return FAILURE; +} + } // End of namespace Saga diff --git a/saga/interface.h b/saga/interface.h index fc820de12d..a391b5546b 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -36,6 +36,8 @@ enum INTERFACE_UPDATE_FLAGS { UPDATE_MOUSECLICK }; +#define ITE_INVENTORY_SIZE 24 + #define VERB_STRLIMIT 32 #define STATUS_TEXT_LEN 128 @@ -59,6 +61,17 @@ enum INTERFACE_UPDATE_FLAGS { #define ITE_RPORTRAIT_X 274 #define ITE_RPORTRAIT_Y 4 +#define ITE_INVENTORY_XSTART 181 +#define ITE_INVENTORY_YSTART 155 +#define ITE_INVENTORY_ROWS 2 +#define ITE_INVENTORY_COLUMNS 4 +#define ITE_INVENTORY_ICON_WIDTH 29 +#define ITE_INVENTORY_ICON_HEIGHT 20 +#define ITE_INVENTORY_ICON_XOFFSET 1 +#define ITE_INVENTORY_ICON_YOFFSET 0 +#define ITE_INVENTORY_XSPACING 3 +#define ITE_INVENTORY_YSPACING 1 + // IHNMAIMS interface values #define IHNM_STATUS_Y 304 #define IHNM_STATUS_W 640 @@ -76,6 +89,18 @@ enum INTERFACE_UPDATE_FLAGS { #define IHNM_RPORTRAIT_X -1 #define IHNM_RPORTRAIT_Y -1 +// TODO +#define IHNM_INVENTORY_XSTART 0 +#define IHNM_INVENTORY_YSTART 0 +#define IHNM_INVENTORY_ROWS 0 +#define IHNM_INVENTORY_COLUMNS 0 +#define IHNM_INVENTORY_ICON_WIDTH 0 +#define IHNM_INVENTORY_ICON_HEIGHT 0 +#define IHNM_INVENTORY_ICON_XOFFSET 0 +#define IHNM_INVENTORY_ICON_YOFFSET 0 +#define IHNM_INVENTORY_XSPACING 0 +#define IHNM_INVENTORY_YSPACING 0 + enum PANEL_MODES { kPanelNone, kPanelCommand, @@ -87,7 +112,6 @@ enum BUTTON_FLAGS { BUTTON_LABEL = 0x01, BUTTON_BITMAP = 0x02, BUTTON_SET = 0x04 - }; #define BUTTON_VERB ( BUTTON_LABEL | BUTTON_BITMAP | BUTTON_SET ) @@ -134,6 +158,16 @@ struct INTERFACE_DESC { int lportrait_y; int rportrait_x; int rportrait_y; + int inv_xstart; + int inv_ystart; + int inv_rows; + int inv_columns; + int inv_icon_width; + int inv_icon_height; + int inv_icon_xoffset; + int inv_icon_yoffset; + int inv_xspacing; + int inv_yspacing; }; struct INTERFACE_MODULE { @@ -158,7 +192,7 @@ struct VERB_DATA { }; class Interface { - public: +public: Interface(SagaEngine *vm); ~Interface(void); @@ -174,8 +208,11 @@ class Interface { int draw(); int update(const Point& imousePt, int update_flag); - - private: + void addToInventory(int sprite); + void removeFromInventory(int sprite); + void drawInventory(); + int inventoryTest(const Point& imousePt, int *ibutton); +private: int hitTest(const Point& imousePt, int *ibutton); int drawStatusBar(SURFACE *ds); int handleCommandUpdate(SURFACE *ds, const Point& imousePt); @@ -183,7 +220,7 @@ class Interface { int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt); int handlePlayfieldClick(SURFACE *ds, const Point& imousePt); - private: +private: SagaEngine *_vm; bool _initialized; @@ -200,6 +237,10 @@ class Interface { SPRITELIST *_scenePortraits; int _activeVerb; SCRIPT_THREAD *_iThread; + + uint16 *_inventory; + int _inventorySize; + byte _inventoryCount; }; } // End of namespace Saga diff --git a/saga/module.mk b/saga/module.mk index ada12ae01e..67425fbb83 100644 --- a/saga/module.mk +++ b/saga/module.mk @@ -18,6 +18,7 @@ MODULE_OBJS := \ saga/interface.o \ saga/isomap.o \ saga/ite_introproc.o \ + saga/objectdata.o \ saga/objectmap.o \ saga/palanim.o \ saga/render.o \ diff --git a/saga/objectdata.cpp b/saga/objectdata.cpp new file mode 100644 index 0000000000..8a125a28e0 --- /dev/null +++ b/saga/objectdata.cpp @@ -0,0 +1,77 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 The ScummVM project + * + * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +// Actor data table +#include "saga/saga.h" +#include "saga/objectdata.h" + +namespace Saga { + +enum { + kObjUseWith = 0x01, + kObjNotFlat = 0x02 +}; + +OBJECTTABLE ObjectTable[OBJECTCOUNT] = { + { 8, 49, 1256, 760, 0, 9, 5, kObjNotFlat }, // Magic Hat + { 9, 52, 1080, 1864, 0, 10, 4, kObjUseWith }, // Berries + { 10, 259, 744, 524, 0, 11, 42, kObjUseWith }, // Card Key + { 11, 0, 480, 480, 0, 12, 6, 0 }, // Foot Print + { 12, 0, 480, 480, 0, 13, 38, kObjUseWith }, // Power Cell + { 13, 28, 640, 412, 40, 14, 15, kObjUseWith }, // Digital Clock + { 14, 0, 480, 480, 0, 15, 41, kObjUseWith }, // Oil Lamp + { 15, 24, 868, 456, 35, 16, 13, kObjUseWith }, // Magnetic Key + { 16, 0, 480, 480, 0, 17, 7, kObjUseWith }, // Plaster + { 17, 249, 320, 476, 45, 18, 44, 0 }, // Trophy + { 18, 0, 480, 480, 0, 19, 20, 0 }, // Coins + { 19, 19, 600, 480, 0, 20, 8, 0 }, // Lens Fragments + { 20, 0, 1012, 568, 80, 21, 10, kObjUseWith }, // Key to jail cell + { 21, 0, 480, 480, 0, 22, 9, 0 }, // Remade lens + { 22, 0, 480, 480, 0, 23, 21, 0 }, // Tycho's Map + { 23, 0, 480, 480, 0, 24, 23, 0 }, // Silver Medallion + { 24, 0, 480, 480, 0, 25, 24, 0 }, // Mud in Fur + { 25, 0, 480, 480, 0, 26, 25, 0 }, // Gold Ring + { 27, 13, 1036, 572, 0, 47, 14, kObjUseWith }, // Screwdriver + { 28, 0, 480, 480, 0, 29, 26, 0 }, // Apple Token + { 29, 0, 480, 480, 0, 30, 22, kObjUseWith }, // Letter from Elara + { 30, 0, 164, 440, 0, 31, 16, kObjUseWith }, // Spoon + { 32, 0, 480, 480, 0, 33, 43, 0 }, // Catnip + { 33, 31, 580, 392, 0, 45, 11, 0 }, // Twigs + { 35, 0, 468, 480, 0, 36, 12, kObjUseWith }, // Empty Bowl (also bowl of honey) + { 37, 0, 480, 480, 0, 38, 45, kObjUseWith }, // Needle and Thread + { 38, 25, 332, 328, 0, 39, 19, 0 }, // Rock Crystal + { 39, 0, 480, 480, 0, 40, 0, kObjUseWith }, // Salve + { 40, 269, 644, 416, 0, 41, 39, kObjNotFlat }, // Electrical Cable + { 41, 12, 280, 516, 0, 42, 17, kObjUseWith }, // Piece of flint + { 42, 5, 876, 332, 32, 65, 18, 0 }, // Rat Cloak + { 43, 52, 556, 1612, 0, 49, 28, kObjUseWith | kObjNotFlat }, // Bucket + { 48, 52, 732, 948, 0, 50, 27, kObjUseWith }, // Cup + { 49, 52, 520, 1872, 0, 53, 29, 0 }, // Fertilizer + { 50, 52, 1012, 1268, 0, 52, 30, 0 }, // Feeder + { 51, 252, -20, -20, 0, 71, 32, kObjUseWith | kObjNotFlat }, // Bowl in jail cell + { 53, 252, 1148, 388, 0, 70, 33, 0 }, // Loose stone block in jail cell + { 26, 12, 496, 368, 0, 76, 31, 0 }, // Coil of Rope from Quarry + { 54, 281, 620, 352, 0, 80, 46, 0 } // Orb of Storms in Dam Lab +}; + +} // End of namespace Saga diff --git a/saga/objectdata.h b/saga/objectdata.h new file mode 100644 index 0000000000..621e299cdb --- /dev/null +++ b/saga/objectdata.h @@ -0,0 +1,46 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 The ScummVM project + * + * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +// Actor data table header file + +#ifndef SAGA_OBJECTDATA_H +#define SAGA_OBJECTDATA_H + +namespace Saga { + +struct OBJECTTABLE { + byte nameIndex; + int32 sceneIndex; + int16 x, y, z; + int32 spritelistRn; + byte scriptRn; + uint16 interactBits; +}; + +#define OBJECTCOUNT 39 + +extern OBJECTTABLE ObjectTable[OBJECTCOUNT]; + +#endif + +} // End of namespace Saga diff --git a/saga/resnames.h b/saga/resnames.h index 0d038d9a6e..95f35d1b65 100644 --- a/saga/resnames.h +++ b/saga/resnames.h @@ -51,6 +51,7 @@ namespace Saga { #define IHNM_DIALOGUE_PANEL 10 #define ITE_SETUP_PANEL 5 +#define ITE_MAIN_SPRITES 6 #define ITE_COMMAND_BUTTONSPRITES 7 #define ITE_DEFAULT_PORTRAITS 125 diff --git a/saga/saga.cpp b/saga/saga.cpp index 4b997887b7..42f9b6a5e3 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -210,6 +210,8 @@ void SagaEngine::go() { _previousTicks = _system->getMillis(); + _sprite->loadList(ITE_MAIN_SPRITES, &_mainSprites); + // Begin Main Engine Loop _scene->startScene(); diff --git a/saga/saga.h b/saga/saga.h index 7c209a3afb..8b68088afa 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -65,6 +65,7 @@ using Common::MemoryReadStream; struct RSCFILE_CONTEXT; struct SEMAPHORE; +struct SPRITELIST; enum ERRORCODE { MEM = -2, @@ -115,7 +116,9 @@ public: Console *_console; Events *_events; PalAnim *_palanim; - + + SPRITELIST *_mainSprites; + /** Random number generator */ Common::RandomSource _rnd; diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index b22de449a8..e1e0450e89 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -31,6 +31,7 @@ #include "saga/console.h" #include "saga/interface.h" #include "saga/music.h" +#include "saga/objectdata.h" #include "saga/sound.h" #include "saga/sndres.h" @@ -155,23 +156,28 @@ int Script::SF_sleep(SCRIPTFUNC_PARAMS) { // Script function #2 (0x02) int Script::SF_takeObject(SCRIPTFUNC_PARAMS) { SDataWord_T param = thread->pop(); + int index = param & 0x1FFF; + + if (ObjectTable[index].sceneIndex != -1) { + ObjectTable[index].sceneIndex = -1; + _vm->_interface->addToInventory(index); + } - debug(1, "stub: SF_takeObject(%d)", param); return SUCCESS; } // Script function #3 (0x03) // Check if an object is carried. int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) { - // INCOMPLETE - SDataWord_T param1; - param1 = thread->pop(); - - // FIXME: Incomplete, but returning 0 assures that the fair start - // script will run completely. + SDataWord_T param = thread->pop(); + int index = param & 0x1FFF; - thread->retVal = 0; + if (index >= ARRAYSIZE(ObjectTable)) { + thread->retVal = 0; + return FAILURE; + } + thread->retVal = (ObjectTable[index].sceneIndex == -1) ? 1 : 0; return SUCCESS; } -- cgit v1.2.3