/* 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/mads.h" #include "mads/game.h" #include "mads/game_data.h" #include "mads/nebular/game_nebular.h" #include "mads/graphics.h" #include "mads/msurface.h" #include "mads/resources.h" namespace MADS { Game *Game::init(MADSEngine *vm) { if (vm->getGameID() == GType_RexNebular) return new Nebular::GameNebular(vm); return nullptr; } Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm), _scene(vm) { _sectionNumber = _priorSectionNumber = 0; _difficultyLevel = DIFFICULTY_HARD; _saveSlot = -1; _statusFlag = 0; _sectionHandler = nullptr; _sectionNumber = 1; _priorSectionNumber = 0; _currentSectionNumber = -1; _v1 = _v2 = 0; _v3 = _v4 = 0; _v5 = _v6 = 0; _aaName = "*I0.AA"; _playerSpritesFlag = false; } Game::~Game() { delete _surface; delete _sectionHandler; } void Game::run() { _statusFlag = true; int protectionResult = checkCopyProtection(); switch (protectionResult) { case 1: // Copy protection failed _scene._nextSceneId = 804; initialiseGlobals(); _globalFlags[5] = 0xFFFF; _saveSlot = -1; break; case 2: _statusFlag = 0; break; default: break; } if (_saveSlot == -1 && protectionResult != -1 && protectionResult != -2) { initSection(_sectionNumber); _statusFlag = true; _vm->_dialogs->_pendingDialog = DIALOG_DIFFICULTY; _vm->_dialogs->showDialog(); _vm->_dialogs->_pendingDialog = DIALOG_NONE; _priorSectionNumber = 0; _priorSectionNumber = -1; _scene._priorSceneId = 0; _scene._currentSceneId = -1; } if (protectionResult != 1 && protectionResult != 2) { initialiseGlobals(); if (_saveSlot != -1) { warning("TODO: loadGame(\"REX.SAV\", 210)"); _statusFlag = false; } } if (_statusFlag) gameLoop(); } void Game::gameLoop() { while (!_vm->shouldQuit() && _statusFlag) { setSectionHandler(); _sectionHandler->preLoadSection(); initSection(_sectionNumber); _sectionHandler->postLoadSection(); _scene._spriteSlots.clear(true); if (_sectionNumber == _currentSectionNumber) { sectionLoop(); } // TODO: Extra reset methods _vm->_events->resetCursor(); _vm->_events->freeCursors(); _vm->_sound->closeDriver(); } _vm->_palette->close(); } void Game::sectionLoop() { while (!_vm->shouldQuit() && _statusFlag && _sectionNumber == _currentSectionNumber) { _v1 = 3; _player._spritesChanged = true; _v5 = 0; _v6 = 0; _vm->_events->resetCursor(); _quotes = nullptr; _scene.clearVocab(); _scene.loadSceneLogic(); _v4 = 0; _player._stepEnabled = true; _player._visible = true; _vm->_dialogs->_defaultPosition = Common::Point(-1, -1); _visitedScenes.add(_scene._nextSceneId); _scene._screenObjects._v8333C = -1; _scene._screenObjects._v832EC = 0; _scene._screenObjects._yp = 0; _v3 = -1; _scene._sceneLogic->setup(); if (_player._spritesChanged || _v3) { if (_player._spritesLoaded) _scene._spriteSlots.releasePlayerSprites(); _vm->_palette->resetGamePalette(18, 10); _scene._spriteSlots.clear(true); } else { _vm->_palette->initGamePalette(); } _vm->_palette->_paletteUsage.load(3, 0xF0, 0xF1, 0xF2); _scene.loadScene(_scene._nextSceneId, _aaName, 0); _vm->_sound->pauseNewCommands(); if (!_player._spritesLoaded) { _player.loadSprites(""); _playerSpritesFlag = false; } // TODO: main section loop logic goes here // Clear the scene _scene.free(); _sectionNumber = _scene._nextSceneId / 100; // TODO: sub_1DD46(3) // Check whether to show a dialog if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globalFlags[5]) { _scene._spriteSlots.releasePlayerSprites(); _vm->_dialogs->showDialog(); _vm->_dialogs->_pendingDialog = DIALOG_NONE; } } } void Game::initSection(int sectionNumber) { _priorSectionNumber = _currentSectionNumber; _currentSectionNumber = sectionNumber; _vm->_palette->resetGamePalette(18, 10); _vm->_palette->setLowRange(); _vm->_events->loadCursors("*CURSOR.SS"); assert(_vm->_events->_cursorSprites); _vm->_events->setCursor2((_vm->_events->_cursorSprites->getCount() <= 1) ? CURSOR_ARROW : CURSOR_WAIT); } void Game::loadResourceSequence(const Common::String prefix, int v) { warning("TODO: loadResourceSequence"); } } // End of namespace MADS