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
25 #ifdef ENABLE_AGOS2
26
27 #include "common/savefile.h"
28
29 #include "graphics/surface.h"
30
31 #include "agos/agos.h"
32 #include "agos/intern.h"
33 #include "agos/vga.h"
34
35 namespace AGOS {
36
checkLinkBox()37 void AGOSEngine_Feeble::checkLinkBox() { // Check for boxes spilling over to next row of text
38 if (_hyperLink != 0) {
39 _variableArray[52] = _textWindow->x + _textWindow->textColumn - _variableArray[50];
40 if (_variableArray[52] != 0) {
41 defineBox(_variableArray[53], _variableArray[50], _variableArray[51], _variableArray[52], 15, 145, 208, _dummyItem2);
42 _variableArray[53]++;
43 }
44 _variableArray[50] = _textWindow->x;
45 _variableArray[51] = _textWindow->textRow + _textWindow->y + (_oracleMaxScrollY-_textWindow->scrollY) * 15;
46 }
47 }
48
hyperLinkOn(uint16 x)49 void AGOSEngine_Feeble::hyperLinkOn(uint16 x) {
50 if (!getBitFlag(51))
51 return;
52
53 _hyperLink = x;
54 _variableArray[50] = _textWindow->textColumn + _textWindow->x;
55 _variableArray[51] = _textWindow->textRow + _textWindow->y + (_oracleMaxScrollY - _textWindow->scrollY) * 15;
56 }
57
58
hyperLinkOff()59 void AGOSEngine_Feeble::hyperLinkOff() {
60 if (!getBitFlag(51))
61 return;
62
63 _variableArray[52] = _textWindow->x + _textWindow->textColumn - _variableArray[50];
64 defineBox(_variableArray[53], _variableArray[50], _variableArray[51], _variableArray[52], 15, 145, 208, _dummyItem2);
65 _variableArray[53]++;
66 _hyperLink = 0;
67 }
68
linksUp()69 void AGOSEngine_Feeble::linksUp() { // Scroll Oracle Links
70 uint16 j;
71 for (j = 700; j < _variableArray[53]; j++) {
72 moveBox(j, 0, -15);
73 }
74 }
75
linksDown()76 void AGOSEngine_Feeble::linksDown() {
77 uint16 i;
78 for (i = 700; i < _variableArray[53]; i++) {
79 moveBox(i,0, 15);
80 }
81 }
82
checkUp(WindowBlock * window)83 void AGOSEngine_Feeble::checkUp(WindowBlock *window) {
84 uint16 j, k;
85
86 if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[31] > 52)) {
87 k = (((_variableArray[31] / 52) - 2) % 3);
88 j = k * 6;
89 if (!isBoxDead(j + 201)) {
90 uint index = getWindowNum(window);
91 drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask);
92 animate(4, 9, k + 34, 0, 0, 0);
93 }
94 }
95 if ((_variableArray[31] - _variableArray[30]) == 76) {
96 k = ((_variableArray[31] / 52) % 3);
97 j = k * 6;
98 if (isBoxDead(j + 201)) {
99 animate(4, 9, k + 31, 0, 0, 0);
100 undefineBox(j + 201);
101 undefineBox(j + 202);
102 undefineBox(j + 203);
103 undefineBox(j + 204);
104 undefineBox(j + 205);
105 undefineBox(j + 206);
106 }
107 _variableArray[31] -= 52;
108 _iOverflow = 1;
109 }
110 }
111
inventoryUp(WindowBlock * window)112 void AGOSEngine_Feeble::inventoryUp(WindowBlock *window) {
113 _marks = 0;
114 checkUp(window);
115 animate(4, 9, 21, 0 ,0, 0);
116 while (_currentBoxNum == 0x7FFB && getBitFlag(89)) {
117 checkUp(window);
118 delay(1);
119 }
120 waitForMark(2);
121 checkUp(window);
122 sendSync(922);
123 waitForMark(1);
124 checkUp(window);
125 }
126
127
checkDown(WindowBlock * window)128 void AGOSEngine_Feeble::checkDown(WindowBlock *window) {
129 uint16 j, k;
130
131 if (((_variableArray[31] - _variableArray[30]) == 24) && (_iOverflow == 1)) {
132 uint index = getWindowNum(window);
133 drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask);
134 k = ((_variableArray[31] / 52) % 3);
135 animate(4, 9, k + 25, 0, 0, 0);
136 _variableArray[31] += 52;
137 }
138 if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[30] > 52)) {
139 k = (((_variableArray[31] / 52) + 1) % 3);
140 j = k * 6;
141 if (isBoxDead(j + 201)) {
142 animate(4, 9, k + 28, 0, 0, 0);
143 undefineBox(j + 201);
144 undefineBox(j + 202);
145 undefineBox(j + 203);
146 undefineBox(j + 204);
147 undefineBox(j + 205);
148 undefineBox(j + 206);
149 }
150 }
151 }
152
inventoryDown(WindowBlock * window)153 void AGOSEngine_Feeble::inventoryDown(WindowBlock *window) {
154 _marks = 0;
155 checkDown(window);
156 animate(4, 9, 23, 0, 0, 0);
157 while (_currentBoxNum == 0x7FFC && getBitFlag(89)) {
158 checkDown(window);
159 delay(1);
160 }
161 waitForMark(2);
162 checkDown(window);
163 sendSync(924);
164 waitForMark(1);
165 checkDown(window);
166 }
167
scrollOracle()168 void AGOSEngine_Feeble::scrollOracle() {
169 int i;
170
171 for (i = 0; i < 5; i++)
172 scrollOracleUp();
173 }
174
oracleTextUp()175 void AGOSEngine_Feeble::oracleTextUp() {
176 Subroutine *sub;
177 int i = 0;
178 changeWindow(3);
179 _noOracleScroll = 0;
180
181 if (_textWindow->scrollY > _oracleMaxScrollY) // For scroll up
182 _oracleMaxScrollY = _textWindow->scrollY;
183 while (!shouldQuit()) {
184 if (_textWindow->scrollY == _oracleMaxScrollY)
185 break;
186 _textWindow->textRow = 105;
187 for (i = 0; i < 5; i++) {
188 _newLines = 0;
189 _textWindow->textColumn = 0;
190 _textWindow->textRow -= 3;
191 if (i == 2) {
192 _textWindow->scrollY += 1;
193 _textWindow->textRow += 15;
194 linksUp();
195 }
196 scrollOracleUp();
197 setBitFlag(94, true);
198 sub = getSubroutineByID(_variableArray[104]);
199 if (sub)
200 startSubroutineEx(sub);
201 setBitFlag(94, false);
202 }
203 if (_currentBoxNum != 601 || !getBitFlag(89))
204 break;
205 delay(100);
206 }
207 }
208
oracleTextDown()209 void AGOSEngine_Feeble::oracleTextDown() {
210 Subroutine *sub;
211 int i = 0;
212 changeWindow(3);
213 _noOracleScroll = 0;
214
215 if (_textWindow->scrollY > _oracleMaxScrollY) // For scroll up
216 _oracleMaxScrollY = _textWindow->scrollY;
217 while (!shouldQuit()) {
218 if (_textWindow->scrollY == 0)
219 break;
220
221 for (i = 0; i < 5; i++) {
222 _newLines = 0;
223 _textWindow->textColumn = 0;
224 _textWindow->textRow = (i + 1) * 3;
225 if (i == 4) {
226 _textWindow->scrollY -= 1;
227 _textWindow->textRow = 0;
228 linksDown();
229 }
230 scrollOracleDown();
231 setBitFlag(93, true);
232 sub = getSubroutineByID(_variableArray[104]);
233 if (sub)
234 startSubroutineEx(sub);
235 setBitFlag(93, false);
236 }
237 if (_currentBoxNum != 600 || !getBitFlag(89))
238 break;
239 delay(100);
240 }
241 }
242
scrollOracleUp()243 void AGOSEngine_Feeble::scrollOracleUp() {
244 byte *src, *dst;
245 uint16 w, h;
246
247 dst = getBackGround() + 103 * _backGroundBuf->pitch + 136;
248 src = getBackGround() + 106 * _backGroundBuf->pitch + 136;
249
250 for (h = 0; h < 21; h++) {
251 for (w = 0; w < 360; w++) {
252 if (dst[w] == 0 || dst[w] == 113 || dst[w] == 116 || dst[w] == 252)
253 dst[w] = src[w];
254 }
255 dst += _backGroundBuf->pitch;
256 src += _backGroundBuf->pitch;
257 }
258
259 for (h = 0; h < 80; h++) {
260 memcpy(dst, src, 360);
261 dst += _backGroundBuf->pitch;
262 src += _backGroundBuf->pitch;
263 }
264
265 for (h = 0; h < 3; h++) {
266 memset(dst, 0, 360);
267 dst += _backGroundBuf->pitch;
268 src += _backGroundBuf->pitch;
269 }
270 }
271
scrollOracleDown()272 void AGOSEngine_Feeble::scrollOracleDown() {
273 byte *src, *dst;
274 uint16 w, h;
275
276 src = getBackGround() + 203 * _backGroundBuf->pitch + 136;
277 dst = getBackGround() + 206 * _backGroundBuf->pitch + 136;
278
279 for (h = 0; h < 77; h++) {
280 memcpy(dst, src, 360);
281 dst -= _backGroundBuf->pitch;
282 src -= _backGroundBuf->pitch;
283 }
284
285 for (h = 0; h < 24; h++) {
286 for (w = 0; w < 360; w++) {
287 if (src[w] == 0)
288 dst[w] = src[w];
289
290 if (src[w] == 113 || src[w] == 116 || src[w] == 252) {
291 dst[w] = src[w];
292 src[w] = 0;
293 }
294 }
295 dst -= _backGroundBuf->pitch;
296 src -= _backGroundBuf->pitch;
297 }
298 }
299
oracleLogo()300 void AGOSEngine_Feeble::oracleLogo() {
301 Common::Rect srcRect, dstRect;
302 byte *src, *dst;
303 uint16 w, h;
304
305 dstRect.left = 16;
306 dstRect.top = 16;
307 dstRect.right = 58;
308 dstRect.bottom = 59;
309
310 srcRect.left = 0;
311 srcRect.top = 0;
312 srcRect.right = 42;
313 srcRect.bottom = 43;
314
315 src = _iconFilePtr;
316 dst = getBackBuf() + _backBuf->pitch * dstRect.top + dstRect.left;
317
318 for (h = 0; h < dstRect.height(); h++) {
319 for (w = 0; w < dstRect.width(); w++) {
320 if (src[w])
321 dst[w] = src[w];
322 }
323 src += 336;
324 dst += _backBuf->pitch;
325 }
326 }
327
swapCharacterLogo()328 void AGOSEngine_Feeble::swapCharacterLogo() {
329 Common::Rect srcRect, dstRect;
330 byte *src, *dst;
331 uint16 w, h;
332 int x;
333
334 dstRect.left = 64;
335 dstRect.top = 16;
336 dstRect.right = 106;
337 dstRect.bottom = 59;
338
339 srcRect.top = 0;
340 srcRect.bottom = 43;
341
342 x = _variableArray[91];
343 if (x > _variableArray[90])
344 x--;
345 if (x < _variableArray[90])
346 x++;
347 _variableArray[91] = x;
348
349 x++;
350 x *= 42;
351
352 srcRect.left = x;
353 srcRect.right = srcRect.left + 42;
354
355 src = _iconFilePtr + srcRect.top * 336 + srcRect.left;
356 dst = getBackBuf() + _backBuf->pitch * dstRect.top + dstRect.left;
357
358 for (h = 0; h < dstRect.height(); h++) {
359 for (w = 0; w < dstRect.width(); w++) {
360 if (src[w])
361 dst[w] = src[w];
362 }
363 src += 336;
364 dst += _backBuf->pitch;
365 }
366 }
367
listSaveGamesFeeble()368 void AGOSEngine_Feeble::listSaveGamesFeeble() {
369 char b[108];
370 Common::InSaveFile *in;
371 uint16 j, k, z, maxFiles;
372 int OK;
373 memset(b, 0, 108);
374
375 maxFiles = countSaveGames() - 1;
376 j = maxFiles;
377 k = 1;
378 z = maxFiles;
379 if (getBitFlag(95)) {
380 j++;
381 z++;
382 }
383
384 while (!shouldQuit()) {
385 OK = 1;
386 if (getBitFlag(93) || getBitFlag(94)) {
387 OK = 0;
388 if (j > z)
389 break;
390 }
391
392 if (getBitFlag(93)) {
393 if (((_newLines + 1) >= _textWindow->scrollY) && ((_newLines + 1) < (_textWindow->scrollY + 3)))
394 OK = 1;
395 }
396
397 if (getBitFlag(94)) {
398 if ((_newLines + 1) == (_textWindow->scrollY + 7))
399 OK = 1;
400 }
401
402
403 if (OK == 1) {
404 if (j == maxFiles + 1) {
405 showMessageFormat("\n");
406 hyperLinkOn(j + 400);
407 setTextColor(116);
408 showMessageFormat(" %d. ", 1);
409 hyperLinkOff();
410 setTextColor(113);
411 k++;
412 j--;
413 }
414
415 if (!(in = _saveFileMan->openForLoading(genSaveName(j))))
416 break;
417 in->read(b, 100);
418 delete in;
419 }
420
421 showMessageFormat("\n");
422 hyperLinkOn(j + 400);
423 setTextColor(116);
424 if (k < 10)
425 showMessageFormat(" ");
426 showMessageFormat("%d. ", k);
427 setTextColor(113);
428 showMessageFormat("%s ", b);
429 hyperLinkOff();
430 j--;
431 k++;
432 }
433 }
434
saveUserGame(int slot)435 void AGOSEngine_Feeble::saveUserGame(int slot) {
436 WindowBlock *window;
437 Common::InSaveFile *in;
438 char name[108];
439 int len;
440 memset(name, 0, 108);
441
442 window = _windowArray[3];
443
444 window->textRow = (slot + 1 - window->scrollY) * 15;
445 window->textColumn = 26;
446
447 if ((in = _saveFileMan->openForLoading(genSaveName(readVariable(55))))) {
448 in->read(name, 100);
449 delete in;
450 }
451
452 len = 0;
453 while (name[len]) {
454 byte chr = name[len];
455 window->textColumn += getFeebleFontSize(chr);
456 len++;
457 }
458
459 windowPutChar(window, 0x7f);
460 while (!shouldQuit()) {
461 _keyPressed.reset();
462 delay(1);
463
464 if (_keyPressed.ascii == 0 || _keyPressed.ascii >= 127)
465 continue;
466
467 window->textColumn -= getFeebleFontSize(127);
468 name[len] = 0;
469 windowBackSpace(_windowArray[3]);
470
471 if (_keyPressed.keycode == Common::KEYCODE_ESCAPE) {
472 _variableArray[55] = 27;
473 break;
474 }
475 if (_keyPressed.keycode == Common::KEYCODE_KP_ENTER || _keyPressed.keycode == Common::KEYCODE_RETURN) {
476 if (!saveGame(readVariable(55), name))
477 _variableArray[55] = (int16)0xFFFF;
478 else
479 _variableArray[55] = 0;
480 break;
481 }
482 if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE && len != 0) {
483 len--;
484 byte chr = name[len];
485 window->textColumn -= getFeebleFontSize(chr);
486 name[len] = 0;
487 windowBackSpace(_windowArray[3]);
488 }
489 if (_keyPressed.ascii >= 32 && window->textColumn + 26 <= window->width) {
490 name[len++] = _keyPressed.ascii;
491 windowPutChar(_windowArray[3], _keyPressed.ascii);
492 }
493
494 windowPutChar(window, 0x7f);
495 }
496 }
497
windowBackSpace(WindowBlock * window)498 void AGOSEngine_Feeble::windowBackSpace(WindowBlock *window) {
499 byte *dst;
500 uint x, y, h, w;
501
502 _videoLockOut |= 0x8000;
503
504 x = window->x + window->textColumn;
505 y = window->y + window->textRow;
506
507 dst = getBackGround() + _backGroundBuf->pitch * y + x;
508
509 for (h = 0; h < 13; h++) {
510 for (w = 0; w < 8; w++) {
511 if (dst[w] == 113 || dst[w] == 116 || dst[w] == 252)
512 dst[w] = 0;
513 }
514 dst += _backGroundBuf->pitch;
515 }
516
517 _videoLockOut &= ~0x8000;
518 }
519
520 } // End of namespace AGOS
521
522 #endif // ENABLE_AGOS2
523