scummvm/engines/immortal/immortal.h
2024-08-26 10:42:04 +03:00

775 lines
28 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef IMMORTAL_H
#define IMMORTAL_H
// Audio is only handled in kernel, therefore it is only needed here
#include "audio/mixer.h"
// Immortal.h is the engine, so it needs the engine headers
#include "engines/engine.h"
#include "engines/savestate.h"
// Theorectically, all graphics should be handled through driver, which is part of kernel, which is in immortal.h
#include "graphics/screen.h"
#include "graphics/surface.h"
// Detection is only needed by the main engine
#include "immortal/detection.h"
#include "common/formats/prodos.h"
#include "common/debug-channels.h"
#include "common/events.h"
#include "common/scummsys.h"
#include "common/system.h"
#include "common/fs.h"
#include "common/hash-str.h"
#include "common/random.h"
#include "common/serializer.h"
#include "common/util.h"
#include "common/platform.h"
// Utilities.h contains many things used by all objects, not just immortal
#include "immortal/utilities.h"
// Room also includes story.h
#include "immortal/room.h"
namespace Immortal {
// Needed by kernel for input
enum InputAction {
kActionNothing,
kActionKey,
kActionRestart, // Key "R" <-- Debug?
kActionSound,
kActionFire,
kActionButton, // Does this just refer to whatever is not the fire button?
kActionDBGStep // Debug key for moving engine forward one frame at a time
};
enum ButtonHeldMask {
kButton0Held = 2,
kButton1Held = 4
};
enum InputDirection {
kDirectionUp,
kDirectionLeft,
kDirectionDown,
kDirectionRight
};
// Needed by kernel for text
enum FadeType {
kTextFadeIn,
kTextDontFadeIn
};
// Needed by kernel for music
enum Song {
kSongNothing,
kSongMaze,
kSongCombat,
kSongText
};
enum Sound {
kSoundSwish = 6,
kSoundAwe,
kSoundHuh,
kSoundClank,
kSoundFireBall,
kSoundDoor
};
// Needed by logic for various things
enum MonsterID {
kPlayerID
};
// Needed by logic for certificate processing
enum CertificateIndex : uint8 {
kCertHits,
kCertLevel,
kCertLoGameFlags,
kCertHiGameFlags,
kCertQuickness,
kCertInvLo,
kCertInvHi,
kCertGoldLo,
kCertGoldHi
};
// Needed by logic for various things
enum GameFlags : uint8 {
kSavedNone,
kSavedKing,
kSavedAna
};
// Needed by level (maybe?)
enum LevelType {
kRoomType,
kMonsterType,
kObjectType
};
// Basically the equivalent of the explosion from a projectile in other games I think
struct Spark {
};
// Generic sprites can be used anywhere, just sort of misc sprites
struct GenericSprite {
};
// Doors are a property of the level, not the room, they define the connections between rooms
struct Door {
uint8 _x = 0;
uint8 _y = 0;
uint8 _fromRoom = 0;
uint8 _toRoom = 0;
uint8 _busyOnRight = 0;
uint8 _on = 0;
};
// Universe is a set of properties for the entire level, nor just the room
struct Univ {
uint16 _rectX = 0;
uint16 _rectY = 0;
uint16 _numAnims = 0;
uint16 _numCols = 0;
uint16 _numRows = 0;
uint16 _numChrs = 0;
uint16 _num2Cols = 0;
uint16 _num2Rows = 0;
uint16 _num2Cells = 0;
uint16 _num2Chrs = 0;
};
struct Chr {
byte *_scanlines[32];
};
struct ImmortalGameDescription;
// Forward declaration because we will need the Disk and Room classes
class ProDosDisk;
class Room;
class ImmortalEngine : public Engine {
private:
Common::RandomSource _randomSource;
protected:
// Engine APIs
Common::Error run() override;
public:
ImmortalEngine(OSystem *syst, const ADGameDescription *gameDesc);
~ImmortalEngine() override;
const ADGameDescription *_gameDescription;
/* Terrible functions because C doesn't like
* bit manipulation enough
*/
uint16 xba(uint16 ab); // This just replicates the XBA command from the 65816, because flipping the byte order is somehow not a common library function???
uint16 rol(uint16 ab, int n); // Rotate bits left by n
uint16 ror(uint16 ab, int n); // Rotate bits right by n
uint16 mult16(uint16 a, uint16 b); // Just avoids using (uint16) everywhere, and is slightly closer to the original
/*
* --- Members ---
*
*/
/*
* Constants
*/
// Misc constants
const int kNumLengths = 21;
const int kNiceTime = 36;
const int kMaxCertificate = 16;
// Screen constants
const int kScreenW__ = 128; // ??? labeled in source as SCREENWIDTH
const int kScreenH__ = 128; // ???
const int kViewPortW = 256;
const int kViewPortH = 128;
const int kScreenSize = (kResH * kResV) * 2; // The size of the screen buffer is (320x200) * 2 byte words
const uint16 kScreenLeft = 32;
const uint16 kScreenTop = 20;
const uint8 kTextLeft = 8;
const uint8 kTextTop = 4;
const uint8 kGaugeX = 0;
const uint8 kGaugeY = static_cast<uint8>((-13) & 0xff); // ???
const uint16 kScreenBMW = 160; // Screen BitMap Width?
const uint16 kChrW = 64;
const uint16 kChrH = 32;
const uint16 kChrH2 = kChrH * 2;
const uint16 kChrH3 = kChrH * 3;
const uint16 kChrLen = (kChrW / 2) * kChrH;
const uint16 kChrBMW = kChrW / 2;
const uint16 kLCutaway = 4;
const uint16 kLDrawSolid = 32 * ((3 * 16) + 5);
const uint16 kChrDy[19] = {kChr0, kChrH, kChrH2, kChrH, kChrH2,
kChrH2, kChrH, kChrH2, kChrH2, kChr0,
kChr0, kChrH2, kChrH, kChrH2, kChrH2,
kChrH2, kChrH, kChrH2, kChrH2
};
const uint16 kChrMask[19] = {kChr0, kChr0, kChr0, kChr0,
kChrR, kChrL, kChr0, kChrL,
kChrR, kChr0, kChr0, kChrLD,
kChr0, kChrR, kChrLD, kChrRD,
kChr0, kChrRD, kChrL
};
const uint16 kIsBackground[36] = {1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
};
// Disk offsets
const int kPaletteOffset = 21205; // This is the byte position of the palette data in the disk
// Sprite constants
const uint16 kMaxSpriteW = 64;
const uint16 kMaxSpriteH = 64;
const uint16 kSpriteDY = 32;
const uint16 kVSX = kMaxSpriteW;
const uint16 kVSY = kSpriteDY;
const uint16 kVSBMW = (kViewPortW + kMaxSpriteW) / 2;
const uint16 kVSLen = kVSBMW * (kViewPortH + kMaxSpriteH);
const uint16 kVSDY = 32; // difference from top of screen to top of viewport in the virtual screen buffer
const uint16 kMySuperBottom = kVSDY + kViewPortH;
const uint16 kSuperBottom = 200;
const uint16 kMySuperTop = kVSDY;
const uint16 kSuperTop = 0;
const uint16 kViewPortSpX = 32;
const uint16 kViewPortSpY = 0;
const uint16 kWizardX = 28; // Common sprite center for some reason
const uint16 kWizardY = 37;
const uint16 kObjectY = 24;
const uint16 kObjectX = 32;
const uint16 kObjectHeight = 48;
const uint16 kObjectWidth = 64;
// Text constants
const uint8 kMaxRows = 5;
const uint8 kMaxCollumns = 26;
const uint16 kYesNoY = 88;
const uint16 kYesNoX1 = 8;
const uint16 kYesNoX2 = 182;
// Asset constants
const char kGaugeOn = 1; // On uses the sprite at index 1 of the font spriteset
const char kGaugeOff = 0; // Off uses the sprite at index 0 of the font spriteset
const char kGaugeStop = 1; // Literally just means the final kGaugeOn char to draw
const char kGaugeStart = 1; // First kGaugeOn char to draw
// Level constants
const int kStoryNull = 5;
const int kMaxFilesPerLevel = 16;
const int kMaxPartInstances = 4;
const int kLevelToMaze[8] = {0, 0, 1, 1, 2, 2, 2, 3};
/*
* 'global' members
*/
// Misc
Common::ErrorCode _err; // If this is not kNoError at any point, the engine will stop
uint8 _certificate[16]; // The certificate (password) is basically the inventory/equipment array
uint8 _lastCertLen = 0;
bool _draw = 0; // Whether the screen should draw this frame
int _zero = 0; // No idea what this is yet
bool _gameOverFlag = false;
uint8 _gameFlags = 0; // Bitflag array of event flags, but only two were used (saving ana and saving the king) <-- why is gameOverFlag not in this? Lol
bool _themePaused = false; // In the source, this is actually considered a bit flag array of 2 bits (b0 and b1). However, it only ever checks for non-zero, so it's effectively only 1 bit.
int _titlesShown = 0;
int _time = 0;
int _promoting = 0; // I think promoting means the title stuff
bool _restart = false;
// Story members
Story _stories[8];
// Level members
int _maxLevels = 0; // This is determined when loading in story files
int _level = 0;
bool _levelOver = false;
int _count = 0;
int _lastLevelLoaded = 0;
int _lastSongLoaded = 0;
int _storyLevel = 0;
int _storyX = 0;
int _loadA = 0;
int _loadY = 0;
uint16 _initialX = 0;
uint16 _initialY = 0;
int _initialBX = 0;
int _initialBY = 0;
int _dRoomNum = 0;
int _initialRoom = 0;
int _currentRoom = 0;
int _lastType = 0;
int _roomCellX = 0;
int _roomCellY = 0;
Room *_rooms[kMaxRooms]; // Rooms within the level
Common::Array<SFlame> _allFlames[kMaxRooms]; // The level needs it's own set of flames so that the flames can be turned on/off permanently. This is technically more like a hashmap in the source, but it could also be seen as a 2d array, just hashed together in the source
// Door members
Common::Array<Door> _doors;
uint8 _numDoors = 0;
uint8 _doorRoom = 0;
uint8 _doorToNextLevel = 0;
uint8 _doorCameInFrom = 0;
uint8 _ladders = 0;
uint8 _numLadders = 0;
uint8 _ladderInUse = 0;
uint8 _secretLadder = 0;
uint8 _secretCount = 0;
uint8 _secretDelta = 0;
// Debug members
bool _singleStep = false; // Flag for _singleStep mode
// Input members
int _pressedAction = 0;
int _heldAction = 0;
int _pressedDirection = 0;
int _heldDirection = 0;
// Text printing members
uint8 _slowText = 0;
uint8 _formatted = 0;
uint8 _collumn = 0;
uint8 _row = 0;
uint8 _myButton = 0;
uint8 _lastYes = 0;
// Music members
Song _playing; // Currently playing song
int _themeID = 0; // Not sure yet tbh
int _combatID = 0;
// Asset members
int _numSprites = 0; // This is more accurately actually the index within the sprite array, so _numSprites + 1 is the current number of sprites
DataSprite _dataSprites[kFont + 1]; // All the sprite data, indexed by SpriteName
Sprite _sprites[kMaxSprites]; // All the sprites shown on screen
Cycle _cycles[kMaxCycles];
Common::Array<Common::String> _strPtrs; // Str should really be a char array, but inserting frame values will be stupid so it's just a string instead
Common::Array<Motive> _motivePtrs;
Common::Array<Damage> _damagePtrs;
Common::Array<Use> _usePtrs;
Common::Array<Pickup> _pickupPtrs;
Common::Array<SCycle> _cycPtrs; // This is not actually a set of pointers, but it is serving the function of what was called cycPtrs in the source
CArray2D<Motive> _programPtrs;
Common::Array<ObjType> _objTypePtrs;
// Universe members
Univ *_univ; // Pointer to the struct that contains the universe properties
uint16 *_logicalCNM; // Draw-type data for the CNM (indexes into )
uint16 *_CNM; // Stands for CHARACTER NUMBER MAP, but really it should be TILE NUMBER MAP, because it points to tiles, which are made of characters
byte *_oldCBM; // Stands for CHARACTER BIT MAP, but should probably be called like, TILE CHARACTER MAP, because it is the full gfx data for all tiles
Common::Array<Chr> _Draw; // In the source this contained the Linear Coded Chr Routines, but here it just contains the expanded pixel data
uint16 *_Solid;
uint16 *_Right;
uint16 *_Left;
Common::SeekableReadStream *_dataBuffer; // This contains the uncompressed CNM + CBM
uint16 *_modCNM;
uint16 *_modLogicalCNM;
uint16 _myCNM[(kViewPortCW + 1)][(kViewPortCH + 1)];
uint16 _myModCNM[(kViewPortCW + 1)][(kViewPortCH + 1)];
uint16 _myModLCNM[(kViewPortCW + 1)][(kViewPortCH + 1)];
// Screen members
byte *_screenBuff; // The final buffer that will transfer to the screen
Graphics::Surface *_mainSurface; // The ScummVM Surface
uint16 _columnX[kViewPortCW + 1];
uint16 _columnTop[kViewPortCW + 1];
uint16 _columnIndex[kViewPortCW + 1]; // Why the heck is this an entire array, when it's just an index that gets zeroed before it gets used anyway...
uint16 _tIndex[kMaxDrawItems];
uint16 _tPriority[kMaxDrawItems];
uint16 _viewPortX = 0;
uint16 _viewPortY = 0;
uint16 _myViewPortX = 0; // Probably mirror of viewportX
uint16 _myViewPortY = 0;
int _lastGauge = 0; // Mirror for player health, used to update health gauge display
uint16 _lastBMW = 0; // Mirrors used to determine where bitmap width needs to be re-calculated
uint16 _lastY = 0;
uint16 _lastPoint = 0;
uint16 _penX = 0; // Basically where in the screen we are currently drawing
uint16 _penY = 0;
uint16 _myUnivPointX = 0;
uint16 _myUnivPointY = 0;
int _num2DrawItems = 0;
GenericSprite _genSprites[6];
// Palette members
int _dontResetColors = 0; // Not sure yet
bool _usingNormal = 0; // Whether the palette is using normal
bool _dim = 0; // Whether the palette is dim
uint16 _palUniv[16];
uint16 _palDefault[16];
uint16 _palWhite[16];
uint16 _palBlack[16];
uint16 _palDim[16];
byte _palRGB[48]; // Palette that ScummVM actually uses, which is an RGB conversion of the original
/*
* --- Functions ---
*
*/
/*
* [Kernel.cpp] Functions from Kernel.gs and Driver.gs
*/
// Screen
void clearScreen(); // Draws a black rectangle on the screen buffer but only inside the frame
void whiteScreen(); // Draws a white rectanlge on the screen buffer (but does not do anything with resetColors)
void rect(int x, int y, int w, int h); // Draws a solid rectangle at x,y with size w,h. Also shadows for blit?
void backspace(); // Moves draw position back and draws empty rect in place of char
void printByte(int b);
void printChr(char c);
void loadWindow(); // Gets the window.bm file
void drawUniv(); // Draw the background, add the sprites, determine draw order, draw the sprites
void copyToScreen(); // If draw is 0, just check input, otherwise also copy the screen buffer to the scummvm surface and update screen
void mungeBM(); // Put together final bitmap?
void blit(); // Will probably want this to be it's own function
void blit40(); // Uses macro blit 40 times
void sBlit();
void scroll();
void makeMyCNM(); // ?
void drawBGRND(); // Draw floor parts of leftmask rightmask and maskers
void addRows(); // Add rows to drawitem array
void addSprite(uint16 vpX, uint16 vpY, SpriteName s, int img, uint16 x, uint16 y, uint16 p);
void addSprites(); // Add all active sprites that are in the viewport, into a list that will be sorted by priority
void sortDrawItems(); // Sort said items
void drawItems(); // Draw the items over the background
void drawIcon(int img);
void setPen(uint16 penX, uint16 penY); // Sets the 'pen' x and y positions, including making y negative if above a certain point
void center();
void carriageReturn();
// Music
void toggleSound(); // Actually pauses the sound, doesn't just turn it off/mute
void fixPause();
Song getPlaying();
void playMazeSong();
void playCombatSong();
void playTextSong();
void doGroan();
void stopMusic();
void musicPause(int sID);
void musicUnPause(int sID);
void loadSingles(Common::String songName); // Loads and then parse the maze song
void standardBeep();
// Palette
void loadPalette(); // Get the static palette data from the disk
void setColors(uint16 pal[]); // Applies the current palette to the ScummVM surface palette
void fixColors(); // Determine whether the screen should be dim or normal
void useNormal();
void useDim();
void useBlack();
void useWhite();
void pump(); // Alternates between white and black with delays in between (flashes screen)
void fadePal(uint16 pal[], int count, uint16 target[]); // Fades the palette except the frame
void fade(uint16 pal[], int dir, int delay); // Calls fadePal() by a given delay each iteration
void fadeOut(int j); // Calls Fade with a delay of j jiffies and direction 1
void fadeIn(int j); // || and direction 0
void normalFadeOut();
void slowFadeOut();
void normalFadeIn();
// Assets
Common::SeekableReadStream *loadIFF(Common::String fileName); // Loads a file and uncompresses if it is compressed
void initStoryStatic(); // Sets up all of the global static story elements
int loadUniv(char mazeNum); // Unpacks the .CNM and .UNV files into all the CNM stuff, returns the total length of everything
void loadMazeGraphics(int m); // Creates a universe with a maze
void makeBlisters(int povX, int povY); // Turns the unmodified CNM/CBM/LCNM etc into the modified ones to actually be used for drawing the game
void loadFont(); // Gets the font.spr file, and centers the sprite
void clearSprites(); // Clears all sprites before drawing the current frame
void loadSprites(); // Loads all the sprite files and centers their sprites (in spritelist, but called from kernel)
// Input
void userIO(); // Get input
void pollKeys(); // Buffer input
void noNetwork(); // Setup input mirrors
void waitKey(); // Waits until a key is pressed (until getInput() returns true)
void waitClick(); // Waits until one of the two buttons is pressed
void blit8(); // This is actually just input, but it is called blit because it does a 'paddle blit' 8 times
// These will replace the myriad of hardware input handling from the source
bool getInput(); // True if there was input, false if not
void addKeyBuffer();
void clearKeyBuff();
/*
* [DrawChr.cpp] Functions from DrawChr.cpp
*/
// Main
int mungeCBM(uint16 num2Chrs);
void storeAddr(uint16 *drawType, uint16 chr2, uint16 drawIndex);
void mungeSolid(int oldChr, uint16 &drawIndex);
void mungeLRHC(int oldChr, uint16 &drawIndex);
void mungeLLHC(int oldChr, uint16 &drawIndex);
void mungeULHC(int oldChr, uint16 &drawIndex);
void mungeURHC(int oldChr, uint16 &drawIndex);
void drawSolid(int chr, int x, int y);
void drawULHC(int chr, int x, int y);
void drawURHC(int chr, int x, int y);
void drawLLHC(int chr, int x, int y);
void drawLRHC(int chr, int x, int y);
/*
* [Logic.cpp] Functions from Logic.GS
*/
// Debug
void doSingleStep(); // Let the user advance the engine one frame at a time
// Main
void trapKeys(); // Poorly named, this checks if the player wants to restart/pause music/use debug step
int keyOrButton(); // Returns value based on whether it was a keyboard key or a button press
void logicInit();
void logic(); // Keeps time, handles win and lose conditions, then general logic
void restartLogic(); // This is the actual logic init
int logicFreeze(); // Overcomplicated way to check if game over or level over
void updateHitGauge();
void drawGauge(int h);
void makeCertificate();
void calcCheckSum(int l, uint8 checksum[]); // Checksum is one word, but the source called it CheckSum
bool getCertificate();
void printCertificate();
// Misc
bool printAnd(Str s);
bool fromOldGame();
void setGameFlags(uint16 f);
uint16 getGameFlags();
void setSavedKing();
bool isSavedKing();
void setSavedAna();
bool isSavedAna();
int getLevel(); // Literally just return _level...
void gameOverDisplay();
void gameOver();
void levelOver();
/*
* [Misc.cpp] Functions from Misc
*/
// Misc
void miscInit();
void setRandomSeed();
void getRandom();
// Input related
bool buttonPressed();
bool firePressed();
// Text printing
void myFadeOut();
void myFadeIn();
bool textPrint(Str s, int n);
bool textBeginning(Str s, int n);
bool textSub(Str s, FadeType f, int n);
void textEnd(Str s, int n);
void textMiddle(Str s, int n);
void textCR();
void textPageBreak(Common::String s, int &index);
void textAutoPageBreak();
void textDoSpace(Common::String s, int index);
void textBounceDelay();
bool yesNo();
void noOn();
void yesOn();
void myDelay(int j);
/*
* [Level.cpp] Functions from level.GS
* < All functions implemented (in some capacity)! >
*/
// Init
void levelInitAtStartOfGameOnly();
void levelInit();
//void levelGetCount <-- lda count
// Main
void levelStory(int l);
void levelLoadFile(int l);
void levelNew(int l);
void levelDrawAll();
void levelShowRoom(int r, int bX, int bY);
bool levelIsShowRoom(int r);
bool levelIsLoaded(int l);
void univAtNew(int l);
//void getLastType <-- lda lastType
//void setLastType <-- sta lastType
//void getShowRoom <-- lda currentRoom
/*
* [Cycle.cpp] Functions from Cyc
*/
// Misc
void cycleFreeAll(); // Delete all cycles
/*
* [Story.cpp] Functions related to Story.GS
*/
// Init
void initStoryDynamic();
/*
* [Sprites.cpp] Functions from Sprites.GS and spriteList.GS
*/
// Init
void initDataSprite(Common::SeekableReadStream *f, DataSprite *d, int index, uint16 cenX, uint16 cenY); // Initializes the data sprite
// Main
void superSprite(DataSprite *dSprite, uint16 x, uint16 y, int img, uint16 bmw, byte *dst, uint16 superTop, uint16 superBottom);
bool clipSprite(uint16 &height, uint16 &pointIndex, uint16 &skipY, DataSprite *dSprite, uint16 &pointX, uint16 &pointY, int img, uint16 bmw, uint16 superTop, uint16 superBottom);
void spriteAligned(DataSprite *dSprite, Image &img, uint16 &skipY, uint16 &pointIndex, uint16 &height, uint16 bmw, byte *dst);
/*
* [Compression.cpp] Functions from Compression.GS
*/
// Main routines
Common::SeekableReadStream *unCompress(Common::File *source, int lSource);
// Subroutines called by unCompress
void setUpDictionary(uint16 *pCodes, uint16 *pTk, uint16 &findEmpty);
int inputCode(uint16 &outCode, int &lSource, Common::File *source, uint16 &evenOdd);
int member(uint16 &codeW, uint16 &k, uint16 *pCodes, uint16 *pTk, uint16 &findEmpty, uint16 &index);
/*
* [door.cpp] Functions from Door.GS
*/
void roomTransfer(int r, int x, int y); // Transfers the player from the current room to a new room at x,y
void doorOpenSecret();
void doorCloseSecret();
//void doorToNextLevel();
void doorInit();
void doorClrLock();
void doorNew(SDoor door);
void doorDrawAll();
void doorOnDoorMat();
//void doorEnter(); // <-- this is actually a method of Player Monster, should probably move it there later
int findDoorTop(int x, int y);
int findDoor(int x, int y);
bool doLockStuff(int d, MonsterID m, int top);
bool inDoorTop(int x, int y, MonsterID m);
bool inDoor(int x, int y, MonsterID m);
int doorDoStep(MonsterID m, int d, int index);
int doorSetOn(int d);
int doorComeOut(MonsterID m);
void doorSetLadders(MonsterID m);
/*
* [Music.cpp] Functions from music.GS and sound.GS
*/
// Misc
/*
* --- ScummVM general engine Functions ---
*
*/
Common::ErrorCode initDisks(); // Opens and parses IMMORTAL.dsk and IMMORTAL_GFX.dsk
uint32 getFeatures() const; // Returns the game description flags
Common::String getGameId() const; // Returns the game Id
/* Gets a random number
*/
uint32 getRandomNumber(uint maxNum) {
return _randomSource.getRandomNumber(maxNum);
}
bool hasFeature(EngineFeature f) const override {
return
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime) ||
(f == kSupportsReturnToLauncher);
};
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override {
return true;
}
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override {
return true;
}
/* Uses a serializer to allow implementing savegame
* loading and saving using a single method
*/
Common::Error syncGame(Common::Serializer &s);
/* Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) {
Common::Serializer s(nullptr, stream);
return syncGame(s);
}
Common::Error loadGameStream(Common::SeekableReadStream *stream) {
Common::Serializer s(stream, nullptr);
return syncGame(s);
} */
};
extern ImmortalEngine *g_immortal;
#define SHOULD_QUIT ::Immortal::g_immortal->shouldQuit()
} // namespace Immortal
#endif