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 * Additional copyright for this file:
8 * Copyright (C) 1995 Presto Studios, Inc.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "buried/buried.h"
27 #include "buried/gameui.h"
28 #include "buried/graphics.h"
29 #include "buried/inventory_window.h"
30 #include "buried/navarrow.h"
31 #include "buried/navdata.h"
32 #include "buried/resources.h"
33 #include "buried/scene_view.h"
34
35 #include "common/keyboard.h"
36 #include "graphics/surface.h"
37
38 namespace Buried {
39
NavArrowWindow(BuriedEngine * vm,Window * parent)40 NavArrowWindow::NavArrowWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
41 _background = _vm->_gfx->getBitmap(IDB_ARROW_BACKGROUND);
42
43 _arrowBitmaps[0][0] = IDB_ARROW_UP_CLEAR;
44 _arrowBitmaps[0][1] = IDB_ARROW_UP_LIT;
45 _arrowBitmaps[0][2] = IDB_ARROW_UP_HIGHLIGHTED;
46 _arrowBitmaps[1][0] = IDB_ARROW_LEFT_CLEAR;
47 _arrowBitmaps[1][1] = IDB_ARROW_LEFT_LIT;
48 _arrowBitmaps[1][2] = IDB_ARROW_LEFT_HIGHLIGHTED;
49 _arrowBitmaps[2][0] = IDB_ARROW_RIGHT_CLEAR;
50 _arrowBitmaps[2][1] = IDB_ARROW_RIGHT_LIT;
51 _arrowBitmaps[2][2] = IDB_ARROW_RIGHT_HIGHLIGHTED;
52 _arrowBitmaps[3][0] = IDB_ARROW_DOWN_CLEAR;
53 _arrowBitmaps[3][1] = IDB_ARROW_DOWN_LIT;
54 _arrowBitmaps[3][2] = IDB_ARROW_DOWN_HIGHLIGHTED;
55 _arrowBitmaps[4][0] = IDB_ARROW_FORWARD_CLEAR;
56 _arrowBitmaps[4][1] = IDB_ARROW_FORWARD_LIT;
57 _arrowBitmaps[4][2] = IDB_ARROW_FORWARD_HIGHLIGHTED;
58
59 for (int i = 0; i < NUM_ARROWS; i++)
60 _arrowStatus[i] = BUTTON_DISABLED;
61
62 rebuildArrows();
63
64 _rect = Common::Rect(510, 292, 640, 418);
65 }
66
~NavArrowWindow()67 NavArrowWindow::~NavArrowWindow() {
68 _background->free();
69 delete _background;
70 }
71
updateArrow(int button,int newStatus)72 bool NavArrowWindow::updateArrow(int button, int newStatus) {
73 _arrowStatus[button] = newStatus;
74
75 rebuildArrows();
76 invalidateWindow(false);
77 return true;
78 }
79
updateAllArrows(int left,int up,int right,int down,int forward)80 bool NavArrowWindow::updateAllArrows(int left, int up, int right, int down, int forward) {
81 // clone2727 says: This is wrong. Left and up are swapped.
82 // I can only imagine what bugs this causes.
83 _arrowStatus[0] = left;
84 _arrowStatus[1] = up;
85 _arrowStatus[2] = right;
86 _arrowStatus[3] = down;
87 _arrowStatus[4] = forward;
88
89 rebuildArrows();
90 invalidateWindow(false);
91 return true;
92 }
93
updateAllArrows(const LocationStaticData & locationStaticData)94 bool NavArrowWindow::updateAllArrows(const LocationStaticData &locationStaticData) {
95 _arrowStatus[0] = (locationStaticData.destUp.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
96 _arrowStatus[1] = (locationStaticData.destLeft.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
97 _arrowStatus[2] = (locationStaticData.destRight.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
98 _arrowStatus[3] = (locationStaticData.destDown.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
99 _arrowStatus[4] = (locationStaticData.destForward.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
100
101 rebuildArrows();
102 invalidateWindow(false);
103 return true;
104 }
105
drawArrow(int xDst,int yDst,int arrow)106 bool NavArrowWindow::drawArrow(int xDst, int yDst, int arrow) {
107 Graphics::Surface *arrowBitmap = _vm->_gfx->getBitmap(_arrowBitmaps[arrow][_arrowStatus[arrow]]);
108
109 for (int ySrc = 0; ySrc < arrowBitmap->h; ySrc++)
110 memcpy(_background->getBasePtr(xDst, yDst + ySrc), arrowBitmap->getBasePtr(0, ySrc), arrowBitmap->w * arrowBitmap->format.bytesPerPixel);
111
112 arrowBitmap->free();
113 delete arrowBitmap;
114 return true;
115 }
116
rebuildArrows()117 bool NavArrowWindow::rebuildArrows() {
118 _background->free();
119 delete _background;
120 _background = _vm->_gfx->getBitmap(IDB_ARROW_BACKGROUND);
121
122 drawArrow(37, 2, 0);
123 drawArrow(2, 39, 1);
124 drawArrow(64, 38, 2);
125 drawArrow(38, 68, 3);
126
127 Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
128 _vm->_gfx->opaqueTransparentBlit(_background, 39, 49, centerArrow->w, centerArrow->h, centerArrow, 0, 0, (_arrowStatus[4] == BUTTON_DISABLED) ? 50 : 85, 255, 255, 255);
129 centerArrow->free();
130 delete centerArrow;
131 return true;
132 }
133
onLButtonDown(const Common::Point & point,uint flags)134 void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
135 Common::Rect leftButton(1, 43, 40, 78);
136 Common::Rect upButton(40, 1, 76, 45);
137 Common::Rect rightButton(63, 45, 130, 71);
138 Common::Rect downButton(42, 71, 78, 124);
139 Common::Rect forwardButton(39, 49, 101, 91);
140
141 ((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
142 ((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
143
144 // clone2727: This logic was broken in the original. retVal wasn't initialized.
145 bool retVal = false;
146
147 // Did we click anywhere near the forward button?
148 if (forwardButton.contains(point)) {
149 // If we only clicked on the forward arrow, then take care of it here
150 if (!rightButton.contains(point) && !downButton.contains(point)) {
151 if (_arrowStatus[4] == BUTTON_ENABLED)
152 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionForward);
153 } else {
154 if (rightButton.contains(point)) {
155 Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
156
157 if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
158 if (_arrowStatus[4] == BUTTON_ENABLED)
159 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionForward);
160 } else {
161 if (_arrowStatus[2] == BUTTON_ENABLED)
162 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionRight);
163 }
164
165 centerArrow->free();
166 delete centerArrow;
167 }
168
169 if (downButton.contains(point)) {
170 Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
171
172 if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
173 if (_arrowStatus[4] == BUTTON_ENABLED)
174 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionForward);
175 } else {
176 if (_arrowStatus[3] == BUTTON_ENABLED)
177 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionDown);
178 }
179
180 centerArrow->free();
181 delete centerArrow;
182 }
183 }
184 } else {
185 if (upButton.contains(point) && _arrowStatus[0] == BUTTON_ENABLED)
186 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionUp);
187
188 if (leftButton.contains(point) && _arrowStatus[1] == BUTTON_ENABLED)
189 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionLeft);
190
191 if (rightButton.contains(point) && _arrowStatus[2] == BUTTON_ENABLED)
192 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionRight);
193
194 if (downButton.contains(point) && _arrowStatus[3] == BUTTON_ENABLED)
195 retVal = ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionDown);
196 }
197
198 if (retVal) {
199 rebuildArrows();
200 invalidateWindow(false);
201 }
202 }
203
onKeyUp(const Common::KeyState & key,uint flags)204 void NavArrowWindow::onKeyUp(const Common::KeyState &key, uint flags) {
205 switch (key.keycode) {
206 case Common::KEYCODE_KP4:
207 case Common::KEYCODE_LEFT:
208 if (_arrowStatus[1] == BUTTON_ENABLED)
209 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionLeft);
210 break;
211 case Common::KEYCODE_KP6:
212 case Common::KEYCODE_RIGHT:
213 if (_arrowStatus[2] == BUTTON_ENABLED)
214 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionRight);
215 break;
216 case Common::KEYCODE_KP2:
217 case Common::KEYCODE_DOWN:
218 if (_arrowStatus[3] == BUTTON_ENABLED)
219 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionDown);
220 break;
221 case Common::KEYCODE_KP8:
222 case Common::KEYCODE_UP:
223 if (_arrowStatus[0] == BUTTON_ENABLED)
224 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionUp);
225 break;
226 case Common::KEYCODE_KP5:
227 if (_arrowStatus[4] == BUTTON_ENABLED)
228 ((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(kDirectionForward);
229 break;
230 default:
231 break;
232 }
233 }
234
onPaint()235 void NavArrowWindow::onPaint() {
236 Common::Rect absoluteRect = getAbsoluteRect();
237 _vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
238 }
239
onEnable(bool enable)240 void NavArrowWindow::onEnable(bool enable) {
241 if (enable)
242 _vm->removeMouseMessages(this);
243 }
244
245 } // End of namespace Buried
246