MADS: Added skeleton framework for game scene classes

This commit is contained in:
Paul Gilbert 2014-02-24 00:20:53 -05:00
parent 8ee283d921
commit 37b788b7dd
15 changed files with 576 additions and 18 deletions

View File

@ -329,4 +329,16 @@ void MessageDialog::show() {
}
}
/*------------------------------------------------------------------------*/
Dialogs *Dialogs::init(MADSEngine *vm) {
if (vm->getGameID() == GType_RexNebular)
return new Dialogs(vm);
error("Unknown game");
}
Dialogs::Dialogs(MADSEngine *vm): _vm(vm) {
}
} // End of namespace MADS

View File

@ -168,6 +168,23 @@ public:
void show();
};
enum DialogId {
DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3,
DIALOG_OPTIONS = 4, DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6
};
class Dialogs {
private:
MADSEngine *_vm;
Dialogs(MADSEngine *vm);
public:
static Dialogs *init(MADSEngine *vm);
public:
Common::Point _defaultPosition;
DialogId _pendingDialog;
};
} // End of namespace MADS
#endif /* MADS_DIALOGS_H */

View File

@ -37,13 +37,15 @@ Game *Game::init(MADSEngine *vm) {
return nullptr;
}
Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr) {
Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _scene(vm) {
_sectionNumber = _priorSectionNumber = 0;
_difficultyLevel = DIFFICULTY_HARD;
_saveSlot = -1;
_statusFlag = 0;
_sectionHandler = nullptr;
_v1 = _v2 = 0;
_v3 = _v4 = 0;
_v5 = _v6 = 0;
}
Game::~Game() {
@ -71,15 +73,15 @@ void Game::run() {
if (_saveSlot == -1 && protectionResult != -1 && protectionResult != -2) {
initSection(_scene._sectionNum);
_statusFlag = _scene._sectionNum != 1;
_pendingDialog = DIALOG_DIFFICULTY;
_vm->_dialogs->_pendingDialog = DIALOG_DIFFICULTY;
showDialog();
_pendingDialog = DIALOG_NONE;
_vm->_dialogs->_pendingDialog = DIALOG_NONE;
_vm->_events->freeCursors();
_scene._priorSectionNum = 0;
_scene._priorSceneId = 0;
_scene._sectionNum2 = -1;
_scene._sectionNumPrior = -1;
_scene._currentSceneId = -1;
}
@ -105,7 +107,7 @@ void Game::gameLoop() {
_scene.clearSprites(true);
if (_scene._sectionNum == _scene._sectionNum2) {
if (_scene._sectionNum == _scene._sectionNumPrior) {
sectionLoop();
}
@ -113,14 +115,47 @@ void Game::gameLoop() {
_vm->_events->resetCursor();
_vm->_events->freeCursors();
_vm->_sound->closeDriver();
}
_vm->_palette->close();
}
void Game::sectionLoop() {
while (!_vm->shouldQuit() && _statusFlag && _scene._sectionNum == _scene._sectionNumPrior) {
if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globalFlags[5]) {
_v1 = 3;
_player._spritesChanged = true;
_v5 = 0;
_v6 = 0;
_vm->_events->resetCursor();
_quotes = nullptr;
_scene.clearVocab();
_scene.loadScene();
_v4 = 0;
_player._stepEnabled = true;
_player._visible = true;
_vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
_scene.addVisitedScene(_scene._nextSceneId);
// TODO: main section loop logic goes here
// Clear the scene
_scene.free();
_scene._sectionNum = _scene._nextSceneId / 100;
// TODO: sub_1DD46(3)
// Check whether to show a dialog
if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globalFlags[5]) {
_scene.releasePlayerSprites();
showDialog();
_vm->_dialogs->_pendingDialog = DIALOG_NONE;
}
}
}
}
void Game::initSection(int sectionNumber) {
@ -202,6 +237,10 @@ void InventoryObject::load(Common::SeekableReadStream &f) {
Player::Player() {
_direction = 8;
_newDirection = 8;
_spritesLoaded = false;
_spriteListStart = _numSprites = 0;
_stepEnabled = false;
_visible = false;
}
} // End of namespace MADS

View File

@ -38,11 +38,6 @@ enum Difficulty {
DIFFICULTY_HARD = 1, DIFFICULTY_MEDIUM = 2, DIFFICULTY_EASY = 3
};
enum DialogId {
DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3,
DIALOG_OPTIONS = 4, DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6
};
class InventoryObject {
public:
int _descId;
@ -67,6 +62,12 @@ class Player {
public:
int _direction;
int _newDirection;
bool _spritesLoaded;
int _spriteListStart;
int _numSprites;
bool _stepEnabled;
bool _spritesChanged;
bool _visible;
public:
Player();
};
@ -76,6 +77,7 @@ protected:
MADSEngine *_vm;
public:
SectionHandler(MADSEngine *vm): _vm(vm) {}
virtual ~SectionHandler() {}
virtual void preLoadSection() = 0;
virtual void sectionPtr2() = 0;
@ -104,10 +106,14 @@ protected:
Scene _scene;
int _saveSlot;
int _statusFlag;
DialogId _pendingDialog;
SectionHandler *_sectionHandler;
int _v1;
int _v2;
int _v3;
int _v4;
int _v5;
int _v6;
byte *_quotes;
/**
* Constructor
@ -172,6 +178,8 @@ public:
* Run the game
*/
void run();
Player &player() { return _player; }
};
} // End of namespace MADS

View File

@ -43,6 +43,7 @@ MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
_textWindowStill = false;
_debugger = nullptr;
_dialogs = nullptr;
_events = nullptr;
_font = nullptr;
_game = nullptr;
@ -55,6 +56,7 @@ MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
MADSEngine::~MADSEngine() {
delete _debugger;
delete _dialogs;
delete _events;
delete _font;
delete _game;
@ -77,6 +79,7 @@ void MADSEngine::initialise() {
ResourcesManager::init(this);
_debugger = new Debugger(this);
_dialogs = Dialogs::init(this);
_events = new EventsManager(this);
_palette = new Palette(this);
_font = new Font(this);

View File

@ -31,6 +31,7 @@
#include "engines/engine.h"
#include "graphics/surface.h"
#include "mads/debugger.h"
#include "mads/dialogs.h"
#include "mads/events.h"
#include "mads/font.h"
#include "mads/game.h"
@ -88,6 +89,7 @@ protected:
virtual bool hasFeature(EngineFeature f) const;
public:
Debugger *_debugger;
Dialogs *_dialogs;
EventsManager *_events;
Font *_font;
Game *_game;

View File

@ -4,6 +4,8 @@ MODULE_OBJS := \
nebular/dialogs_nebular.o \
nebular/game_nebular.o \
nebular/sound_nebular.o \
nebular/nebular_scenes.o \
nebular/nebular_scenes8.o \
assets.o \
compression.o \
debugger.o \

View File

@ -0,0 +1,49 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "mads/mads.h"
#include "mads/scene.h"
#include "mads/nebular/nebular_scenes.h"
#include "mads/nebular/nebular_scenes8.h"
namespace MADS {
namespace Nebular {
SceneLogic *SceneFactory::createScene(Scene *scene) {
scene->addActiveVocab(NOUN_DROP);
scene->addActiveVocab(NOUN_DOLLOP);
scene->addActiveVocab(NOUN_DASH);
scene->addActiveVocab(NOUN_SPLASH);
scene->addActiveVocab(NOUN_ALCOHOL);
// TODO: Implement all the game scenes
assert(scene->_nextSceneId == 804);
return new Scene804(scene);
}
} // End of namespace Nebular
} // End of namespace MADS

View File

@ -0,0 +1,91 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef MADS_NEBULAR_SCENES_H
#define MADS_NEBULAR_SCENES_H
#include "common/scummsys.h"
#include "mads/game.h"
#include "mads/scene.h"
namespace MADS {
namespace Nebular {
enum Noun {
NOUN_BLOWGUN = 0x29,
NOUN_BURGER = 0x35,
NOUN_CHAIR = 0x47,
NOUN_DEAD_FISH = 0x65,
NOUN_DOOR = 0x6E,
NOUN_EAT = 0x75,
NOUN_EXAMINE = 0x7D,
NOUN_FRONT_WINDOW = 0x8E,
NOUN_FUZZY_DICE = 0x91,
NOUN_HOSE_DOWN = 0x0A6,
NOUN_HOTPANTS = 0x0A7,
NOUN_HULL = 0x0A8,
NOUN_HURL = 0x0A9,
NOUN_IGNITE = 0x0B4,
NOUN_INFLATE = 0x0B5,
NOUN_INSERT = 0x0B6,
NOUN_INSPECT = 0x0B7,
NOUN_JUNGLE = 0x0B8,
NOUN_LIFE_SUPPORT_SECTION = 0x0CC,
NOUN_LOG = 0x0D0,
NOUN_LOOK_AT = 0x0D1,
NOUN_LOOK_IN = 0x0D2,
NOUN_LOOK_THROUGH = 0x0D3,
NOUN_MONKEY = 0x0E3,
NOUN_OUTER_HULL = 0x0F8,
NOUN_OUTSIDE = 0x0F9,
NOUN_PEER_THROUGH = 0x103,
NOUN_PLANT_STALK = 0x10F,
NOUN_READ = 0x11F,
NOUN_REFRIDGERATOR = 0x122,
NOUN_ROBO_KITCHEN = 0x127,
NOUN_SHIELD_ACCESS_PANEL = 0x135,
NOUN_SHIELD_MODULATOR = 0x137,
NOUN_SHOOT = 0x13A,
NOUN_SIT_IN = 0x13F,
NOUN_SMELL = 0x147,
NOUN_STUFFED_FISH = 0x157,
NOUN_VIEW_SCREEN = 0x180,
NOUN_CAPTIVE_CREATURE = 0x1C3,
NOUN_NATIVE_WOMAN = 0x1DC,
NOUN_ALCOHOL = 0x310,
NOUN_DOLLOP = 0x3AC,
NOUN_DROP = 0x3AD,
NOUN_DASH = 0x3AE,
NOUN_SPLASH = 0x3AF
};
class SceneFactory {
public:
static SceneLogic *createScene(Scene *scene);
};
} // End of namespace Nebular
} // End of namespace MADS
#endif /* MADS_NEBULAR_SCENES_H */

View File

@ -0,0 +1,50 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "mads/nebular/nebular_scenes8.h"
namespace MADS {
namespace Nebular {
void Scene804::setup() {
}
void Scene804::enter() {
}
void Scene804::step() {
}
void Scene804::preActions() {
}
void Scene804::actions() {
}
void Scene804::postActions() {
}
} // End of namespace Nebular
} // End of namespace MADS

View File

@ -0,0 +1,55 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef MADS_NEBULAR_SCENES8_H
#define MADS_NEBULAR_SCENES8_H
#include "common/scummsys.h"
#include "mads/game.h"
#include "mads/scene.h"
namespace MADS {
namespace Nebular {
class Scene804: public SceneLogic {
public:
Scene804(Scene *scene): SceneLogic(scene) {}
virtual void setup();
virtual void enter();
virtual void step();
virtual void preActions();
virtual void actions();
virtual void postActions();
};
} // End of namespace Nebular
} // End of namespace MADS
#endif /* MADS_NEBULAR_SCENES8_H */

View File

@ -293,7 +293,7 @@ void Palette::initRange(byte *palette) {
int varE = vbx;
int var10 = vdx;
do {
int vdx = 0;
vdx = 0;
do {
int vcx = 0;
int var4 = vdx;

View File

@ -24,6 +24,7 @@
#define MADS_PALETTE_H
#include "common/scummsys.h"
#include "common/stream.h"
namespace MADS {

View File

@ -22,16 +22,26 @@
#include "common/scummsys.h"
#include "mads/scene.h"
#include "mads/mads.h"
#include "mads/nebular/nebular_scenes.h"
namespace MADS {
Scene::Scene() {
Scene::Scene(MADSEngine *vm): _vm(vm) {
_sectionNum = 1;
_sectionNum2 = -1;
_sectionNumPrior = -1;
_priorSectionNum = 0;
_priorSceneId = 0;
_nextSceneId = 0;
_currentSceneId = 0;
_vocabCount = 0;
_vocabBuffer = nullptr;
_sceneLogic = nullptr;
}
Scene::~Scene() {
delete[] _vocabBuffer;
delete _sceneLogic;
}
void Scene::clearSprites(bool flag) {
@ -45,6 +55,86 @@ void Scene::clearSprites(bool flag) {
_spriteSlots.push_back(SpriteSlot(ST_FULL_SCREEN_REFRESH, -1));
}
/**
* Releases any sprites used by the player
*/
void Scene::releasePlayerSprites() {
Player &player = _vm->_game->player();
if (player._spritesLoaded && player._numSprites > 0) {
int spriteEnd = player._spriteListStart + player._numSprites - 1;
do {
deleteSpriteEntry(spriteEnd);
} while (--spriteEnd >= player._spriteListStart);
}
}
void Scene::deleteSpriteEntry(int listIndex) {
delete _spriteList[listIndex];
_spriteList.remove_at(listIndex);
}
void Scene::clearDynamicHotspots() {
_dynamicHotspots.clear();
_dynamicHotspotsChanged = false;
}
void Scene::clearVocab() {
freeVocab();
_vocabCount = 0;
}
void Scene::freeVocab() {
delete[] _vocabBuffer;
_vocabBuffer = nullptr;
}
void Scene::addActiveVocab(int vocabId) {
if (activeVocabIndexOf(vocabId) == -1) {
assert(_activeVocabs.size() < 200);
_activeVocabs.push_back(vocabId);
}
}
int Scene::activeVocabIndexOf(int vocabId) {
for (uint i = 0; i < _activeVocabs.size(); ++i) {
if (_activeVocabs[i] == vocabId)
return i;
}
return -1;
}
void Scene::addVisitedScene(int sceneId) {
if (!visitedScenesExists(sceneId))
_visitedScenes.push_back(sceneId);
}
bool Scene::visitedScenesExists(int sceneId) {
for (int i = 0; i < _visitedScenes.size(); ++i) {
if (_visitedScenes[i] == sceneId)
return true;
}
return false;
}
void Scene::loadScene() {
delete _sceneLogic;
switch (_vm->getGameID()) {
case GType_RexNebular:
_sceneLogic = Nebular::SceneFactory::createScene(this);
break;
default:
error("Unknown game");
}
}
void Scene::free() {
warning("TODO: Scene::free");
}
/*------------------------------------------------------------------------*/
SpriteSlot::SpriteSlot() {
@ -74,4 +164,15 @@ TextDisplay::TextDisplay() {
_col1 = _col2 = 0;
}
/*------------------------------------------------------------------------*/
DynamicHotspot::DynamicHotspot() {
_seqIndex = 0;
_facing = 0;
_descId = 0;
_field14 = 0;
_articleNumber = 0;
_cursor = 0;
}
} // End of namespace MADS

View File

@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
#include "mads/assets.h"
namespace MADS {
@ -62,32 +63,159 @@ public:
TextDisplay();
};
class DynamicHotspot {
public:
int _seqIndex;
Common::Rect _bounds;
Common::Point _feetPos;
int _facing;
int _descId;
int _field14;
int _articleNumber;
int _cursor;
DynamicHotspot();
};
#define SPRITE_COUNT 50
#define TEXT_DISPLAY_COUNT 40
#define DYNAMIC_HOTSPOT_COUNT 8
class MADSEngine;
class Scene;
class SceneLogic {
protected:
Scene *_scene;
public:
/**
* Constructor
*/
SceneLogic(Scene *scene): _scene(scene) {}
/**
* Called to initially setup a scene
*/
virtual void setup() = 0;
/**
* Called as the scene is entered (made active)
*/
virtual void enter() = 0;
/**
* Called one per frame
*/
virtual void step() = 0;
/**
* Called before an action is started
*/
virtual void preActions() = 0;
/**
* Handles scene actions
*/
virtual void actions() = 0;
/**
* Post-action handling
*/
virtual void postActions() = 0;
};
class Scene {
private:
/**
* Free the voculary list buffer
*/
void freeVocab();
/**
* Return the index of a given Vocab in the active vocab list
*/
int activeVocabIndexOf(int vocabId);
/**
* Returns true if a given Scene Id exists in the listed of previously visited scenes.
*/
bool visitedScenesExists(int sceneId);
protected:
MADSEngine *_vm;
public:
SceneLogic *_sceneLogic;
int _priorSectionNum;
int _sectionNum;
int _sectionNum2;
int _sectionNumPrior;
int _priorSceneId;
int _nextSceneId;
int _currentSceneId;
TextDisplay _textDisplay[TEXT_DISPLAY_COUNT];
Common::Array<SpriteSlot> _spriteSlots;
Common::Array<int> _spriteList;
Common::Array<SpriteAsset *> _spriteList;
int _spriteListIndex;
Common::Array<DynamicHotspot> _dynamicHotspots;
bool _dynamicHotspotsChanged;
byte *_vocabBuffer;
int _vocabCount;
Common::Array<int> _activeVocabs;
Common::Array<int> _visitedScenes;
/**
* Constructor
*/
Scene();
Scene(MADSEngine *vm);
/**
* Destructor
*/
~Scene();
/**
* Initialise the sprite data
* @param flag Also reset sprite list
*/
void clearSprites(bool flag);
/**
* Delete any sprites used by the player
*/
void releasePlayerSprites();
/**
* Delete a sprite entry
*/
void deleteSpriteEntry(int listIndex);
/**
* Clear the dynamic hotspot list
*/
void clearDynamicHotspots();
/**
* Clear the vocabulary list
*/
void clearVocab();
/**
* Add a given vocab entry to the active list
*/
void addActiveVocab(int vocabId);
/**
* Add a scene to the visited scene list if it doesn't already exist
*/
void addVisitedScene(int sceneId);
/**
* Loads the scene logic for a given scene
*/
void loadScene();
/**
* Clear the data for the scene
*/
void free();
};
} // End of namespace MADS