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 /*
24  * This code is based on Labyrinth of Time code with assistance of
25  *
26  * Copyright (c) 1993 Terra Nova Development
27  * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
28  *
29  */
30 
31 #include "common/events.h"
32 
33 #include "lab/lab.h"
34 
35 #include "lab/dispman.h"
36 #include "lab/interface.h"
37 #include "lab/image.h"
38 #include "lab/utils.h"
39 
40 namespace Lab {
41 
42 #define CRUMBSWIDTH 24
43 #define CRUMBSHEIGHT 24
44 
Interface(LabEngine * vm)45 Interface::Interface(LabEngine *vm) : _vm(vm) {
46 	_screenButtonList = nullptr;
47 	_hitButton = nullptr;
48 }
49 
createButton(uint16 x,uint16 y,uint16 id,Common::KeyCode key,Image * image,Image * altImage)50 Button *Interface::createButton(uint16 x, uint16 y, uint16 id, Common::KeyCode key, Image *image, Image *altImage) {
51 	Button *button = new Button();
52 
53 	if (button) {
54 		button->_x = _vm->_utils->vgaScaleX(x);
55 		button->_y = y;
56 		button->_buttonId = id;
57 		button->_keyEquiv = key;
58 		button->_image = image;
59 		button->_altImage = altImage;
60 		button->_isEnabled = true;
61 
62 		return button;
63 	} else
64 		return nullptr;
65 }
66 
freeButtonList(ButtonList * buttonList)67 void Interface::freeButtonList(ButtonList *buttonList) {
68 	for (ButtonList::iterator buttonIter = buttonList->begin(); buttonIter != buttonList->end(); ++buttonIter) {
69 		Button *button = *buttonIter;
70 		delete button->_image;
71 		delete button->_altImage;
72 		delete button;
73 	}
74 
75 	buttonList->clear();
76 }
77 
drawButtonList(ButtonList * buttonList)78 void Interface::drawButtonList(ButtonList *buttonList) {
79 	for (ButtonList::iterator button = buttonList->begin(); button != buttonList->end(); ++button) {
80 		toggleButton((*button), 1, true);
81 
82 		if (!(*button)->_isEnabled)
83 			toggleButton((*button), 1, false);
84 	}
85 }
86 
toggleButton(Button * button,uint16 disabledPenColor,bool enable)87 void Interface::toggleButton(Button *button, uint16 disabledPenColor, bool enable) {
88 	if (!enable)
89 		_vm->_graphics->checkerBoardEffect(disabledPenColor, button->_x, button->_y, button->_x + button->_image->_width - 1, button->_y + button->_image->_height - 1);
90 	else
91 		button->_image->drawImage(button->_x, button->_y);
92 
93 	button->_isEnabled = enable;
94 }
95 
checkNumButtonHit(Common::KeyCode key)96 Button *Interface::checkNumButtonHit(Common::KeyCode key) {
97 	uint16 gkey = key - '0';
98 
99 	if (!_screenButtonList)
100 		return nullptr;
101 
102 	for (ButtonList::iterator buttonItr = _screenButtonList->begin(); buttonItr != _screenButtonList->end(); ++buttonItr) {
103 		Button *button = *buttonItr;
104 		if (!button->_isEnabled)
105 			continue;
106 
107 		if ((gkey - 1 == button->_buttonId) || (gkey == 0 && button->_buttonId == 9) || (button->_keyEquiv != Common::KEYCODE_INVALID && key == button->_keyEquiv)) {
108 			button->_altImage->drawImage(button->_x, button->_y);
109 			_vm->_system->delayMillis(80);
110 			button->_image->drawImage(button->_x, button->_y);
111 			return button;
112 		}
113 	}
114 
115 	return nullptr;
116 }
117 
checkButtonHit(Common::Point pos)118 Button *Interface::checkButtonHit(Common::Point pos) {
119 	if (!_screenButtonList)
120 		return nullptr;
121 
122 	for (ButtonList::iterator buttonItr = _screenButtonList->begin(); buttonItr != _screenButtonList->end(); ++buttonItr) {
123 		Button *button = *buttonItr;
124 		Common::Rect buttonRect(button->_x, button->_y, button->_x + button->_image->_width - 1, button->_y + button->_image->_height - 1);
125 
126 		if (buttonRect.contains(pos) && button->_isEnabled) {
127 			_hitButton = button;
128 			return button;
129 		}
130 	}
131 
132 	return nullptr;
133 }
134 
handlePressedButton()135 void Interface::handlePressedButton() {
136 	if (!_hitButton)
137 		return;
138 
139 	_hitButton->_altImage->drawImage(_hitButton->_x, _hitButton->_y);
140 	for (int i = 0; i < 3; i++)
141 		_vm->waitTOF();
142 	_hitButton->_image->drawImage(_hitButton->_x, _hitButton->_y);
143 
144 	_hitButton = nullptr;
145 	_vm->_graphics->screenUpdate();
146 }
147 
attachButtonList(ButtonList * buttonList)148 void Interface::attachButtonList(ButtonList *buttonList) {
149 	_screenButtonList = buttonList;
150 }
151 
getButton(uint16 id)152 Button *Interface::getButton(uint16 id) {
153 	for (ButtonList::iterator buttonItr = _screenButtonList->begin(); buttonItr != _screenButtonList->end(); ++buttonItr) {
154 		Button *button = *buttonItr;
155 		if (button->_buttonId == id)
156 			return button;
157 	}
158 
159 	return nullptr;
160 }
161 
mayShowCrumbIndicator()162 void Interface::mayShowCrumbIndicator() {
163 	static byte dropCrumbsImageData[CRUMBSWIDTH * CRUMBSHEIGHT] = {
164 		0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0,
165 		0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0,
166 		4, 7, 7, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 7, 7, 4,
167 		4, 7, 4, 4, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 7, 4,
168 		4, 7, 4, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 7, 4,
169 		4, 7, 4, 0, 0, 3, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 4, 7, 4,
170 		4, 7, 4, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 0, 0, 3, 2, 3, 0, 4, 7, 4,
171 		4, 7, 4, 0, 0, 0, 0, 0, 4, 7, 7, 7, 7, 7, 7, 4, 3, 2, 2, 2, 3, 4, 7, 4,
172 		4, 7, 4, 0, 0, 0, 0, 4, 7, 7, 4, 4, 4, 4, 7, 7, 4, 3, 3, 3, 0, 4, 7, 4,
173 		4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 4, 0, 0, 4, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
174 		4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
175 		4, 7, 4, 0, 0, 0, 0, 4, 4, 4, 3, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
176 		4, 7, 4, 0, 0, 0, 0, 0, 4, 3, 2, 3, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
177 		4, 7, 4, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
178 		4, 7, 4, 0, 0, 0, 0, 0, 3, 2, 2, 2, 3, 4, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4,
179 		4, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 4, 0, 0, 0, 0, 4, 7, 4,
180 		0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0, 0, 0, 0, 0, 4, 7, 4,
181 		0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 4, 7, 4,
182 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 4, 7, 4,
183 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 4, 7, 4,
184 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 3, 0, 0, 4, 4, 7, 4,
185 		0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 4,
186 		0, 0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0,
187 		0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0
188 	};
189 
190 	if (_vm->getPlatform() != Common::kPlatformWindows)
191 		return;
192 
193 	if (_vm->_droppingCrumbs && _vm->isMainDisplay()) {
194 		static byte *imgData = new byte[CRUMBSWIDTH * CRUMBSHEIGHT];
195 		memcpy(imgData, dropCrumbsImageData, CRUMBSWIDTH * CRUMBSHEIGHT);
196 		static Image dropCrumbsImage(CRUMBSWIDTH, CRUMBSHEIGHT, imgData, _vm);
197 
198 		dropCrumbsImage.drawMaskImage(612, 4);
199 	}
200 }
201 
mayShowCrumbIndicatorOff()202 void Interface::mayShowCrumbIndicatorOff() {
203 	static byte dropCrumbsOffImageData[CRUMBSWIDTH * CRUMBSHEIGHT] = {
204 		0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0,
205 		0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0,
206 		4, 8, 8, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 8, 8, 4,
207 		4, 8, 4, 4, 0, 0, 3, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 8, 4,
208 		4, 8, 4, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 8, 4,
209 		4, 8, 4, 0, 0, 3, 8, 8, 8, 3, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 4, 8, 4,
210 		4, 8, 4, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 0, 0, 3, 8, 3, 0, 4, 8, 4,
211 		4, 8, 4, 0, 0, 0, 0, 0, 4, 8, 8, 8, 8, 8, 8, 4, 3, 8, 8, 8, 3, 4, 8, 4,
212 		4, 8, 4, 0, 0, 0, 0, 4, 8, 8, 4, 4, 4, 4, 8, 8, 4, 3, 3, 3, 0, 4, 8, 4,
213 		4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 4, 0, 0, 4, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
214 		4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
215 		4, 8, 4, 0, 0, 0, 0, 4, 4, 4, 3, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
216 		4, 8, 4, 0, 0, 0, 0, 0, 4, 3, 8, 3, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
217 		4, 8, 4, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
218 		4, 8, 4, 0, 0, 0, 0, 0, 3, 8, 8, 8, 3, 4, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4,
219 		4, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 0, 0, 0, 0, 4, 8, 4,
220 		0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0, 0, 0, 0, 0, 4, 8, 4,
221 		0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 4, 8, 4,
222 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 4, 8, 4,
223 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 4, 8, 4,
224 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 8, 8, 3, 0, 0, 4, 4, 8, 4,
225 		0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4,
226 		0, 0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0,
227 		0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0
228 	};
229 
230 	if (_vm->getPlatform() != Common::kPlatformWindows)
231 		return;
232 
233 	if (_vm->isMainDisplay()) {
234 		static byte *imgData = new byte[CRUMBSWIDTH * CRUMBSHEIGHT];
235 		memcpy(imgData, dropCrumbsOffImageData, CRUMBSWIDTH * CRUMBSHEIGHT);
236 		static Image dropCrumbsOffImage(CRUMBSWIDTH, CRUMBSHEIGHT, imgData, _vm);
237 
238 		dropCrumbsOffImage.drawMaskImage(612, 4);
239 	}
240 }
241 
242 } // End of namespace Lab
243