scummvm/engines/dm/dm.cpp

291 lines
8.3 KiB
C++
Raw Normal View History

2016-08-26 22:36:31 +02:00
/* 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.
*
*/
/*
* Based on the Reverse Engineering work of Christophe Fontanel,
* maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
*/
#include "common/scummsys.h"
#include "common/system.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
#include "engines/util.h"
#include "engines/engine.h"
#include "graphics/palette.h"
#include "common/file.h"
#include "common/events.h"
#include "dm/dm.h"
2016-06-15 22:42:08 +02:00
#include "gfx.h"
#include "dungeonman.h"
#include "eventman.h"
#include "menus.h"
#include "champion.h"
#include "loadsave.h"
2016-06-19 00:54:28 +02:00
#include "objectman.h"
#include "inventory.h"
#include "text.h"
2016-08-26 22:37:14 +02:00
#include "movesens.h"
#include "group.h"
#include "timeline.h"
namespace DM {
void turnDirRight(direction &dir) { dir = (direction)((dir + 1) & 3); }
void turnDirLeft(direction &dir) { dir = (direction)((dir - 1) & 3); }
direction returnOppositeDir(direction dir) { return (direction)((dir + 2) & 3); }
uint16 returnPrevVal(uint16 val) {
return (direction)((val + 3) & 3);
}
uint16 returnNextVal(uint16 val) {
return (val + 1) & 0x3;
}
bool isOrientedWestEast(direction dir) { return dir & 1; }
uint16 getFlag(uint16 val, uint16 mask) {
return val & mask;
}
uint16 setFlag(uint16 &val, uint16 mask) {
return val |= mask;
}
uint16 clearFlag(uint16 &val, uint16 mask) {
return val &= ~mask;
}
uint16 toggleFlag(uint16& val, uint16 mask) {
return val ^= mask;
}
DMEngine::DMEngine(OSystem *syst) : Engine(syst), _console(nullptr) {
// Do not load data files
// Do not initialize graphics here
// Do not initialize audio devices here
// Do these from run
//Specify all default directories
//const Common::FSNode gameDataDir(ConfMan.get("example"));
//SearchMan.addSubDirectoryMatching(gameDataDir, "example2");
DebugMan.addDebugChannel(kDMDebugExample, "example", "example desc");
2016-05-04 11:23:52 +02:00
// register random source
_rnd = new Common::RandomSource("quux");
2016-06-17 23:08:04 +02:00
_dungeonMan = nullptr;
_displayMan = nullptr;
2016-06-17 23:08:04 +02:00
_eventMan = nullptr;
_menuMan = nullptr;
_championMan = nullptr;
_loadsaveMan = nullptr;
2016-06-19 00:54:28 +02:00
_objectMan = nullptr;
_inventoryMan = nullptr;
_textMan = nullptr;
2016-08-26 22:37:14 +02:00
_movsens = nullptr;
_groupMan = nullptr;
_timeline = nullptr;
2016-08-26 22:43:17 +02:00
_g321_stopWaitingForPlayerInput = false;
_g301_gameTimeTicking = false;
_g524_restartGameAllowed = false;
_g331_pressingEye = false;
_g333_pressingMouth = false;
_g332_stopPressingEye = false;
_g334_stopPressingMouth = false;
_g340_highlightBoxInversionRequested = false;
2016-06-17 23:08:04 +02:00
debug("DMEngine::DMEngine");
}
DMEngine::~DMEngine() {
debug("DMEngine::~DMEngine");
// dispose of resources
delete _rnd;
delete _console;
delete _displayMan;
delete _dungeonMan;
2016-06-15 10:41:33 +02:00
delete _eventMan;
delete _menuMan;
delete _championMan;
delete _loadsaveMan;
2016-06-19 00:54:28 +02:00
delete _objectMan;
delete _inventoryMan;
delete _textMan;
2016-08-26 22:37:14 +02:00
delete _movsens;
delete _groupMan;
delete _timeline;
// clear debug channels
DebugMan.clearAllDebugChannels();
}
2016-08-26 22:47:44 +02:00
void DMEngine::f463_initializeGame() {
_displayMan->f479_loadGraphics();
_displayMan->f460_initializeGraphicData();
// DUMMY CODE: next line
2016-07-02 00:27:05 +02:00
_displayMan->loadPalette(g19_PalCredits);
_eventMan->initMouse();
2016-08-26 22:47:44 +02:00
while (_loadsaveMan->f435_loadgame() != k1_LoadgameSuccess) {
2016-06-19 00:24:19 +02:00
warning("TODO: F0441_STARTEND_ProcessEntrance");
}
2016-08-26 22:47:44 +02:00
_displayMan->f94_loadFloorSet(k0_FloorSetStone);
_displayMan->f95_loadWallSet(k0_WallSetStone);
_objectMan->loadObjectNames();
// There was some memory wizardy for the Amiga platform, I skipped that part
_displayMan->f461_allocateFlippedWallBitmaps();
2016-08-26 22:47:44 +02:00
f462_startGame();
warning("MISSING CODE: F0267_MOVE_GetMoveResult_CPSCE (if newGame)");
_eventMan->showMouse(true);
warning("MISSING CODE: F0357_COMMAND_DiscardAllInput");
}
void DMEngine::f448_initMemoryManager() {
warning("STUB FUNCTION");
for (uint16 i = 0; i < 16; ++i)
_displayMan->_g347_paletteTopAndBottomScreen[i] = g21_PalDungeonView[0][i];
}
void DMEngine::f462_startGame() {
2016-08-26 22:43:17 +02:00
_g331_pressingEye = false;
_g332_stopPressingEye = false;
_g333_pressingMouth = false;
_g334_stopPressingMouth = false;
_g340_highlightBoxInversionRequested = false;
2016-07-02 02:58:44 +02:00
_eventMan->_g341_highlightBoxEnabled = false;
2016-07-02 01:55:48 +02:00
_championMan->_g300_partyIsSleeping = false;
2016-08-26 22:47:44 +02:00
_championMan->_g506_actingChampionOrdinal = M0_indexToOrdinal(kM1_ChampionNone);
_menuMan->_g509_actionAreaContainsIcons = true;
2016-08-26 22:47:44 +02:00
_eventMan->_g599_useChampionIconOrdinalAsMousePointerBitmap = M0_indexToOrdinal(kM1_ChampionNone);
2016-07-02 02:58:44 +02:00
_eventMan->_g441_primaryMouseInput = g447_PrimaryMouseInput_Interface;
_eventMan->_g442_secondaryMouseInput = g448_SecondaryMouseInput_Movement;
warning("MISSING CODE: set primary/secondary keyboard input");
2016-08-26 22:47:44 +02:00
f3_processNewPartyMap(_dungeonMan->_g309_partyMapIndex);
2016-07-02 13:47:19 +02:00
if (!_g298_newGame) {
2016-06-19 00:24:19 +02:00
warning("TODO: loading game");
} else {
2016-07-02 00:27:05 +02:00
_displayMan->_g578_useByteBoxCoordinates = false;
2016-06-19 00:24:19 +02:00
warning("TODO: clear screen");
}
2016-06-19 00:24:19 +02:00
warning("TODO: build copper");
2016-08-26 22:47:44 +02:00
_menuMan->f395_drawMovementArrows();
_championMan->f278_resetDataToStartGame();
2016-08-26 22:43:17 +02:00
_g301_gameTimeTicking = true;
}
2016-08-26 22:47:44 +02:00
void DMEngine::f3_processNewPartyMap(uint16 mapIndex) {
warning("MISSING CODE: F0194_GROUP_RemoveAllActiveGroups");
2016-08-26 22:47:44 +02:00
_dungeonMan->f174_setCurrentMapAndPartyMap(mapIndex);
_displayMan->f96_loadCurrentMapGraphics();
warning("MISSING CODE: F0195_GROUP_AddAllActiveGroups");
warning("MISSING CODE: F0337_INVENTORY_SetDungeonViewPalette");
}
Common::Error DMEngine::run() {
2016-06-29 23:17:04 +02:00
initArrays();
// scummvm/engine specific
initGraphics(320, 200, false);
_console = new Console(this);
_displayMan = new DisplayMan(this);
_dungeonMan = new DungeonMan(this);
2016-06-15 10:41:33 +02:00
_eventMan = new EventManager(this);
_menuMan = new MenuMan(this);
_championMan = new ChampionMan(this);
_loadsaveMan = new LoadsaveMan(this);
2016-06-19 00:54:28 +02:00
_objectMan = new ObjectMan(this);
_inventoryMan = new InventoryMan(this);
_textMan = new TextMan(this);
_movsens = new MovesensMan(this);
_groupMan = new GroupMan(this);
_timeline = new Timeline(this);
_displayMan->setUpScreens(320, 200);
2016-08-26 22:47:44 +02:00
f463_initializeGame(); // @ F0463_START_InitializeGame_CPSADEF
while (true) {
2016-08-26 22:47:44 +02:00
f2_gameloop();
2016-06-19 00:24:19 +02:00
warning("TODO: F0444_STARTEND_Endgame(G0303_B_PartyDead);");
}
2016-06-16 23:48:18 +02:00
return Common::kNoError;
}
2016-06-16 23:48:18 +02:00
2016-08-26 22:47:44 +02:00
void DMEngine::f2_gameloop() {
warning("DUMMY CODE SETTING PARTY POS AND DIRECTION");
2016-07-02 13:47:19 +02:00
_dungeonMan->_g306_partyMapX = 10;
_dungeonMan->_g307_partyMapY = 4;
_dungeonMan->_g308_partyDir = kDirNorth;
warning("DUMMY CODE: setting InventoryMan::_g432_inventoryChampionOrdinal to zero");
_inventoryMan->_g432_inventoryChampionOrdinal = 0;
warning("DUMMY CODE: clearing screen to black"); // in loop below
while (true) {
2016-08-26 22:43:17 +02:00
_g321_stopWaitingForPlayerInput = false;
2016-08-26 22:47:44 +02:00
_menuMan->f390_refreshActionAreaAndSetChampDirMaxDamageReceived();
//do {
_eventMan->processInput();
2016-08-26 22:47:44 +02:00
_eventMan->f380_processCommandQueue();
2016-08-26 22:43:17 +02:00
//} while (!_g321_stopWaitingForPlayerInput || !_g301_gameTimeTicking);
if (!_inventoryMan->_g432_inventoryChampionOrdinal && !_championMan->_g300_partyIsSleeping) {
Box box(0, 223, 0, 135);
_displayMan->f135_fillBoxBitmap(_displayMan->_g296_bitmapViewport, box, k0_ColorBlack, k112_byteWidthViewport, k136_heightViewport); // dummy code
2016-08-26 22:47:44 +02:00
_displayMan->f128_drawDungeon(_dungeonMan->_g308_partyDir, _dungeonMan->_g306_partyMapX, _dungeonMan->_g307_partyMapY);
}
2016-07-02 23:10:05 +02:00
// DUMMY CODE: next 2 lines
2016-08-26 22:47:44 +02:00
_menuMan->f395_drawMovementArrows();
2016-07-02 23:10:05 +02:00
_displayMan->f97_drawViewport(k1_viewportDungeonView);
_displayMan->updateScreen();
_system->delayMillis(10);
}
2016-06-16 23:48:18 +02:00
}
2016-08-26 22:47:44 +02:00
int16 DMEngine::M1_ordinalToIndex(int16 val) {
2016-06-23 23:12:39 +02:00
return val - 1;
}
2016-08-26 22:47:44 +02:00
int16 DMEngine::M0_indexToOrdinal(int16 val) {
2016-06-23 23:12:39 +02:00
return val + 1;
}
} // End of namespace DM