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  *              Originally written by Syn9 in FreeBASIC with SDL
22  *              http://syn9.thehideoutgames.com/index_backup.php
23  *
24  *            Ported to plain C for GCW-Zero handheld by Dmitry Smagin
25  *                http://github.com/dmitrysmagin/griffon_legend
26  *
27  *
28  *                 Programming/Graphics: Daniel "Syn9" Kennedy
29  *                     Music/Sound effects: David Turner
30  *
31  *                   Beta testing and gameplay design help:
32  *                    Deleter, Cha0s, Aether Fox, and Kiz
33  *
34  */
35 
36 #ifndef GRIFFON_GRIFFON_H
37 #define GRIFFON_GRIFFON_H
38 
39 #include "common/scummsys.h"
40 #include "common/error.h"
41 #include "common/events.h"
42 #include "common/random.h"
43 #include "engines/engine.h"
44 
45 #include "audio/mixer.h"
46 
47 #include "graphics/transparent_surface.h"
48 
49 namespace Griffon {
50 
51 class Console;
52 
53 #define kSoundHandles 16
54 #define kMaxNPC      32
55 #define kMaxFloat    32
56 #define kMaxSpell    32
57 
58 // spells
59 enum {
60 	kSpellIce = 0,
61 	kSpellSteel,
62 	kSpellWood,
63 	kSpellRock,
64 	kSpellFire
65 };
66 
67 // inventory items
68 enum {
69 	kInvFlask = 0,
70 	kInvDoubleFlask,
71 	kInvShock,
72 	kInvNormalKey,
73 	kInvMasterKey
74 };
75 
76 enum {
77 	kSndBite = 0,
78 	kSndCrystal,
79 	kSndDoor,
80 	kSndEnemyHit,
81 	kSndIce,
82 	kSndLever,
83 	kSndLightning,
84 	kSndMetalHit,
85 	kSndPowerUp,
86 	kSndRocks,
87 	kSndSwordHit,
88 	kSndThrow,
89 	kSndChest,
90 	kSndFire,
91 	kSndBeep
92 };
93 
94 //  in game scripts
95 enum {
96 	kScriptFlask = 0,			// get flask
97 	kScriptMasterKey = 2, 		// find master key
98 	kScriptFindCrystal = 3,		// find crystal
99 	kScriptFindShield = 4,		// find shield - obj 8
100 	kScriptFindSword = 5,		// find sword - obj 9
101 	kScriptKeyChest = 6,		// regular key chest
102 	kScriptBlueFlask = 7,		// blue flask
103 	kScriptGardenMasterKey = 8,	// garden's master key
104 	kScriptLightningBomb = 9,	// lightning bomb
105 	kScriptBlueFlaskChest = 10,	// blue flask chest
106 	kScriptLightningChest = 11,	// lightning chest
107 	kScriptArmourChest = 12,	// armour chest
108 	kScriptCitadelMasterKey = 13,	// citadel master key
109 	kScriptEndOfGame = 14,		// end of game
110 	kScriptGetSword3 = 15,		// get sword3
111 	kScriptShield3 = 16,		// shield3
112 	kScriptArmour3 = 17,		// armour3
113 	kScriptKeyChest1 = 20,		// key chest 1
114 	kScriptLever = 60			// lever
115 };
116 
117 // monsters
118 enum {
119 	kMonsterBabyDragon = 1, 	// baby dragon
120  	kMonsterOneWing = 2,		// one wing
121  	kMonsterBoss1 = 3, 			// boss 1
122  	kMonsterBlackKnight = 4,	// black knight
123  	kMonsterFireHydra = 5,		// fire hydra
124  	kMonsterRedDragon = 6,		// red dragon
125  	kMonsterPriest = 7,			// priest
126  	kMonsterYellowDragon = 8,	// yellow fire dragon
127  	kMonsterTwoWing = 9,		// two wing
128 	kMonsterDragon2 = 10,		// dragon2
129 	kMonsterFinalBoss = 11,		// final boss
130 	kMonsterBatKitty = 12		// bat kitty
131 };
132 
133 // engine actions
134 enum GriffonActions {
135 	kGriffonLeft,
136 	kGriffonRight,
137 	kGriffonUp,
138 	kGriffonDown,
139 	kGriffonAttack,
140 	kGriffonInventory,
141 	kGriffonMenu,
142 	kGriffonConfirm,
143 	kGriffonCutsceneSpeedUp
144 };
145 
146 #define kEpsilon 0.001
147 
148 struct Player {
149 	float   px;
150 	float   py;
151 	float   opx;
152 	float   opy;
153 	int     walkDir;
154 	float   walkFrame;
155 	float   walkSpeed;
156 	float   attackFrame;
157 	float   attackSpeed;
158 
159 	int hp;
160 	int maxHp;
161 	float hpflash;
162 	int hpflashb;
163 	int level;
164 	int maxLevel;
165 	int sword;
166 	int shield;
167 	int armour;
168 	int foundSpell[5];
169 	float spellCharge[5];
170 	int inventory[5];
171 	float attackStrength;
172 	float spellStrength;
173 	int spellDamage;
174 	int swordDamage;
175 
176 	int exp;
177 	int nextLevel;
178 
179 	int pause;
180 
181 	float itemselshade;
182 	int ysort;
183 
184 	void reset();
185 };
186 
187 struct BodySection {
188 	float   x;
189 	float   y;
190 	int parentID;
191 	int isbase;
192 	int sprite;
193 	int bonelength; // the 'bone' that connects the body sections
194 };
195 
196 struct NPC {
197 	float x;
198 	float y;
199 	int spriteset;
200 	int x1;     // patrol area
201 	int y1;
202 	int x2;
203 	int y2;
204 	int attitude;
205 	int hp;
206 
207 	int maxhp;
208 	int item1;
209 	int item2;
210 	int item3;
211 	int script;
212 	float frame;
213 	float frame2;     // end boss specific
214 	int cframe;
215 	bool onMap;      // is this npc set to be genned in the mapfile
216 
217 	int ticks;
218 	int pause;
219 	int shake;
220 
221 	int movementmode;
222 	int walkdir;
223 	float walkspd;
224 	int movingdir;
225 	bool moving;
226 
227 	bool attacking;
228 	float attackframe;
229 	int cattackframe;
230 	float attackspd;
231 	int attackdelay;
232 	int attacknext;
233 	int attackattempt;
234 
235 	int spellDamage;
236 	int attackDamage;
237 
238 
239 	// one wing and firehydra specific
240 	BodySection bodysection[31];
241 	float swayAngle;
242 	float swaySpeed;
243 	float headTargetX[4];
244 	float headTargetY[4];
245 	int castPause;
246 
247 	// firehydra specific
248 	int attacknext2[4];
249 	bool attacking2[4];
250 	int attackframe2[4];
251 
252 	// dragon2 specific
253 	float   floating;
254 };
255 
256 struct Spell {
257 	int spellnum;
258 	float   homex;
259 	float   homey;
260 	float   enemyx;
261 	float   enemyy;
262 
263 	float   frame;
264 
265 	int damagewho;  // 0 = npc, 1 = player
266 
267 	// for earthslide
268 	float   rocky[9]; // CHECKME: Looks unused
269 	int rockimg[9];
270 	int rockdeflect[9];
271 
272 	float   strength;
273 
274 	// fire
275 	int legalive[5];
276 
277 	// spell 6 specific
278 	float   fireballs[7][4];    // x,y,targetx, targety
279 	int nfballs;
280 	int ballon[7];
281 
282 	int npc;
283 };
284 
285 struct AnimSet {
286 	int x;  // xyloc on spriteimageset
287 	int y;
288 	int xofs;   // the actual place to paste the sprite in reference to the bodypart loc on screen
289 	int yofs;
290 	int w;  // w/h of the sprite in the imageset
291 	int h;
292 };
293 
294 struct DataChunk {
295 	byte *data;
296 	int size;
297 };
298 
299 struct FloatTextStruct {
300 	float framesLeft;
301 	float x;
302 	float y;
303 	int col;
304 	char *text;
305 };
306 
307 struct FloatIconStruct {
308 	float framesLeft;
309 	float x;
310 	float y;
311 	int ico;
312 };
313 
314 struct AttackOffsetStruct {
315 	float x;
316 	float y;
317 	bool completed;
318 };
319 
320 struct Config {
321 	bool music;
322 	int musicVol;
323 	bool effects;
324 	int effectsVol;
325 };
326 
327 struct ObjectInfoStruct {
328 	int nFrames;
329 	int xTiles;
330 	int yTiles;
331 	int speed;
332 	int type;
333 	int script;
334 };
335 
336 enum {
337 	kGameModeIntro,
338 	kGameModePlay,
339 	kGameModeNewGame,
340 	kGameModeLoadGame
341 };
342 
343 class GriffonEngine : public Engine {
344 public:
345 	GriffonEngine(OSystem *syst);
346 	~GriffonEngine() override;
347 
348 	Common::Error run() override;
349 	void syncSoundSettings() override;
350 
351 private:
352 	Common::RandomSource *_rnd;
353 	bool _shouldQuit;
354 	int _gameMode;
355 
356 	Console *_console;
357 
358 private:
359 
360 	// combat.cpp
361 	void attack();
362 	void castSpell(int spellnum, float homex, float homey, float enemyx, float enemyy, int damagewho);
363 	void checkHit();
364 	void damageNPC(int npcnum, int damage, int spell);
365 	void damagePlayer(int damage);
366 
367 	// cutscenes.cpp
368 	void showLogos();
369 	void intro();
370 	void endOfGame();
371 	void theEnd();
372 
373 	// dialogs.cpp
374 	void title(int mode);
375 	void configMenu();
376 	void saveLoadNew();
377 	void renderSaveStates();
378 
379 	// draw.cpp
380 	void drawAnims(int Layer);
381 	void drawHud();
382 	void drawNPCs(int mode);
383 	void drawOver(int modx, int mody);
384 	void drawPlayer();
385 	void drawView();
386 	void swash();
387 
388 	// engine.cpp
389 	float RND();
390 
391 	void mainLoop();
392 	void updateEngine();
393 	void newGame();
394 
395 	// gfx.cpp
396 	void addFloatIcon(int ico, float xloc, float yloc);
397 	void addFloatText(const char *stri, float xloc, float yloc, int col);
398 	void eventText(const char *stri);
399 	void drawLine(Graphics::TransparentSurface *buffer, int x1, int y1, int x2, int y2, int col);
400 	void drawString(Graphics::TransparentSurface *buffer, const char *stri, int xloc, int yloc, int col);
401 	void drawProgress(int w, int wm);
402 
403 	// input.cpp
404 	void checkInputs();
405 	void handleWalking();
406 	void checkTrigger();
407 	void processTrigger(int trignum);
408 
409 	// logic.cpp
410 	void updateAnims();
411 	void updateY();
412 	void updateNPCs();
413 	void updateSpells();
414 	void updateSpellsUnder();
415 
416 	// resources.cpp
417 	void initialize();
418 	Graphics::TransparentSurface *loadImage(const char *name, bool colorkey = false);
419 	void loadMap(int mapnum);
420 	void loadAnims();
421 	void loadFont();
422 	void loadItemImgs();
423 	void loadTiles();
424 	void loadTriggers();
425 	void loadObjectDB();
426 
427 	// saveload.cpp
428 	Common::String getSaveStateName(int slot) const override;
429 	int loadPlayer(int slotnum);
430 	Common::Error loadGameState(int slot) override;
431 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
432 	Common::Error loadGameStream(Common::SeekableReadStream *file) override;
433 	Common::Error saveGameStream(Common::WriteStream *file, bool isAutosave) override;
434 
435 	// sound.cpp
436 	void setChannelVolume(int channel, int volume);
437 	int getSoundHandle();
438 	int playSound(DataChunk *chunk, bool looped = false);
439 	void pauseSoundChannel(int channel);
440 	void haltSoundChannel(int channel);
441 	void resumeSoundChannel(int channel);
442 	bool isSoundChannelPlaying(int channel);
443 	void setupAudio();
444 	void updateMusic();
445 
canLoadGameStateCurrently()446 	bool canLoadGameStateCurrently() override { return true; }
canSaveGameStateCurrently()447 	bool canSaveGameStateCurrently() override { return _gameMode == kGameModePlay; }
getAutosaveSlot()448 	int getAutosaveSlot() const override { return 4; }
449 	bool hasFeature(EngineFeature f) const override;
450 
451 private:
452 	Graphics::TransparentSurface *_video, *_videoBuffer, *_videoBuffer2, *_videoBuffer3;
453 
454 	// system
455 	Graphics::TransparentSurface *_titleImg, *_titleImg2, *_inventoryImg;
456 	Graphics::TransparentSurface *_logosImg, *_theEndImg;
457 	Common::Event _event;
458 
459 	Graphics::TransparentSurface *_mapBg, *_clipBg, *_clipBg2;
460 	unsigned int _clipSurround[4][4];
461 
462 	float _animSpeed; // CHECKME: it seems to always be 0.5
463 	int _rampData[40][24];
464 
465 	int _curMap;
466 	Graphics::TransparentSurface *_fontChr[224][5]; // 256 - 32
467 	Graphics::TransparentSurface *_itemImg[21], *_windowImg;
468 	Graphics::TransparentSurface *_spellImg;
469 
470 	bool _itemSelOn;
471 	int _curItem, _itemTicks;
472 	float _itemyloc;
473 	bool _selEnemyOn;
474 	int _curEnemy;
475 	bool _forcePause;
476 	bool _roomLock; // set to disable any room jumps while in the room
477 	int _scriptFlag[100][10], _saveSlot;  // script, flag
478 
479 	// timer related - move to local later
480 	int _ticks, _ticksPassed, _nextTicks;
481 	float _fp, _fps, _fpsr; // CHECKME: _fp and _fps seems to be integers
482 	int _secsInGame, _secStart;
483 
484 	Graphics::TransparentSurface *mapImg[4];
485 
486 	Common::Rect rcSrc, rcDest;
487 
488 	// -----------special case
489 	bool _dontDrawOver;   // used in map24 so that the candles don't draw over the boss, default set to 0
490 
491 	// saveload info
492 	Graphics::TransparentSurface *_saveLoadImg;
493 
494 	// post info
495 	float _postInfo[21][3];
496 	int _postInfoNbr;
497 
498 	// cloud info
499 	Graphics::TransparentSurface *_cloudImg;
500 	float _cloudAngle;
501 	int _cloudsOn;
502 
503 	// spell info
504 	Spell _spellInfo[kMaxSpell];
505 
506 	// player info
507 	Player _player;
508 	Player _playera;
509 	bool _movingUp, _movingDown, _movingLeft, _movingRight;
510 	bool _attacking;
511 	int _asecstart;
512 
513 	// tile info
514 	Graphics::TransparentSurface *_tiles[4];
515 	int _tileinfo[3][40][24][3]; // maplayer, x, y, tiledata (tile, tilelayer)
516 
517 	// animation info
518 	Graphics::TransparentSurface *_anims[100];
519 	// id number 0&1 = players
520 	Graphics::TransparentSurface *_animsAttack[100];
521 	// attack anims
522 	AttackOffsetStruct _playerAttackOfs[4][16];
523 
524 	FloatTextStruct _floatText[kMaxFloat];
525 	FloatIconStruct _floatIcon[kMaxFloat];
526 
527 	// special for animset2
528 	AnimSet _animSet2[7], _animSet9[7];
529 
530 	// object info
531 	float _objectFrame[256][2];
532 	int _lastObj;
533 	// frame!, curframe
534 	ObjectInfoStruct _objectInfo[33];
535 
536 	int _objectTile[33][9][3][3][2];
537 	// [objnum] [frame] [x] [y] [tile/layer]
538 	int _objectMap[21][15];
539 
540 	int _objectMapFull[1000][21][15];
541 	// [mapnum] x, y  set to 1 to make this objmap spot stay at -1
542 
543 	// trigger info
544 	int _triggers[10000][9];
545 	// [map#][index], [var]
546 	// map#,x,y
547 	int _triggerLoc[320][240], _triggerNbr;
548 
549 	// npc info
550 	NPC _npcInfo[kMaxNPC];
551 	int _lastNpc;
552 
553 	// music info
554 	DataChunk *_musicGardens1, *_musicGardens2, *_musicGardens3, *_musicGardens4, *_musicBoss, *_musicMenu, *_musicEndOfGame;
555 	int _musicChannel, _menuChannel;
556 	bool _playingBoss, _playingGardens;
557 
558 	DataChunk *_sfx[15];
559 	Audio::SoundHandle _handles[kSoundHandles];
560 	Audio::Mixer *_mixer;
561 
562 	// set to 1 for normal key, set to 2 for master, set to 0 if unlocked
563 	int _roomLocks[201], _lockType;
564 	int _roomToUnlock;
565 
566 	bool _canUseKey;
567 	bool _saidLocked;
568 	bool _saidJammed;
569 
570 	// ysort
571 	int _ysort[2401], _lasty, _firsty;
572 
573 	bool _pmenu;
574 
575 	Config config;
576 	void saveConfig();
577 };
578 
579 }
580 
581 #endif // GRIFFON_GRIFFON_H
582