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