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 * Originally written by Syn9 in FreeBASIC with SDL
23 * http://syn9.thehideoutgames.com/index_backup.php
24 *
25 * Ported to plain C for GCW-Zero handheld by Dmitry Smagin
26 * http://github.com/dmitrysmagin/griffon_legend
27 *
28 *
29 * Programming/Graphics: Daniel "Syn9" Kennedy
30 * Music/Sound effects: David Turner
31 *
32 * Beta testing and gameplay design help:
33 * Deleter, Cha0s, Aether Fox, and Kiz
34 *
35 */
36
37 #include "common/file.h"
38 #include "common/system.h"
39
40 #include "image/bmp.h"
41
42 #include "griffon/griffon.h"
43
44 namespace Griffon {
45
46 // HELPER MACRO ---------------------------------------------------------------
47 #define INPUT(A, B) \
48 do { \
49 Common::String line; \
50 line = file.readLine(); \
51 sscanf(line.c_str(), A, B); \
52 } while(0)
53
54
initialize()55 void GriffonEngine::initialize() {
56 // init char *_floatstri[kMaxFloat]
57 for (int i = 0; i < kMaxFloat; i++) {
58 _floatText[i].text = (char *)malloc(64); // 64 bytes each string (should be enough)
59 _floatText[i].framesLeft = 0;
60 _floatText[i].x = 0;
61 _floatText[i].y = 0;
62 _floatText[i].col = 0;
63
64 _floatIcon[i].framesLeft = 0;
65 _floatIcon[i].x = 0;
66 _floatIcon[i].y = 0;
67 _floatIcon[i].ico = 0;
68 }
69
70 _video = new Graphics::TransparentSurface;
71 _video->create(320, 240, g_system->getScreenFormat());
72 _videoBuffer = new Graphics::TransparentSurface;
73 _videoBuffer->create(320, 240, g_system->getScreenFormat());
74 _videoBuffer2 = new Graphics::TransparentSurface;
75 _videoBuffer2->create(320, 240, g_system->getScreenFormat());
76 _videoBuffer3 = new Graphics::TransparentSurface;
77 _videoBuffer3->create(320, 240, g_system->getScreenFormat());
78 _mapBg = new Graphics::TransparentSurface;
79 _mapBg->create(320, 240, g_system->getScreenFormat());
80 _clipBg = new Graphics::TransparentSurface;
81 _clipBg->create(320, 240, g_system->getScreenFormat());
82 _clipBg2 = new Graphics::TransparentSurface;
83 _clipBg2->create(320, 240, g_system->getScreenFormat());
84
85 for (int i = 0; i <= 3; i++) {
86 char name[128];
87
88 sprintf(name, "art/map%i.bmp", i + 1);
89 mapImg[i] = loadImage(name, true);
90 }
91
92 _cloudImg = loadImage("art/clouds.bmp", true);
93 _cloudImg->setAlpha(64, true);
94
95 _saveLoadImg = nullptr;
96
97 _titleImg = loadImage("art/titleb.bmp");
98 _titleImg2 = loadImage("art/titlea.bmp", true);
99 //_titleimg2->setAlpha(204, true);
100
101 _inventoryImg = loadImage("art/inventory.bmp", true);
102
103 _logosImg = loadImage("art/logos.bmp");
104 _theEndImg = loadImage("art/theend.bmp");
105
106
107 loadTiles();
108 loadTriggers();
109 loadObjectDB();
110 loadAnims();
111 loadFont();
112 loadItemImgs();
113
114 _fpsr = 1.0f;
115 _nextTicks = _ticks + 1000;
116
117 for (int i = 0; i <= 15; i++) {
118 _playerAttackOfs[0][i].x = 0; // -1// -(i + 1)
119 _playerAttackOfs[0][i].y = -sin(3.14159 * 2 * (i + 1) / 16) * 2 - 1;
120
121 _playerAttackOfs[1][i].x = 0; // i + 1
122 _playerAttackOfs[1][i].y = -sin(3.14159 * 2 * (i + 1) / 16) * 2 + 1;
123
124 _playerAttackOfs[2][i].x = -1; // -(i + 1)
125 _playerAttackOfs[2][i].y = -sin(3.14159 * 2 * (i + 1) / 16) * 2;
126
127 _playerAttackOfs[3][i].x = 1; // i + 1
128 _playerAttackOfs[3][i].y = -sin(3.14159 * 2 * (i + 1) / 16) * 2;
129 }
130
131 setupAudio();
132 }
133
loadImage(const char * name,bool colorkey)134 Graphics::TransparentSurface *GriffonEngine::loadImage(const char *name, bool colorkey) {
135 Common::File file;
136
137 file.open(name);
138 if (!file.isOpen()) {
139 error("Cannot open file %s", name);
140 }
141
142 debug(1, "Loading: %s", name);
143
144 Image::BitmapDecoder bitmapDecoder;
145 bitmapDecoder.loadStream(file);
146 file.close();
147
148 Graphics::TransparentSurface *surface = new Graphics::TransparentSurface(*bitmapDecoder.getSurface()->convertTo(g_system->getScreenFormat()));
149
150 if (colorkey)
151 surface->applyColorKey(255, 0, 255);
152
153 return surface;
154 }
155
loadMap(int mapnum)156 void GriffonEngine::loadMap(int mapnum) {
157 debug(2, "Loaded map %d", mapnum);
158
159 unsigned int ccc = _clipBg->format.RGBToColor(255, 255, 255);
160
161 _curMap = mapnum;
162 Common::Rect trect(320, 240);
163
164 _mapBg->fillRect(trect, 0);
165 _clipBg->fillRect(trect, ccc);
166 _clipBg2->fillRect(trect, ccc);
167
168 _forcePause = false;
169 _cloudsOn = false;
170 if (mapnum < 6)
171 _cloudsOn = true;
172 if (mapnum > 41)
173 _cloudsOn = true;
174 if (mapnum > 47)
175 _cloudsOn = false;
176 if (mapnum == 52)
177 _cloudsOn = true;
178 if (mapnum == 60)
179 _cloudsOn = true;
180 if (mapnum == 50)
181 _cloudsOn = true;
182 if (mapnum == 54)
183 _cloudsOn = true;
184 if (mapnum == 58)
185 _cloudsOn = true;
186 if (mapnum == 62)
187 _cloudsOn = true;
188 if (mapnum == 83)
189 _cloudsOn = true;
190
191 // -----------special case
192 _dontDrawOver = false;
193 if (mapnum == 24)
194 _dontDrawOver = true;
195
196 if ((mapnum == 53 || mapnum == 57 || mapnum == 61 || mapnum == 65 || mapnum == 62) && _scriptFlag[kScriptLever][0] > 0)
197 mapnum = mapnum + 100;
198 if ((mapnum == 161 || mapnum == 162) && _scriptFlag[kScriptLever][0] == 2)
199 mapnum = mapnum + 100;
200
201 for (int i = 0; i < kMaxSpell; i++)
202 _spellInfo[i].frame = 0;
203
204 _roomLock = false;
205 _saidLocked = false;
206 _saidJammed = false;
207 _itemSelOn = false;
208 _selEnemyOn = false;
209 _curItem = 0;
210 _player.itemselshade = 0;
211
212 char name[256];
213 // read *.map file
214 sprintf(name, "mapdb/%04i.map", mapnum);
215 debug(1, "Reading %s", name);
216
217 Common::File file;
218 file.open(name);
219
220 if (!file.isOpen())
221 error("Cannot open file %s", name);
222
223 int tempmap[320][200];
224 for (int x = 0; x <= 319; x++) {
225 for (int y = 0; y <= 199; y++)
226 INPUT("%i", &tempmap[x][y]);
227 }
228 file.close();
229
230 for (int x = 0; x <= 319; x++) {
231 for (int y = 0; y <= 239; y++)
232 _triggerLoc[x][y] = -1;
233 }
234
235 // read *.trg file
236 sprintf(name, "mapdb/%04i.trg", mapnum);
237 debug(1, "Reading %s", name);
238 file.open(name);
239
240 if (!file.isOpen())
241 error("Cannot open file %s", name);
242
243 INPUT("%i", &_triggerNbr);
244
245 for (int i = 0; i < _triggerNbr; i++) {
246 int mapx, mapy, trig;
247
248 INPUT("%i", &mapx);
249 INPUT("%i", &mapy);
250 INPUT("%i", &trig);
251
252 _triggerLoc[mapx][mapy] = trig;
253 }
254 file.close();
255
256
257 for (int y = 0; y <= 23; y++) {
258 for (int x = 0; x <= 39; x++)
259 _rampData[x][y] = tempmap[3 * 40 + x][y + 40];
260 }
261
262 for (int y = 0; y <= 23; y++) {
263 for (int x = 0; x <= 39; x++) {
264 for (int l = 0; l <= 2; l++) {
265 for (int a = 0; a <= 2; a++)
266 _tileinfo[l][x][y][a] = 0;
267 }
268 }
269 }
270
271 if (_scriptFlag[kScriptFindShield][0] == 1 && _curMap == 4) {
272 _triggerLoc[9][7] = 5004;
273 tempmap[9][7] = 41;
274 tempmap[9][7 + 40] = 0;
275 }
276
277 for (int y = 0; y <= 23; y++) {
278 for (int x = 0; x <= 39; x++) {
279 for (int l = 0; l <= 2; l++) {
280 int ly = y;
281 int lx = x + l * 40;
282
283 // tile
284 int curtile = tempmap[lx][ly];
285 int curtilelayer = tempmap[lx][ly + 40];
286
287 if (curtile > 0) {
288 curtile = curtile - 1;
289 int curtilel = curtilelayer;
290 int curtilex = curtile % 20;
291 int curtiley = (curtile - curtilex) / 20;
292
293 _tileinfo[l][x][y][0] = curtile + 1;
294 _tileinfo[l][x][y][1] = curtilelayer;
295
296 rcSrc.left = curtilex * 16;
297 rcSrc.top = curtiley * 16;
298 rcSrc.setWidth(16);
299 rcSrc.setHeight(16);
300
301 rcDest.left = x * 16;
302 rcDest.top = y * 16;
303 rcDest.setWidth(16);
304 rcDest.setHeight(16);
305
306 int alpha = 255;
307 if (l == 2 && curtilel == 1) {
308 for (int ff = 0; ff <= 5; ff++) {
309 int ffa = 20 * 5 - 1 + ff * 20;
310 int ffb = 20 * 5 + 4 + ff * 20;
311 if (curtile > ffa && curtile < ffb) {
312 alpha = 128;
313 }
314 }
315 }
316 if (l == 1 && curtilel == 2) {
317 for (int ff = 0; ff <= 4; ff++) {
318 int ffa = 20 * (5 + ff) + 3;
319 if (curtile == ffa) {
320 alpha = 192;
321 }
322 }
323 }
324
325 _tiles[curtilel]->blit(*_mapBg, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(alpha, 255, 255, 255));
326
327 rcDest.left = x * 8;
328 rcDest.top = y * 8;
329 rcDest.setWidth(8);
330 rcDest.setHeight(8);
331
332 _clipBg->fillRect(rcDest, 0);
333 }
334 }
335 }
336 }
337
338 for (int x = 0; x <= 39; x++) {
339 for (int y = 0; y <= 23; y++) {
340 int d = tempmap[3 * 40 + x][y];
341
342 if (_scriptFlag[kScriptFindShield][0] == 1 && x == 9 && y == 7)
343 d = 99;
344
345 if (d > 0) {
346 int clip = d % 2;
347 d = (d - clip) / 2;
348 int npc = d % 2;
349 d = (d - npc) / 2;
350
351 if (d == 99 && x == 9 && y == 7)
352 clip = 1;
353
354 if (clip) {
355 if (d != 99)
356 d = tempmap[6 * 40 + x][y];
357 if (d == 99)
358 d = 1;
359
360 int x1 = x * 8;
361 int y1 = y * 8;
362
363 if (d == 1) {
364 for (int i = 0; i <= 7; i++) {
365 drawLine(_clipBg, x1, y1 + i, x1 + 7 - i, y1 + i, ccc);
366 }
367 } else if (d == 2) {
368 drawLine(_clipBg, x1, y1, x1 + 7, y1, ccc);
369 drawLine(_clipBg, x1, y1 + 1, x1 + 7, y1 + 1, ccc);
370 } else if (d == 3) {
371 for (int i = 0; i <= 7; i++) {
372 drawLine(_clipBg, x1 + i, y1 + i, x1 + 7, y1 + i, ccc);
373 }
374 } else if (d == 4) {
375 drawLine(_clipBg, x1, y1, x1, y1 + 7, ccc);
376 drawLine(_clipBg, x1 + 1, y1, x1 + 1, y1 + 7, ccc);
377 } else if (d == 5) {
378 rcDest.left = x1;
379 rcDest.top = y1;
380 rcDest.setWidth(8);
381 rcDest.setHeight(8);
382 _clipBg->fillRect(rcDest, ccc);
383 } else if (d == 6) {
384 drawLine(_clipBg, x1 + 7, y1, x1 + 7, y1 + 7, ccc);
385 drawLine(_clipBg, x1 + 6, y1, x1 + 6, y1 + 7, ccc);
386 } else if (d == 7) {
387 for (int i = 0; i <= 7; i++) {
388 drawLine(_clipBg, x1, y1 + i, x1 + i, y1 + i, ccc);
389 }
390 } else if (d == 8) {
391 drawLine(_clipBg, x1, y1 + 7, x1 + 7, y1 + 7, ccc);
392 drawLine(_clipBg, x1, y1 + 7, x1 + 6, y1 + 6, ccc);
393 } else if (d == 9) {
394 for (int i = 0; i <= 7; i++) {
395 drawLine(_clipBg, x1 + 7 - i, y1 + i, x1 + 7, y1 + i, ccc);
396 }
397 }
398 }
399 }
400 }
401 }
402
403 _lastObj = 0;
404 _lastNpc = 0;
405
406 for (int i = 0; i < kMaxNPC; i++)
407 _npcInfo[i].onMap = false;
408
409 for (int x = 0; x <= 20; x++) {
410 for (int y = 0; y <= 14; y++) {
411 int d = tempmap[3 * 40 + x][y];
412
413 int npc = 0;
414 int obj = 0;
415 if (d > 0) {
416 int clip = d % 2;
417 d = (d - clip) / 2;
418 npc = d % 2;
419 d = (d - npc) / 2;
420 obj = d % 2;
421 }
422
423 _objectMap[x][y] = -1;
424
425 if (obj == 1) {
426
427 int o = tempmap[5 * 40 + x][y];
428
429 if (_objectMapFull[_curMap][x][y] == 0) {
430 _objectMap[x][y] = o;
431
432 if (_objectInfo[o].nFrames > 1) {
433 if (o > _lastObj)
434 _lastObj = o;
435 }
436
437 int x1 = x * 8;
438 int y1 = y * 8;
439
440 rcDest.left = x1;
441 rcDest.top = y1;
442 rcDest.setWidth(8);
443 rcDest.setHeight(8);
444
445 if (_objectInfo[o].type == 1)
446 _clipBg->fillRect(rcDest, ccc);
447 if (_objectInfo[o].type == 3)
448 _clipBg->fillRect(rcDest, ccc);
449 }
450 }
451 if (npc == 1) {
452 int o = tempmap[4 * 40 + x][y];
453
454 if (o > _lastNpc)
455 _lastNpc = o;
456
457 _npcInfo[o].x = x * 16 - 4;
458 _npcInfo[o].y = y * 16 - 5;
459
460 _npcInfo[o].walkdir = 1;
461 _npcInfo[o].onMap = true;
462 }
463 }
464 }
465
466
467 if (_curMap == 62 && _scriptFlag[kScriptGardenMasterKey][0] > 0)
468 _lastNpc = 0;
469 if (_curMap == 73 && _scriptFlag[kScriptArmourChest][0] > 0)
470 _lastNpc = 0;
471 if (_curMap == 81 && _scriptFlag[kScriptCitadelMasterKey][0] > 0)
472 _lastNpc = 0;
473
474 if (_curMap == 73 && _scriptFlag[kScriptArmourChest][0] == 0)
475 _roomLock = true;
476 if (_curMap == 81 && _scriptFlag[kScriptCitadelMasterKey][0] == 0)
477 _roomLock = true;
478 if (_curMap == 83 && _scriptFlag[kScriptGetSword3][0] == 0)
479 _roomLock = true;
480 if (_curMap == 82)
481 _roomLock = true;
482
483 // read *.npc file
484 sprintf(name, "mapdb/%04i.npc", mapnum);
485 debug(1, "Reading %s", name);
486 file.open(name);
487
488 if (!file.isOpen())
489 error("Cannot open file %s", name);
490
491 for (int i = 0; i < kMaxNPC; i++) {
492 INPUT("%i", &_npcInfo[i].spriteset);
493 INPUT("%i", &_npcInfo[i].x1);
494 INPUT("%i", &_npcInfo[i].y1);
495 INPUT("%i", &_npcInfo[i].x2);
496 INPUT("%i", &_npcInfo[i].y2);
497 INPUT("%i", &_npcInfo[i].movementmode);
498 INPUT("%i", &_npcInfo[i].hp);
499 INPUT("%i", &_npcInfo[i].item1);
500 INPUT("%i", &_npcInfo[i].item2);
501 INPUT("%i", &_npcInfo[i].item3);
502 INPUT("%i", &_npcInfo[i].script);
503
504 _npcInfo[i].cframe = 0;
505 _npcInfo[i].frame = 0;
506 _npcInfo[i].frame2 = 0;
507 _npcInfo[i].attackattempt = 0;
508 _npcInfo[i].ticks = 0;
509
510 // baby dragon
511 if (_npcInfo[i].spriteset == kMonsterBabyDragon) {
512 _npcInfo[i].hp = 12;
513 _npcInfo[i].attackdelay = 2000;
514
515 _npcInfo[i].attackDamage = 2;
516 _npcInfo[i].spellDamage = 0;
517
518 _npcInfo[i].walkspd = 1;
519
520 if (RND() * 5 == 0)
521 _npcInfo[i].hp = 0;
522 }
523
524 // onewing
525 if (_npcInfo[i].spriteset == kMonsterOneWing) {
526 _npcInfo[i].hp = 200;
527 _npcInfo[i].attackdelay = 2000;
528 _npcInfo[i].swaySpeed = 1;
529
530 _npcInfo[i].attackDamage = 24;
531 _npcInfo[i].spellDamage = 30;
532
533 _npcInfo[i].walkspd = 1.4f;
534 _npcInfo[i].castPause = _ticks;
535 }
536
537 // boss1
538 if (_npcInfo[i].spriteset == kMonsterBoss1) {
539 _npcInfo[i].hp = 300;
540 _npcInfo[i].attackdelay = 2200;
541
542 _npcInfo[i].attackDamage = 0;
543 _npcInfo[i].spellDamage = 30;
544
545 _npcInfo[i].walkspd = 1.2f;
546 }
547
548 // black knights
549 if (_npcInfo[i].spriteset == kMonsterBlackKnight) {
550 _npcInfo[i].hp = 200;
551 _npcInfo[i].attackdelay = 2800;
552
553 _npcInfo[i].attackDamage = 0;
554 _npcInfo[i].spellDamage = 30;
555
556 _npcInfo[i].walkspd = 1;
557 }
558
559 // boss2 firehydra
560 if (_npcInfo[i].spriteset == kMonsterFireHydra) {
561 _npcInfo[i].hp = 600;
562 _npcInfo[i].attackdelay = 2200;
563
564 _npcInfo[i].attackDamage = 50;
565 _npcInfo[i].spellDamage = 30;
566
567 _npcInfo[i].walkspd = 1.3f;
568
569 _npcInfo[i].swayAngle = 0;
570 }
571
572 // baby fire dragon
573 if (_npcInfo[i].spriteset == kMonsterRedDragon) {
574 _npcInfo[i].hp = 20;
575 _npcInfo[i].attackdelay = 1500;
576
577 _npcInfo[i].attackDamage = 0;
578 _npcInfo[i].spellDamage = 12;
579
580 _npcInfo[i].walkspd = 1;
581
582 if (RND() * 5 == 0)
583 _npcInfo[i].hp = 0;
584 }
585
586 // priest1
587 if (_npcInfo[i].spriteset == kMonsterPriest) {
588 _npcInfo[i].hp = 40;
589 _npcInfo[i].attackdelay = 5000;
590
591 _npcInfo[i].attackDamage = 0;
592 _npcInfo[i].spellDamage = 8;
593
594 _npcInfo[i].walkspd = 1;
595
596 if (RND() * 8 == 0)
597 _npcInfo[i].hp = 0;
598 }
599
600 // yellow fire dragon
601 if (_npcInfo[i].spriteset == kMonsterYellowDragon) {
602 _npcInfo[i].hp = 100;
603 _npcInfo[i].attackdelay = 1500;
604
605 _npcInfo[i].attackDamage = 0;
606 _npcInfo[i].spellDamage = 24;
607
608 _npcInfo[i].walkspd = 1;
609
610 if (RND() * 5 == 0)
611 _npcInfo[i].hp = 0;
612 }
613
614 // twowing
615 if (_npcInfo[i].spriteset == kMonsterTwoWing) {
616 _npcInfo[i].hp = 140;
617 _npcInfo[i].attackdelay = 2000;
618 _npcInfo[i].swaySpeed = 1;
619
620 _npcInfo[i].attackDamage = 30;
621 _npcInfo[i].spellDamage = 0;
622
623 _npcInfo[i].walkspd = 1;
624
625 _npcInfo[i].castPause = 0;
626 }
627
628 // dragon2
629 if (_npcInfo[i].spriteset == kMonsterDragon2) {
630 _npcInfo[i].hp = 80;
631 _npcInfo[i].attackdelay = 1500;
632
633 _npcInfo[i].attackDamage = 24;
634 _npcInfo[i].spellDamage = 0;
635
636 _npcInfo[i].walkspd = 1;
637
638 _npcInfo[i].floating = RND() * 16;
639 }
640
641 // end boss
642 if (_npcInfo[i].spriteset == kMonsterFinalBoss) {
643 _npcInfo[i].hp = 1200;
644 _npcInfo[i].attackdelay = 2000;
645
646 _npcInfo[i].attackDamage = 100;
647 _npcInfo[i].spellDamage = 60;
648
649 _npcInfo[i].walkspd = 1;
650
651 _npcInfo[i].floating = RND() * 16;
652 }
653
654 // bat kitty
655 if (_npcInfo[i].spriteset == kMonsterBatKitty) {
656 _npcInfo[i].hp = 800;
657 _npcInfo[i].attackdelay = 2000;
658
659 _npcInfo[i].attackDamage = 100;
660 _npcInfo[i].spellDamage = 50;
661
662 _npcInfo[i].walkspd = 1;
663
664 _npcInfo[i].floating = RND() * 16;
665 }
666
667 if (!_npcInfo[i].onMap)
668 _npcInfo[i].hp = 0;
669
670 _npcInfo[i].maxhp = _npcInfo[i].hp;
671
672 _npcInfo[i].attacking = false;
673 _npcInfo[i].attackframe = 0;
674 _npcInfo[i].cattackframe = 0;
675 _npcInfo[i].attackspd = 1.5;
676 _npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay * (1 + RND() * 2);
677
678 if (_npcInfo[i].spriteset == kMonsterOneWing || _npcInfo[i].spriteset == kMonsterTwoWing) {
679 _npcInfo[i].bodysection[0].sprite = 0;
680 _npcInfo[i].bodysection[1].sprite = 1;
681 _npcInfo[i].bodysection[2].sprite = 2;
682 _npcInfo[i].bodysection[3].sprite = 3;
683 _npcInfo[i].bodysection[4].sprite = 4;
684 _npcInfo[i].bodysection[5].sprite = 3;
685 _npcInfo[i].bodysection[6].sprite = 3;
686 _npcInfo[i].bodysection[7].sprite = 5;
687
688 _npcInfo[i].bodysection[0].bonelength = 8;
689 _npcInfo[i].bodysection[1].bonelength = 7;
690 _npcInfo[i].bodysection[2].bonelength = 6;
691 _npcInfo[i].bodysection[3].bonelength = 4;
692 _npcInfo[i].bodysection[4].bonelength = 4;
693 _npcInfo[i].bodysection[5].bonelength = 4;
694 _npcInfo[i].bodysection[6].bonelength = 4;
695
696 for (int f = 0; f <= 7; f++) {
697 _npcInfo[i].bodysection[f].x = _npcInfo[i].x + 12;
698 _npcInfo[i].bodysection[f].y = _npcInfo[i].y + 14;
699 }
700
701 _npcInfo[i].headTargetX[0] = _npcInfo[i].x + 12;
702 _npcInfo[i].headTargetY[0] = _npcInfo[i].y + 14;
703
704 }
705
706 if (_npcInfo[i].spriteset == kMonsterFireHydra) {
707 for (int f = 0; f <= 29; f++) {
708 _npcInfo[i].bodysection[f].x = _npcInfo[i].x + 12;
709 _npcInfo[i].bodysection[f].y = _npcInfo[i].y + 14;
710 }
711
712 for (int f = 0; f <= 2; f++) {
713 _npcInfo[i].headTargetX[f] = _npcInfo[i].x + 12;
714 _npcInfo[i].headTargetY[f] = _npcInfo[i].y + 14;
715
716 _npcInfo[i].attacking2[f] = false;
717 _npcInfo[i].attackframe2[f] = 0;
718 }
719 }
720
721 if (_npcInfo[i].script == kScriptMasterKey) {
722 _roomLock = true;
723 if (_scriptFlag[kScriptMasterKey][0] > 0) {
724 _roomLock = false;
725 _npcInfo[i].hp = 0;
726 }
727 }
728
729 if (_npcInfo[i].script == kScriptFindCrystal) {
730 _roomLock = true;
731 if (_scriptFlag[kScriptFindCrystal][0] > 0) {
732 _roomLock = false;
733 _npcInfo[i].hp = 0;
734 }
735 }
736
737 if (_npcInfo[i].script == kScriptFindSword) {
738 _roomLock = true;
739 if (_scriptFlag[kScriptFindSword][0] > 0) {
740 _roomLock = false;
741 _npcInfo[i].hp = 0;
742 }
743 }
744
745 if (_npcInfo[i].script == kScriptGetSword3) {
746 _roomLock = true;
747 if (_scriptFlag[kScriptGetSword3][0] > 0) {
748 _roomLock = false;
749 _npcInfo[i].hp = 0;
750 }
751 }
752
753 _npcInfo[i].pause = _ticks;
754 }
755
756 file.close();
757
758
759 int cx, cy, npx, npy, lx, ly;
760
761 // academy master key
762 if (_curMap == 34 && _scriptFlag[kScriptMasterKey][0] == 1) {
763 cx = 9;
764 cy = 7;
765
766 _objectMap[cx][cy] = 5;
767
768 rcDest.left = cx * 8;
769 rcDest.top = cy * 8;
770 rcDest.setWidth(8);
771 rcDest.setHeight(8);
772
773 npx = _player.px + 12;
774 npy = _player.py + 20;
775
776 lx = (int)npx / 16;
777 ly = (int)npy / 16;
778
779 if (lx == cx && ly == cy)
780 _player.py = _player.py + 16;
781
782 _clipBg->fillRect(rcDest, ccc);
783 }
784
785 // academy crystal
786 if (_curMap == 24 && !_player.foundSpell[0] && _scriptFlag[kScriptFindCrystal][0] == 1) {
787 cx = 9;
788 cy = 7;
789
790 _objectMap[cx][cy] = 6;
791
792 rcDest.left = cx * 8;
793 rcDest.top = cy * 8;
794 rcDest.setWidth(8);
795 rcDest.setHeight(8);
796
797 npx = _player.px + 12;
798 npy = _player.py + 20;
799
800 lx = (int)npx / 16;
801 ly = (int)npy / 16;
802
803 if (lx == cx && ly == cy)
804 _player.py = _player.py + 16;
805
806 _clipBg->fillRect(rcDest, ccc);
807 }
808
809 // gardens master key
810 if (_curMap == 62 && _scriptFlag[kScriptGardenMasterKey][0] == 1) {
811 cx = 13;
812 cy = 7;
813
814 _objectMap[cx][cy] = 5;
815
816 rcDest.left = cx * 8;
817 rcDest.top = cy * 8;
818 rcDest.setWidth(8);
819 rcDest.setHeight(8);
820
821 npx = _player.px + 12;
822 npy = _player.py + 20;
823
824 lx = (int)npx / 16;
825 ly = (int)npy / 16;
826
827 if (lx == cx && ly == cy)
828 _player.py = _player.py + 16;
829
830 _clipBg->fillRect(rcDest, ccc);
831 }
832
833 // gardens fidelis sword
834 if (_curMap == 66 && _scriptFlag[kScriptFindSword][0] == 1 && _player.sword == 1) {
835 cx = 9;
836 cy = 6;
837
838 _objectMap[cx][cy] = 9;
839
840 rcDest.left = cx * 8;
841 rcDest.top = cy * 8;
842 rcDest.setWidth(8);
843 rcDest.setHeight(8);
844
845 npx = _player.px + 12;
846 npy = _player.py + 20;
847
848 lx = (int)npx / 16;
849 ly = (int)npy / 16;
850
851 if (lx == cx && ly == cy)
852 _player.py = _player.py + 16;
853
854 _clipBg->fillRect(rcDest, ccc);
855 }
856
857 // citadel armour
858 if (_curMap == 73 && _scriptFlag[kScriptArmourChest][0] == 1 && _player.armour == 1) {
859 cx = 8;
860 cy = 7;
861
862 _objectMap[cx][cy] = 16;
863
864 rcDest.left = cx * 8;
865 rcDest.top = cy * 8;
866 rcDest.setWidth(8);
867 rcDest.setHeight(8);
868
869 npx = _player.px + 12;
870 npy = _player.py + 20;
871
872 lx = (int)npx / 16;
873 ly = (int)npy / 16;
874
875 if (lx == cx && ly == cy)
876 _player.py = _player.py + 16;
877
878 _clipBg->fillRect(rcDest, ccc);
879 }
880
881 // citadel master key
882 if (_curMap == 81 && _scriptFlag[kScriptCitadelMasterKey][0] == 1) {
883 cx = 11;
884 cy = 10;
885
886 _objectMap[cx][cy] = 5;
887
888 rcDest.left = cx * 8;
889 rcDest.top = cy * 8;
890 rcDest.setWidth(8);
891 rcDest.setHeight(8);
892
893 npx = _player.px + 12;
894 npy = _player.py + 20;
895
896 lx = (int)npx / 16;
897 ly = (int)npy / 16;
898
899 if (lx == cx && ly == cy)
900 _player.py = _player.py + 16;
901
902 _clipBg->fillRect(rcDest, ccc);
903 }
904
905
906 // max ups
907 if (_curMap == 83 && _scriptFlag[kScriptGetSword3][0] == 1 && _player.sword < 3) {
908 cx = 6;
909 cy = 8;
910
911 _objectMap[cx][cy] = 18;
912
913 rcDest.left = cx * 8;
914 rcDest.top = cy * 8;
915 rcDest.setWidth(8);
916 rcDest.setHeight(8);
917
918 npx = _player.px + 12;
919 npy = _player.py + 20;
920
921 lx = (int)npx / 16;
922 ly = (int)npy / 16;
923
924 if (lx == cx && ly == cy)
925 _player.py = _player.py + 16;
926
927 _clipBg->fillRect(rcDest, ccc);
928 }
929
930 if (_curMap == 83 && _scriptFlag[kScriptShield3][0] == 1 && _player.shield < 3) {
931 cx = 9;
932 cy = 8;
933
934 _objectMap[cx][cy] = 19;
935
936 rcDest.left = cx * 8;
937 rcDest.top = cy * 8;
938 rcDest.setWidth(8);
939 rcDest.setHeight(8);
940
941 npx = _player.px + 12;
942 npy = _player.py + 20;
943
944 lx = (int)npx / 16;
945 ly = (int)npy / 16;
946
947 if (lx == cx && ly == cy)
948 _player.py = _player.py + 16;
949
950 _clipBg->fillRect(rcDest, ccc);
951 }
952
953 if (_curMap == 83 && _scriptFlag[kScriptArmour3][0] == 1 && _player.armour < 3) {
954 cx = 12;
955 cy = 8;
956
957 _objectMap[cx][cy] = 20;
958
959 rcDest.left = cx * 8;
960 rcDest.top = cy * 8;
961 rcDest.setWidth(8);
962 rcDest.setHeight(8);
963
964 npx = _player.px + 12;
965 npy = _player.py + 20;
966
967 lx = (int)npx / 16;
968 ly = (int)npy / 16;
969
970 if (lx == cx && ly == cy)
971 _player.py = _player.py + 16;
972
973 _clipBg->fillRect(rcDest, ccc);
974 }
975
976 _clipBg2->copyRectToSurface(_clipBg->getPixels(), _clipBg->pitch, 0, 0, _clipBg->w, _clipBg->h);
977 }
978
loadAnims()979 void GriffonEngine::loadAnims() {
980 _spellImg = loadImage("art/spells.bmp", true);
981 _anims[0] = loadImage("art/anims0.bmp", true);
982 _animsAttack[0] = loadImage("art/anims0a.bmp", true);
983 _anims[13] = loadImage("art/anims0x.bmp", true);
984 _animsAttack[13] = loadImage("art/anims0xa.bmp", true);
985 _anims[1] = loadImage("art/anims1.bmp", true);
986 _animsAttack[1] = loadImage("art/anims1a.bmp", true);
987 _anims[2] = loadImage("art/anims2.bmp", true);
988
989 // huge
990 _animSet2[0].xofs = 8;
991 _animSet2[0].yofs = 7;
992 _animSet2[0].x = 123;
993 _animSet2[0].y = 0;
994 _animSet2[0].w = 18;
995 _animSet2[0].h = 16;
996 // big
997 _animSet2[1].xofs = 7;
998 _animSet2[1].yofs = 7;
999 _animSet2[1].x = 107;
1000 _animSet2[1].y = 0;
1001 _animSet2[1].w = 16;
1002 _animSet2[1].h = 14;
1003 // med
1004 _animSet2[2].xofs = 6;
1005 _animSet2[2].yofs = 6;
1006 _animSet2[2].x = 93;
1007 _animSet2[2].y = 0;
1008 _animSet2[2].w = 14;
1009 _animSet2[2].h = 13;
1010 // small
1011 _animSet2[3].xofs = 4;
1012 _animSet2[3].yofs = 4;
1013 _animSet2[3].x = 83;
1014 _animSet2[3].y = 0;
1015 _animSet2[3].w = 10;
1016 _animSet2[3].h = 10;
1017 // wing
1018 _animSet2[4].xofs = 4;
1019 _animSet2[4].yofs = 20;
1020 _animSet2[4].x = 42;
1021 _animSet2[4].y = 0;
1022 _animSet2[4].w = 41;
1023 _animSet2[4].h = 33;
1024 // head
1025 _animSet2[5].xofs = 20;
1026 _animSet2[5].yofs = 18;
1027 _animSet2[5].x = 0;
1028 _animSet2[5].y = 0;
1029 _animSet2[5].w = 42;
1030 _animSet2[5].h = 36;
1031
1032 _anims[9] = loadImage("art/anims9.bmp", true);
1033
1034 // huge
1035 _animSet9[0].xofs = 8;
1036 _animSet9[0].yofs = 7;
1037 _animSet9[0].x = 154;
1038 _animSet9[0].y = 0;
1039 _animSet9[0].w = 18;
1040 _animSet9[0].h = 16;
1041 // big
1042 _animSet9[1].xofs = 7;
1043 _animSet9[1].yofs = 7;
1044 _animSet9[1].x = 138;
1045 _animSet9[1].y = 0;
1046 _animSet9[1].w = 16;
1047 _animSet9[1].h = 14;
1048 // med
1049 _animSet9[2].xofs = 6;
1050 _animSet9[2].yofs = 6;
1051 _animSet9[2].x = 93 + 31;
1052 _animSet9[2].y = 0;
1053 _animSet9[2].w = 14;
1054 _animSet9[2].h = 13;
1055 // small
1056 _animSet9[3].xofs = 4;
1057 _animSet9[3].yofs = 4;
1058 _animSet9[3].x = 83 + 31;
1059 _animSet9[3].y = 0;
1060 _animSet9[3].w = 10;
1061 _animSet9[3].h = 10;
1062 // wing
1063 _animSet9[4].xofs = 36;
1064 _animSet9[4].yofs = 20;
1065 _animSet9[4].x = 42;
1066 _animSet9[4].y = 0;
1067 _animSet9[4].w = 72;
1068 _animSet9[4].h = 33;
1069 // head
1070 _animSet9[5].xofs = 20;
1071 _animSet9[5].yofs = 18;
1072 _animSet9[5].x = 0;
1073 _animSet9[5].y = 0;
1074 _animSet9[5].w = 42;
1075 _animSet9[5].h = 36;
1076
1077 _anims[3] = loadImage("art/anims3.bmp", true);
1078 _anims[4] = loadImage("art/anims4.bmp", true);
1079 _anims[5] = loadImage("art/anims5.bmp", true);
1080 _anims[6] = loadImage("art/anims6.bmp", true);
1081 _anims[7] = loadImage("art/anims7.bmp", true);
1082 _anims[8] = loadImage("art/anims8.bmp", true);
1083 _anims[10] = loadImage("art/anims10.bmp", true);
1084 _animsAttack[10] = loadImage("art/anims10a.bmp", true);
1085 _anims[11] = loadImage("art/anims11.bmp", true);
1086 _animsAttack[11] = loadImage("art/anims11a.bmp", true);
1087 _anims[12] = loadImage("art/anims12.bmp", true);
1088 }
1089
loadItemImgs()1090 void GriffonEngine::loadItemImgs() {
1091 Graphics::TransparentSurface *temp = loadImage("art/icons.bmp", true);
1092
1093 for (int i = 0; i <= 20; i++) {
1094 _itemImg[i] = new Graphics::TransparentSurface;
1095 _itemImg[i]->create(16, 16, g_system->getScreenFormat());
1096
1097 rcSrc.left = i * 16;
1098 rcSrc.top = 0;
1099 rcSrc.setWidth(16);
1100 rcSrc.setHeight(16);
1101
1102 temp->blit(*_itemImg[i], 0, 0, Graphics::FLIP_NONE, &rcSrc);
1103 }
1104
1105 temp->free();
1106 }
1107
loadFont()1108 void GriffonEngine::loadFont() {
1109 Graphics::TransparentSurface *font = loadImage("art/font.bmp", true);
1110
1111 for (int i = 32; i <= 255; i++)
1112 for (int f = 0; f <= 4; f++) {
1113 int i2 = i - 32;
1114
1115 _fontChr[i2][f] = new Graphics::TransparentSurface;
1116 _fontChr[i2][f]->create(8, 8, g_system->getScreenFormat());
1117
1118 int col = i2 % 40;
1119
1120 int row = (i2 - col) / 40;
1121
1122 rcSrc.left = col * 8;
1123 rcSrc.top = row * 8 + f * 48;
1124 rcSrc.setWidth(8);
1125 rcSrc.setHeight(8);
1126
1127 rcDest.left = 0;
1128 rcDest.top = 0;
1129 font->blit(*_fontChr[i2][f], rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc);
1130 }
1131
1132 font->free();
1133 }
1134
loadTiles()1135 void GriffonEngine::loadTiles() {
1136 _tiles[0] = loadImage("art/tx.bmp", true);
1137 _tiles[1] = loadImage("art/tx1.bmp", true);
1138 _tiles[2] = loadImage("art/tx2.bmp", true);
1139 _tiles[3] = loadImage("art/tx3.bmp", true);
1140
1141 _windowImg = loadImage("art/window.bmp", true);
1142 }
1143
loadTriggers()1144 void GriffonEngine::loadTriggers() {
1145 Common::File file;
1146 file.open("data/triggers.dat");
1147
1148 if (!file.isOpen())
1149 error("Cannot open file data/Triggers.dat");
1150
1151 for (int i = 0; i <= 9999; i++) {
1152 for (int a = 0; a <= 8; a++)
1153 INPUT("%i", &_triggers[i][a]);
1154 }
1155
1156 file.close();
1157 }
1158
loadObjectDB()1159 void GriffonEngine::loadObjectDB() {
1160 Common::File file;
1161
1162 file.open("objectdb.dat");
1163 if (!file.isOpen())
1164 error("Cannot open file objectdb.dat");
1165
1166 for (int a = 0; a <= 32; a++) {
1167 INPUT("%i", &_objectInfo[a].nFrames);
1168 INPUT("%i", &_objectInfo[a].xTiles);
1169 INPUT("%i", &_objectInfo[a].yTiles);
1170 INPUT("%i", &_objectInfo[a].speed);
1171 INPUT("%i", &_objectInfo[a].type);
1172 INPUT("%i", &_objectInfo[a].script);
1173
1174 for (int b = 0; b <= 8; b++) {
1175 for (int c = 0; c <= 2; c++) {
1176 for (int d = 0; d <= 2; d++) {
1177 for (int e = 0; e <= 1; e++) {
1178 INPUT("%i", &_objectTile[a][b][c][d][e]);
1179 }
1180 }
1181 }
1182 }
1183 }
1184
1185 file.close();
1186 }
1187
1188
1189 } // end of namespace Griffon
1190