aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/inventory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/inventory.cpp')
-rw-r--r--engines/parallaction/inventory.cpp330
1 files changed, 183 insertions, 147 deletions
diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp
index 4e34325404..2b4989bb08 100644
--- a/engines/parallaction/inventory.cpp
+++ b/engines/parallaction/inventory.cpp
@@ -47,142 +47,174 @@ namespace Parallaction {
#define INVENTORY_WIDTH (INVENTORY_ITEMS_PER_LINE*INVENTORYITEM_WIDTH)
#define INVENTORY_HEIGHT (INVENTORY_LINES*INVENTORYITEM_HEIGHT)
-static byte *_buffer;
-uint16 _numInvLines = 0;
-static Common::Point _invPosition;
-
-InventoryItem _inventory[INVENTORY_MAX_ITEMS] = {
- { kZoneDoor, 1 }, // open/close icon
- { kZoneExamine, 3 }, // examine icon
- { kZoneGet, 2 }, // pick up/use icon
- { kZoneSpeak, 4 }, // speak icon
- { 0, 0 }, // items...
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-};
-
-
-int16 getNumUsedSlots() {
- int16 num = 0;
- while (num < INVENTORY_MAX_ITEMS && _inventory[num]._id != 0)
- num++;
- return num;
-}
-
+Inventory *_inv = 0;
+InventoryRenderer *_re = 0;
// get inventory item index at position (x,y)
// in screen coordinates
//
int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) {
+ return _re->hitTest(Common::Point(x,y));
+}
- int16 slot = getNumUsedSlots();
- slot = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
- Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
- r.moveTo(_invPosition);
+int Parallaction::addInventoryItem(ItemName item) {
+ return _inv->addItem(item);
+}
- if (!r.contains(Common::Point(x,y)))
- return -1;
+int Parallaction::addInventoryItem(ItemName item, uint32 value) {
+ return _inv->addItem(item, value);
+}
+
+void Parallaction::dropItem(uint16 v) {
+ printf("dropItem: %i (# = %i)\n", v, _inv->getNumItems());
+ _inv->removeItem(v);
+ printf("# = %i\n", _inv->getNumItems());
+}
- return ((x - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT));
+bool Parallaction::isItemInInventory(int32 v) {
+ return (_inv->findItem(v) != -1);
}
-void drawInventoryItem(uint16 pos, InventoryItem *item) {
+const InventoryItem* getInventoryItem(int16 pos) {
+ return _inv->getItem(pos);
+}
- uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
- uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
+int16 getInventoryItemIndex(int16 pos) {
+ return _inv->getItemName(pos);
+}
+
+void initInventory() {
+ _inv = new Inventory(INVENTORY_MAX_ITEMS);
+ _re = new InventoryRenderer(_vm);
+ _re->bindInventory(_inv);
+}
+void destroyInventory() {
+ delete _inv;
+ delete _re;
+}
+
+void cleanInventory(bool keepVerbs) {
+ _inv->clear(keepVerbs);
+}
+
+
+
+
+
+void Parallaction_ns::jobShowInventory(void *parm, Job *j) {
Common::Rect r;
- _vm->_char._objs->getRect(0, r);
+ _re->getRect(r);
+ _gfx->copyRect(Gfx::kBitBack, r, _re->getData(), INVENTORY_WIDTH);
+}
- // FIXME: this will end up in a general blit function
- byte* s = _vm->_char._objs->getData(item->_index);
- byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * r.height() * INVENTORY_WIDTH;
- for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
- memcpy(d, s, INVENTORYITEM_WIDTH);
+void Parallaction_ns::jobHideInventory(void *parm, Job *j) {
+ static uint16 count = 0;
+ _engineFlags |= kEngineBlockInput;
- d += INVENTORY_WIDTH;
- s += INVENTORYITEM_PITCH;
+ count++;
+ if (count == 2) {
+ count = 0;
+ j->_finished = 1;
+ _engineFlags &= ~kEngineBlockInput;
}
- return;
+ Common::Rect r;
+ _re->getRect(r);
+ _gfx->restoreBackground(r);
}
+void openInventory() {
+ _re->showInventory();
+}
+void closeInventory() {
+ _re->hideInventory();
+}
-void refreshInventory() {
- for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++)
- drawInventoryItem(i, &_inventory[i]);
- return;
+
+InventoryRenderer::InventoryRenderer(Parallaction *vm) : _vm(vm) {
+ _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT);
}
-int Parallaction::addInventoryItem(uint16 item) {
+InventoryRenderer::~InventoryRenderer() {
+ if (_buffer)
+ free(_buffer);
+ _buffer = 0;
+}
- int16 slot = getNumUsedSlots();
- if (slot == INVENTORY_MAX_ITEMS)
- return -1;
+void InventoryRenderer::showInventory() {
+ if (!_inv)
+ error("InventoryRenderer not bound to inventory");
- _inventory[slot]._id = MAKE_INVENTORY_ID(item);
- _inventory[slot]._index = item;
+ _engineFlags |= kEngineInventory;
- return 0;
-}
+ uint16 lines = getNumLines();
+ _pos.x = CLIP(_vm->_mousePos.x - (INVENTORY_WIDTH / 2), 0, (int)(_vm->_screenWidth - INVENTORY_WIDTH));
+ _pos.y = CLIP(_vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, (int)(_vm->_screenHeight - lines * INVENTORYITEM_HEIGHT));
-void Parallaction::dropItem(uint16 v) {
+ refresh();
+}
- bool found = false;
- for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS - 1; slot++) {
+void InventoryRenderer::hideInventory() {
+ if (!_inv)
+ error("InventoryRenderer not bound to inventory");
- if (v == _inventory[slot]._index) {
- found = true;
- }
+ _engineFlags &= ~kEngineInventory;
+}
- if (!found) continue;
+void InventoryRenderer::getRect(Common::Rect& r) const {
+ r.setWidth(INVENTORY_WIDTH);
+ r.setHeight(INVENTORYITEM_HEIGHT * getNumLines());
+ r.moveTo(_pos);
+}
- memcpy(&_inventory[slot], &_inventory[slot+1], sizeof(InventoryItem));
- }
+ItemPosition InventoryRenderer::hitTest(const Common::Point &p) const {
+ Common::Rect r;
+ getRect(r);
+ if (!r.contains(p))
+ return -1;
- return;
+ return ((p.x - _pos.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((p.y - _pos.y) / INVENTORYITEM_HEIGHT));
}
-int16 Parallaction::isItemInInventory(int32 v) {
+void InventoryRenderer::drawItem(ItemPosition pos, ItemName name) {
+ uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
+ uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
- for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS; slot++) {
- if (_inventory[slot]._id == (uint)v)
- return 1;
+ Common::Rect r;
+ _vm->_char._objs->getRect(0, r);
+
+ // FIXME: this will end up in a general blit function
+
+ byte* s = _vm->_char._objs->getData(name);
+ byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * r.height() * INVENTORY_WIDTH;
+ for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
+ memcpy(d, s, INVENTORYITEM_WIDTH);
+
+ d += INVENTORY_WIDTH;
+ s += INVENTORYITEM_PITCH;
}
+}
- return 0;
+int16 InventoryRenderer::getNumLines() const {
+ int16 num = _inv->getNumItems();
+ return (num / INVENTORY_ITEMS_PER_LINE) + ((num % INVENTORY_ITEMS_PER_LINE) > 0 ? 1 : 0);
}
+void InventoryRenderer::refresh() {
+ for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) {
+ ItemName name = _inv->getItemName(i);
+ drawItem(i, name);
+ }
+}
+
void drawBorder(const Common::Rect& r, byte *buffer, byte color) {
byte *d = buffer + r.left + INVENTORY_WIDTH * r.top;
@@ -203,12 +235,14 @@ void drawBorder(const Common::Rect& r, byte *buffer, byte color) {
//
// draws a color border around the specified position in the inventory
//
-void highlightInventoryItem(int16 pos, byte color) {
+void highlightInventoryItem(ItemPosition pos, byte color) {
if (color != 12) color = 19;
if (pos == -1) return;
+ printf("highlight item: %i\n", pos);
+
uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
@@ -217,102 +251,104 @@ void highlightInventoryItem(int16 pos, byte color) {
r.setWidth(INVENTORYITEM_WIDTH);
r.moveTo(col * INVENTORYITEM_WIDTH, line * r.height());
- drawBorder(r, _buffer, color);
+ drawBorder(r, _re->getData(), color);
return;
}
-int16 getInventoryItemIndex(int16 pos) {
- // TODO: should assert against the number of items actually contained,
- // not the theoretical limit.
- assert(pos >= 0 && pos < INVENTORY_MAX_ITEMS);
- return _inventory[pos]._index;
-}
-void Parallaction_ns::jobShowInventory(void *parm, Job *j) {
-// printf("job_showInventory()...");
- int16 slot = getNumUsedSlots();
- _numInvLines = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
- Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
- r.moveTo(_invPosition);
- _gfx->copyRect(Gfx::kBitBack, r, _buffer, INVENTORY_WIDTH);
- return;
-}
+Inventory::Inventory(uint16 maxItems) : _maxItems(maxItems), _numItems(0) {
+ _items = (InventoryItem*)calloc(_maxItems, sizeof(InventoryItem));
+ addItem(1, kZoneDoor);
+ addItem(3, kZoneExamine);
+ addItem(2, kZoneGet);
+ addItem(4, kZoneSpeak);
+}
-void Parallaction_ns::jobHideInventory(void *parm, Job *j) {
-// printf("job_hideInventory()\n");
- static uint16 count = 0;
+Inventory::~Inventory() {
+ free(_items);
+}
- _engineFlags |= kEngineBlockInput;
+ItemPosition Inventory::addItem(ItemName name, uint32 value) {
+ if (_numItems == INVENTORY_MAX_ITEMS)
+ return -1;
- count++;
- if (count == 2) {
- count = 0;
- j->_finished = 1;
- _engineFlags &= ~kEngineBlockInput;
- }
+ if (name == 0)
+ return -1;
- Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
- r.moveTo(_invPosition);
+ _items[_numItems]._id = value;
+ _items[_numItems]._index = name;
- _gfx->restoreBackground(r);
+ _numItems++;
- return;
+ return _numItems;
}
+ItemPosition Inventory::addItem(ItemName name) {
+ return addItem(name, MAKE_INVENTORY_ID(name));
+}
+ItemPosition Inventory::findItem(ItemName name) const {
+ for (ItemPosition slot = 0; slot < _numItems; slot++) {
+ if (name == _items[slot]._index)
+ return slot;
+ }
-void openInventory() {
- _engineFlags |= kEngineInventory;
-
- int16 slot = getNumUsedSlots();
- uint16 lines = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
+ return -1;
+}
- _invPosition.x = CLIP(_vm->_mousePos.x - (INVENTORY_WIDTH / 2), 0, (int)(_vm->_screenWidth - INVENTORY_WIDTH));
- _invPosition.y = CLIP(_vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, (int)(_vm->_screenHeight - lines * INVENTORYITEM_HEIGHT));
+void Inventory::removeItem(ItemName name) {
+ ItemPosition pos = findItem(name);
+ if (pos == -1) {
+ printf("removeItem: name %i not found\n", name);
+ return;
+ }
- refreshInventory();
+ _numItems--;
- return;
+ if (_numItems != pos) {
+ memcpy(&_items[pos], &_items[pos+1], (_numItems - pos) * sizeof(InventoryItem));
+ }
+ _items[_numItems]._id = 0;
+ _items[_numItems]._index = 0;
}
+void Inventory::clear(bool keepVerbs) {
+ uint first = (keepVerbs ? INVENTORY_FIRST_ITEM : 0);
+ for (uint16 slot = first; slot < _maxItems; slot++) {
+ _items[slot]._id = 0;
+ _items[slot]._index = 0;
+ }
-void closeInventory() {
- _engineFlags &= ~kEngineInventory;
+ _numItems = first;
}
-void initInventory() {
- _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT);
-}
-void destroyInventory() {
- if (_buffer)
- free(_buffer);
- _buffer = 0;
+ItemName Inventory::getItemName(ItemPosition pos) const {
+ // TODO: should assert against the number of items actually contained,
+ // not the theoretical limit.
+ assert(pos >= 0 && pos < INVENTORY_MAX_ITEMS);
+ return _items[pos]._index;
}
-void cleanInventory() {
+const InventoryItem* Inventory::getItem(ItemPosition pos) const {
+ return &_items[pos];
+}
- for (uint16 slot = INVENTORY_FIRST_ITEM; slot < INVENTORY_MAX_ITEMS; slot++) {
- _inventory[slot]._id = 0;
- _inventory[slot]._index = 0;
- }
- return;
-}
} // namespace Parallaction