Files
2026-02-02 04:50:13 +01:00

228 lines
6.3 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 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<typename T> 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<typename T> 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<Global *> &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<Global *> _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