/* 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 . * */ #ifndef DGDS_GLOBALS_H #define DGDS_GLOBALS_H #include "common/types.h" #include "common/array.h" #include "dgds/dgds.h" namespace Dgds { class Clock; /** * The original game uses a struct here with 3 entries: * 1. global variable num (uint16) * 2. pointer to the variable (uint16) * 3. pointer - get+set function ptr **or** 1 == R/W **or** 0 == RO (32 bits) * We make that a bit nicer using c++. * * The original also creates a lookup table to do O(1) lookups of each global, * but there are only ~20 of them so we just iterate through each time. */ class Global { public: Global(uint16 num) : _num(num) {} virtual ~Global() {} virtual int16 get() = 0; virtual int16 set(int16 val) = 0; virtual uint16 getNum() const { return _num; } virtual void setRaw(int16 val) = 0; /// only for use in loading state. private: uint16 _num; }; /* This is a bit of a misnomer - the global is readonly during play, but it can be set by load/save or restart operations */ template class ReadOnlyGlobal : public Global { public: ReadOnlyGlobal(uint16 num, T *val) : Global(num), _val(val) {} int16 get() override { return *_val; } int16 set(int16 val) override { return *_val; } void setRaw(int16 val) override { *_val = val; } private: T *_val; }; template class ReadWriteGlobal : public Global { public: ReadWriteGlobal(uint16 num, T *val) : Global(num), _val(val) {} int16 get() override { return *_val; } int16 set(int16 val) override { *_val = val; return *_val; } void setRaw(int16 val) override { *_val = val; } private: T *_val; }; class Globals { public: Globals(Clock &clock); virtual ~Globals(); int16 getGlobal(uint16 num); int16 setGlobal(uint16 num, int16 val); virtual Common::Error syncState(Common::Serializer &s); // note: children should call parent first Common::Array &getAllGlobals() { return _globals; } int16 getGameMinsToAddOnUse() const { return _gameMinsToAddOnUse; } int16 getGameMinsToAddOnPickUp() const { return _gameMinsToAddOnPickUp; } int16 getGameMinsToAddOnLook() const { return _gameMinsToAddOnLook; } int16 getGameMinsToAddOnDrop() const { return _gameMinsToAddOnDrop; } int16 getGameMinsToAddOnObjInteraction() const { return _gameMinsToAddOnObjInteraction; } int16 getGameIsInteractiveGlobal() { return _gameIsInteractiveGlobal; } void setLastSceneNum(int16 num) { _lastOpcode1SceneChangeNum = num; } int16 getLastSceneNum() const { return _lastOpcode1SceneChangeNum; } protected: // these ones seem to be common between games int16 _lastOpcode1SceneChangeNum; int16 _sceneOp12SceneNum; int16 _currentSelectedItem; int16 _gameMinsToAddOnUse; int16 _gameMinsToAddOnPickUp; int16 _gameMinsToAddOnLook; int16 _gameMinsToAddOnDrop; int16 _gameMinsToAddOnObjInteraction; int16 _gameIsInteractiveGlobal; // used to decide if the game can start a "meanwhile" sequence int16 _sceneOpcode15FromScene; int16 _sceneOpcode15ToScene; Common::Array _globals; }; // TODO: Work out what this table is even for.. class DragonDataTable { public: DragonDataTable(); uint16 getValueFromTable(); int16 _row; int16 _col; int16 _divBy4; int16 _output; private: int getOffsetForVal(uint16 val) const; }; class DragonGlobals : public Globals { public: DragonGlobals(Clock &clock); int16 getArcadeState() const { return _arcadeState; } void setArcadeState(int16 state) { _arcadeState = state; } private: // Dragon-specific globals int16 _sceneOpcode100Var; int16 _arcadeState; int16 _opcode106EndMinutes; DragonDataTable _table; Common::Error syncState(Common::Serializer &s) override; }; class HocGlobals : public Globals { public: HocGlobals(Clock &clock); int16 getSheckels() const { return _sheckels; } int16 getShellBet() const { return _shellBet; } int16 getShellPea() const { return _shellPea; } void setShellPea(int16 pea) { _shellPea = pea; } int16 getNativeGameState() const { return _nativeGameState; } void setNativeGameState(int16 state) { _nativeGameState = state; } int16 getTrainState() const { return _trainState; } void setTrainState(int16 state) { _trainState = state; } int16 getIntroState() const { return _introState; } void setIntroState(int16 state) { _introState = state; } private: // HoC-specific globals int16 _introState; int16 _startScene; int16 _trainState; int16 _shellPea; int16 _shellBet; int16 _sheckels; int16 _palFade; int16 _unk46; int16 _unk47; int16 _tankState; int16 _nativeGameState; // state for the shell game, tank game, etc. int16 _tankFinished; int16 _currentCharacter; int16 _currentCharacter2; int16 _partnerDlgDlgNum; // Dialog shown when right-clicking int16 _partnerDlgFileNum; // on character swap button int16 _unk55; Common::Error syncState(Common::Serializer &s) override; }; class WillyGlobals : public Globals { public: WillyGlobals(Clock &clock); void setPalFade(int16 val) { _palFade = val; } int16 getPalFade() const { return _palFade; } void setDroppedItemNum(int16 val) { _droppedItemNum = val; } bool isHideMouseCursor() const { return _hideMouseCursor != 0; } bool isDrawTimeSkipButtons() const { return _invDrawTimeSkipButtons != 0; } private: // Willy-specific globals int16 _trouble; int16 _money; int16 _invDrawTimeSkipButtons; int16 _hideMouseCursor; int16 _unk74; int16 _unk75; int16 _palFade; int16 _droppedItemNum; int16 _characterStance; int16 _characterPos; int16 _unk81; int16 _unk82; Common::Error syncState(Common::Serializer &s) override; }; } // end namespace Dgds #endif // DGDS_GLOBALS_H