1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "common/scummsys.h"
24
25 #include "zvision/scripting/controls/slot_control.h"
26
27 #include "zvision/zvision.h"
28 #include "zvision/scripting/script_manager.h"
29 #include "zvision/graphics/cursors/cursor_manager.h"
30 #include "zvision/graphics/render_manager.h"
31
32 #include "common/stream.h"
33
34 namespace ZVision {
35
SlotControl(ZVision * engine,uint32 key,Common::SeekableReadStream & stream)36 SlotControl::SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
37 : Control(engine, key, CONTROL_SLOT),
38 _cursor(CursorIndex_Active),
39 _distanceId('0') {
40
41 _renderedItem = 0;
42 _bkg = NULL;
43
44 // Loop until we find the closing brace
45 Common::String line = stream.readLine();
46 _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
47 Common::String param;
48 Common::String values;
49 getParams(line, param, values);
50
51 while (!stream.eos() && !line.contains('}')) {
52 if (param.matchString("hotspot", true)) {
53 int x;
54 int y;
55 int width;
56 int height;
57
58 sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
59
60 _hotspot = Common::Rect(x, y, width, height);
61 } else if (param.matchString("rectangle", true)) {
62 int x;
63 int y;
64 int width;
65 int height;
66
67 sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
68
69 _rectangle = Common::Rect(x, y, width, height);
70 } else if (param.matchString("cursor", true)) {
71 _cursor = _engine->getCursorManager()->getCursorId(values);
72 } else if (param.matchString("distance_id", true)) {
73 sscanf(values.c_str(), "%c", &_distanceId);
74 } else if (param.matchString("venus_id", true)) {
75 _venusId = atoi(values.c_str());
76 } else if (param.matchString("eligible_objects", true)) {
77 char buf[256];
78 memset(buf, 0, 256);
79 strncpy(buf, values.c_str(), 255);
80
81 char *curpos = buf;
82 char *strend = buf + strlen(buf);
83 while (true) {
84 char *st = curpos;
85
86 if (st >= strend)
87 break;
88
89 while (*curpos != ' ' && curpos < strend)
90 curpos++;
91
92 *curpos = 0;
93 curpos++;
94
95 int obj = atoi(st);
96
97 _eligibleObjects.push_back(obj);
98 }
99 }
100
101 line = stream.readLine();
102 _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
103 getParams(line, param, values);
104 }
105
106 if (_hotspot.isEmpty() || _rectangle.isEmpty()) {
107 warning("Slot %u was parsed incorrectly", key);
108 }
109 }
110
~SlotControl()111 SlotControl::~SlotControl() {
112 // Clear the state value back to 0
113 //_engine->getScriptManager()->setStateValue(_key, 0);
114
115 if (_bkg)
116 delete _bkg;
117 }
118
onMouseUp(const Common::Point & screenSpacePos,const Common::Point & backgroundImageSpacePos)119 bool SlotControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
120 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
121 return false;
122
123 if (_hotspot.contains(backgroundImageSpacePos)) {
124 setVenus();
125
126 int item = _engine->getScriptManager()->getStateValue(_key);
127 int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
128 if (item != 0) {
129 if (mouseItem != 0) {
130 if (eligeblity(mouseItem)) {
131 _engine->getScriptManager()->inventoryDrop(mouseItem);
132 _engine->getScriptManager()->inventoryAdd(item);
133 _engine->getScriptManager()->setStateValue(_key, mouseItem);
134 }
135 } else {
136 _engine->getScriptManager()->inventoryAdd(item);
137 _engine->getScriptManager()->setStateValue(_key, 0);
138 }
139 } else if (mouseItem == 0) {
140 if (eligeblity(0)) {
141 _engine->getScriptManager()->inventoryDrop(0);
142 _engine->getScriptManager()->setStateValue(_key, 0);
143 }
144 } else if (eligeblity(mouseItem)) {
145 _engine->getScriptManager()->setStateValue(_key, mouseItem);
146 _engine->getScriptManager()->inventoryDrop(mouseItem);
147 }
148 }
149 return false;
150 }
151
onMouseMove(const Common::Point & screenSpacePos,const Common::Point & backgroundImageSpacePos)152 bool SlotControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
153 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
154 return false;
155
156 if (_hotspot.contains(backgroundImageSpacePos)) {
157 _engine->getCursorManager()->changeCursor(_cursor);
158 return true;
159 }
160
161 return false;
162 }
163
process(uint32 deltaTimeInMillis)164 bool SlotControl::process(uint32 deltaTimeInMillis) {
165 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
166 return false;
167
168 if (_engine->canRender()) {
169 int curItem = _engine->getScriptManager()->getStateValue(_key);
170 if (curItem != _renderedItem) {
171 if (_renderedItem != 0 && curItem == 0) {
172 _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
173 _renderedItem = curItem;
174 } else {
175 if (_renderedItem == 0) {
176 if (_bkg)
177 delete _bkg;
178
179 _bkg = _engine->getRenderManager()->getBkgRect(_rectangle);
180 } else {
181 _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
182 }
183
184 char buf[16];
185 if (_engine->getGameId() == GID_NEMESIS)
186 sprintf(buf, "%d%cobj.tga", curItem, _distanceId);
187 else
188 sprintf(buf, "g0z%cu%2.2x1.tga", _distanceId, curItem);
189
190 Graphics::Surface *srf = _engine->getRenderManager()->loadImage(buf);
191
192 int16 drawx = _rectangle.left;
193 int16 drawy = _rectangle.top;
194
195 if (_rectangle.width() > srf->w)
196 drawx = _rectangle.left + (_rectangle.width() - srf->w) / 2;
197
198 if (_rectangle.height() > srf->h)
199 drawy = _rectangle.top + (_rectangle.height() - srf->h) / 2;
200
201 _engine->getRenderManager()->blitSurfaceToBkg(*srf, drawx, drawy, 0);
202
203 delete srf;
204
205 _renderedItem = curItem;
206 }
207 }
208 }
209 return false;
210 }
211
eligeblity(int itemId)212 bool SlotControl::eligeblity(int itemId) {
213 for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
214 if (*it == itemId)
215 return true;
216 return false;
217 }
218
219 } // End of namespace ZVision
220