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/paint_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 namespace ZVision {
33
PaintControl(ZVision * engine,uint32 key,Common::SeekableReadStream & stream)34 PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
35 : Control(engine, key, CONTROL_PAINT) {
36
37 _cursor = CursorIndex_Active;
38 _paint = NULL;
39 _bkg = NULL;
40 _brush = NULL;
41 _colorKey = 0;
42 _mouseDown = false;
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("rectangle", 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 _rectangle = Common::Rect(x, y, width + x, height + y);
61 } else if (param.matchString("cursor", true)) {
62 _cursor = _engine->getCursorManager()->getCursorId(values);
63 } else if (param.matchString("brush_file", true)) {
64 _brush = _engine->getRenderManager()->loadImage(values, false);
65 } else if (param.matchString("venus_id", true)) {
66 _venusId = atoi(values.c_str());
67 } else if (param.matchString("paint_file", true)) {
68 _paint = _engine->getRenderManager()->loadImage(values, false);
69 } else if (param.matchString("eligible_objects", true)) {
70 char buf[256];
71 memset(buf, 0, 256);
72 strncpy(buf, values.c_str(), 255);
73
74 char *curpos = buf;
75 char *strend = buf + strlen(buf);
76 while (true) {
77 char *st = curpos;
78
79 if (st >= strend)
80 break;
81
82 while (*curpos != ' ' && curpos < strend)
83 curpos++;
84
85 *curpos = 0;
86 curpos++;
87
88 int obj = atoi(st);
89
90 _eligibleObjects.push_back(obj);
91 }
92 }
93
94 line = stream.readLine();
95 _engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
96 getParams(line, param, values);
97 }
98
99 if (_paint) {
100 _colorKey = _paint->format.RGBToColor(255, 0, 255);
101 _bkg = new Graphics::Surface;
102 _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format);
103 _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey);
104
105 Graphics::Surface *tmp = new Graphics::Surface;
106 tmp->create(_rectangle.width(), _rectangle.height(), _paint->format);
107 _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0);
108 _paint->free();
109 delete _paint;
110 _paint = tmp;
111 }
112 }
113
~PaintControl()114 PaintControl::~PaintControl() {
115 // Clear the state value back to 0
116 //_engine->getScriptManager()->setStateValue(_key, 0);
117 if (_paint) {
118 _paint->free();
119 delete _paint;
120 }
121 if (_brush) {
122 _brush->free();
123 delete _brush;
124 }
125 if (_bkg) {
126 _bkg->free();
127 delete _bkg;
128 }
129 }
130
onMouseUp(const Common::Point & screenSpacePos,const Common::Point & backgroundImageSpacePos)131 bool PaintControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
132 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
133 return false;
134
135 _mouseDown = false;
136
137 return false;
138 }
139
onMouseDown(const Common::Point & screenSpacePos,const Common::Point & backgroundImageSpacePos)140 bool PaintControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
141 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
142 return false;
143
144 if (_rectangle.contains(backgroundImageSpacePos)) {
145 int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
146
147 if (eligeblity(mouseItem)) {
148 setVenus();
149 _mouseDown = true;
150 }
151 }
152
153 return false;
154 }
155
onMouseMove(const Common::Point & screenSpacePos,const Common::Point & backgroundImageSpacePos)156 bool PaintControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
157 if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
158 return false;
159
160 if (_rectangle.contains(backgroundImageSpacePos)) {
161 int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
162
163 if (eligeblity(mouseItem)) {
164 _engine->getCursorManager()->changeCursor(_cursor);
165
166 if (_mouseDown) {
167 Common::Rect bkgRect = paint(backgroundImageSpacePos);
168 if (!bkgRect.isEmpty()) {
169 Common::Rect imgRect = bkgRect;
170 imgRect.translate(-_rectangle.left, -_rectangle.top);
171
172 Graphics::Surface imgUpdate = _bkg->getSubArea(imgRect);
173
174 _engine->getRenderManager()->blitSurfaceToBkg(imgUpdate, bkgRect.left, bkgRect.top, _colorKey);
175 }
176 }
177 return true;
178 }
179 }
180
181 return false;
182 }
183
eligeblity(int itemId)184 bool PaintControl::eligeblity(int itemId) {
185 for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
186 if (*it == itemId)
187 return true;
188 return false;
189 }
190
paint(const Common::Point & point)191 Common::Rect PaintControl::paint(const Common::Point &point) {
192 Common::Rect paintRect = Common::Rect(_brush->w, _brush->h);
193 paintRect.moveTo(point);
194 paintRect.clip(_rectangle);
195
196 if (!paintRect.isEmpty()) {
197 Common::Rect brushRect = paintRect;
198 brushRect.translate(-point.x, -point.y);
199
200 Common::Rect bkgRect = paintRect;
201 bkgRect.translate(-_rectangle.left, -_rectangle.top);
202
203 for (int yy = 0; yy < brushRect.height(); yy++) {
204 uint16 *mask = (uint16 *)_brush->getBasePtr(brushRect.left, brushRect.top + yy);
205 uint16 *from = (uint16 *)_paint->getBasePtr(bkgRect.left, bkgRect.top + yy);
206 uint16 *to = (uint16 *)_bkg->getBasePtr(bkgRect.left, bkgRect.top + yy);
207 for (int xx = 0; xx < brushRect.width(); xx++) {
208 if (*mask != 0)
209 *(to + xx) = *(from + xx);
210
211 mask++;
212 }
213 }
214
215 }
216 return paintRect;
217 }
218
219 } // End of namespace ZVision
220