aboutsummaryrefslogtreecommitdiff
path: root/engines/teenagent/inventory.cpp
diff options
context:
space:
mode:
authorVladimir Menshakov2009-09-03 20:59:17 +0000
committerVladimir Menshakov2009-09-03 20:59:17 +0000
commitebe1b94eb1561b566124b7dcbb73cf3b0a659b33 (patch)
treed4f182bc5b5b46ce5933913a1a8066dc089889ea /engines/teenagent/inventory.cpp
parent9b2104db32d074886daa0ec48624193351d6ed51 (diff)
downloadscummvm-rg350-ebe1b94eb1561b566124b7dcbb73cf3b0a659b33.tar.gz
scummvm-rg350-ebe1b94eb1561b566124b7dcbb73cf3b0a659b33.tar.bz2
scummvm-rg350-ebe1b94eb1561b566124b7dcbb73cf3b0a659b33.zip
imported teenagent engine sources.
svn-id: r43922
Diffstat (limited to 'engines/teenagent/inventory.cpp')
-rw-r--r--engines/teenagent/inventory.cpp285
1 files changed, 285 insertions, 0 deletions
diff --git a/engines/teenagent/inventory.cpp b/engines/teenagent/inventory.cpp
new file mode 100644
index 0000000000..6ee720d3f5
--- /dev/null
+++ b/engines/teenagent/inventory.cpp
@@ -0,0 +1,285 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://www.switchlink.se/svn/teen/objects.h $
+ * $Id: objects.h 172 2009-08-11 08:06:58Z megath $
+ */
+
+#include "inventory.h"
+#include "resources.h"
+#include "common/stream.h"
+#include "objects.h"
+#include "teenagent.h"
+
+using namespace TeenAgent;
+
+void Inventory::init(TeenAgentEngine * engine) {
+ _engine = engine;
+ _active = false;
+ Resources * res = Resources::instance();
+
+ Common::SeekableReadStream * s = res->varia.getStream(3);
+ assert(s != NULL);
+ debug(0, "loading inventory background...");
+ background.load(s, Surface::TypeOns);
+
+ items = res->varia.getStream(4);
+ assert(items != NULL);
+
+ byte offsets = items->readByte();
+ assert(offsets == 92);
+ for(byte i = 0; i < offsets; ++i) {
+ offset[i] = items->readUint16LE();
+ }
+ objects = res->dseg.ptr(0xc4a4);
+ inventory = res->dseg.ptr(0xc48d);
+
+ for(int y = 0; y < 4; ++y)
+ for(int x = 0; x < 6; ++x) {
+ int i = y * 6 + x;
+ graphics[i].rect.left = 28 + 45 * x - 1;
+ graphics[i].rect.top = 23 + 31 * y - 1;
+ graphics[i].rect.right = graphics[i].rect.left + 40;
+ graphics[i].rect.bottom = graphics[i].rect.top + 26;
+ }
+
+ hovered_obj = selected_obj = NULL;
+}
+
+bool Inventory::has(byte item) const {
+ for(int i = 0; i < 24; ++i) {
+ if (inventory[i] == item)
+ return true;
+ }
+ return false;
+}
+
+void Inventory::remove(byte item) {
+ debug(0, "removing %02x from inventory", item);
+ int i;
+ for(i = 0; i < 24; ++i) {
+ if (inventory[i] == item) {
+ break;
+ }
+ }
+ for(; i < 23; ++i) {
+ inventory[i] = inventory[i + 1];
+ graphics[i].free();
+ }
+ inventory[23] = 0;
+ graphics[23].free();
+}
+
+void Inventory::clear() {
+ debug(0, "clearing inventory");
+ for(int i = 0; i < 24; ++i) {
+ inventory[i] = 0;
+ graphics[i].free();
+ }
+}
+
+
+void Inventory::add(byte item) {
+ if (has(item))
+ return;
+ debug(0, "adding %02x to inventory", item);
+ for(int i = 0; i < 24; ++i) {
+ if (inventory[i] == 0) {
+ inventory[i] = item;
+ return;
+ }
+ }
+ error("no room for item %02x", item);
+}
+
+bool Inventory::processEvent(const Common::Event &event) {
+ Resources * res = Resources::instance();
+
+ switch(event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ mouse = event.mouse;
+ if (!active() && event.mouse.y < 5) {
+ activate(true);
+ return _active;
+ }
+
+ if (event.mouse.x < 17 || event.mouse.x >= 303 || event.mouse.y >= 153) {
+ activate(false);
+ return _active;
+ }
+
+ if (!_active)
+ return false;
+
+ hovered_obj = NULL;
+
+ for(int i = 0; i < 24; ++i) {
+ byte item = inventory[i];
+ if (item == 0)
+ continue;
+
+ graphics[i].hovered = graphics[i].rect.in(mouse);
+ if (graphics[i].hovered)
+ hovered_obj = (InventoryObject *)res->dseg.ptr(READ_LE_UINT16(objects + item * 2));
+ }
+ return true;
+
+ case Common::EVENT_LBUTTONDOWN: {
+ //check combine
+ if (selected_obj == NULL || hovered_obj == NULL)
+ return _active;
+
+ int id1 = selected_obj->id;
+ int id2 = hovered_obj->id;
+
+ debug(0, "combine(0x%02x, 0x%02x)!", id1, id2);
+ byte * table = res->dseg.ptr(0xC335);
+ while(table[0] != 0 && table[1] != 0) {
+ if (
+ (id1 == table[0] && id2 == table[1]) ||
+ (id2 == table[0] && id1 == table[1])
+ ) {
+ remove(id1);
+ remove(id2);
+ add(table[2]);
+ uint16 msg = READ_LE_UINT16(table + 3);
+ _engine->displayMessage(msg);
+ _engine->playSoundNow(69);
+ activate(false);
+ resetSelectedObject();
+ return true;
+ }
+ table += 5;
+ }
+ _engine->displayMessage(0xc3e2);
+ activate(false);
+ resetSelectedObject();
+ return true;
+ }
+
+ case Common::EVENT_RBUTTONDOWN:
+ if (!_active)
+ return false;
+
+ if (hovered_obj != NULL) {
+ byte id = hovered_obj->id;
+ debug(0, "rclick object %u", id);
+ uint i = 0;
+ for(byte * table = res->dseg.ptr(0xBB6F + 3); //original offset + 3 bytes.
+ table[0] != 0 && i < 7; table += 3, ++i) {
+ if (table[0] == id) {
+ resetSelectedObject();
+ activate(false);
+ if (_engine->processCallback(READ_LE_UINT16(table + 1)))
+ return true;
+ else {
+ //some callbacks returns false if they need to display default description
+ _engine->displayMessage(hovered_obj->description());
+ activate(false);
+ resetSelectedObject();
+ return true;
+ }
+ }
+ }
+ }
+
+ selected_obj = hovered_obj;
+ if (selected_obj)
+ debug(0, "selected object %s", selected_obj->name);
+ return true;
+
+ case Common::EVENT_KEYDOWN:
+ if (_active && event.kbd.keycode == Common::KEYCODE_ESCAPE) {
+ activate(false);
+ return true;
+ }
+ return false;
+
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONUP:
+ return _active;
+
+ default:
+ return false;
+ }
+}
+
+
+void Inventory::Item::free() {
+ animation.free();
+ surface.free();
+}
+
+void Inventory::Item::render(Inventory * inventory, InventoryObject *obj, Graphics::Surface * dst) {
+ Resources * res = Resources::instance();
+
+ rect.render(dst, hovered? 233: 234);
+ if (obj->animated) {
+ if (animation.empty()) {
+ debug(0, "loading item %d from offset %x", obj->id, inventory->offset[obj->id - 1]);
+ inventory->items->seek(inventory->offset[obj->id - 1]);
+ animation.load(inventory->items, Animation::TypeInventory);
+ }
+ Surface * s = animation.currentFrame();
+ if (s != NULL)
+ s->render(dst, rect.left + 1, rect.top + 1);
+ } else {
+ if (surface.empty()) {
+ debug(0, "loading item %d from offset %x", obj->id, inventory->offset[obj->id - 1]);
+ inventory->items->seek(inventory->offset[obj->id - 1]);
+ surface.load(inventory->items, Surface::TypeOns);
+ }
+ surface.render(dst, rect.left + 1, rect.top + 1);
+ }
+
+ Common::String name;
+ if (inventory->selected_obj && inventory->selected_obj != inventory->hovered_obj) {
+ name = inventory->selected_obj->name;
+ name += " & ";
+ }
+ name += obj->name;
+
+ if (hovered) {
+ int w = res->font7.render(NULL, 0, 0, name, true);
+ res->font7.render(dst, (320 - w) / 2, 180, name, true);
+ }
+}
+
+void Inventory::render(Graphics::Surface * surface) {
+ if (!_active)
+ return;
+
+ background.render(surface);
+ Resources * res = Resources::instance();
+
+ for (int y = 0; y < 4; y++) {
+ for (int x = 0; x < 6; x++) {
+ int idx = x + 6 * y;
+ byte item = inventory[idx];
+ if (item == 0)
+ continue;
+
+ //debug(0, "%d,%d -> %u", x0, y0, item);
+
+ InventoryObject * obj = (InventoryObject *)res->dseg.ptr(READ_LE_UINT16(objects + item * 2));
+ graphics[idx].render(this, obj, surface);
+ }
+ }
+}