scummvm/engines/dm/dm.cpp

712 lines
26 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"
2016-07-11 11:37:01 +02:00
#include "common/array.h"
#include "common/algorithm.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"
2016-07-07 00:46:51 +02:00
#include "projexpl.h"
2016-07-25 16:27:24 +02:00
#include "dialog.h"
namespace DM {
2016-07-11 11:37:01 +02:00
void warning(bool repeat, const char* s, ...) {
va_list va;
va_start(va, s);
Common::String output = Common::String::vformat(s, va);
va_end(va);
if (repeat) {
::warning(output.c_str());
} else {
static Common::Array<Common::String> stringsPrinted;
if (Common::find(stringsPrinted.begin(), stringsPrinted.end(), s) == stringsPrinted.end()) {
stringsPrinted.push_back(output);
::warning(output.c_str());
}
}
}
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 toggleFlag(uint16& val, uint16 mask) {
return val ^= mask;
2016-07-04 17:14:32 +02:00
}
uint16 M75_bitmapByteCount(uint16 pixelWidth, uint16 height) {
return pixelWidth / 2 * height;
}
uint16 M21_normalizeModulo4(uint16 val) {
return val & 3;
}
2016-07-25 16:18:33 +02:00
int32 M30_time(int32 mapTime) {
return mapTime & 0x00FFFFFF;
2016-07-07 00:46:51 +02:00
}
2016-07-25 16:18:33 +02:00
int32 M33_setMapAndTime(int32 &mapTime, uint32 map, uint32 time) {
return (mapTime) = ((time) | (((long)(map)) << 24));
2016-07-07 00:46:51 +02:00
}
2016-07-25 16:18:33 +02:00
uint16 M29_map(int32 mapTime) {
return ((uint16)((mapTime) >> 24));
2016-07-07 00:46:51 +02:00
}
Thing M15_thingWithNewCell(Thing thing, int16 cell) {
return Thing(((thing.toUint16()) & 0x3FFF) | ((cell) << 14));
}
int16 M38_distance(int16 mapx1, int16 mapy1, int16 mapx2, int16 mapy2) {
return ABS(mapx1 - mapx2) + ABS(mapy1 - mapy2);
}
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("dm");
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;
2016-06-19 00:54:28 +02:00
_objectMan = nullptr;
_inventoryMan = nullptr;
_textMan = nullptr;
_moveSens = nullptr;
_groupMan = nullptr;
_timeline = nullptr;
2016-07-07 00:46:51 +02:00
_projexpl = nullptr;
2016-07-25 16:27:24 +02:00
_displayMan = nullptr;
2016-08-26 22:50:01 +02:00
_engineShouldQuit = false;
2016-07-19 18:04:14 +02:00
_g528_saveFormat = 0;
_g527_platform = 0;
_g526_dungeonId = 0;
2016-08-26 22:50:01 +02:00
_g298_newGame = false;
_g523_restartGameRequest = false;
_g321_stopWaitingForPlayerInput = true;
2016-08-26 22:43:17 +02:00
_g301_gameTimeTicking = false;
_g524_restartGameAllowed = false;
2016-08-26 22:50:01 +02:00
_g525_gameId = 0;
2016-08-26 22:43:17 +02:00
_g331_pressingEye = false;
_g332_stopPressingEye = false;
2016-08-26 22:50:01 +02:00
_g333_pressingMouth = false;
2016-08-26 22:43:17 +02:00
_g334_stopPressingMouth = false;
_g340_highlightBoxInversionRequested = false;
2016-08-26 22:50:01 +02:00
_g311_projectileDisableMovementTicks = 0;
_g312_lastProjectileDisabledMovementDirection = 0;
2016-07-07 00:46:51 +02:00
_g302_gameWon = false;
_g327_newPartyMapIndex = kM1_mapIndexNone;
2016-08-26 22:50:01 +02:00
_g325_setMousePointerToObjectInMainLoop = false;
_g310_disabledMovementTicks = 0;
_g313_gameTime = 0;
_g353_stringBuildBuffer[0] = '\0';
_g318_waitForInputMaxVerticalBlankCount = 0;
2016-07-20 16:42:37 +02:00
for (uint16 i = 0; i < 10; ++i)
_g562_entranceDoorAnimSteps[i] = nullptr;
_g564_interfaceCredits = nullptr;
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;
2016-06-19 00:54:28 +02:00
delete _objectMan;
delete _inventoryMan;
delete _textMan;
delete _moveSens;
delete _groupMan;
delete _timeline;
2016-07-07 00:46:51 +02:00
delete _projexpl;
2016-07-25 16:27:24 +02:00
delete _dialog;
2016-08-01 15:24:47 +02:00
for (uint16 i = 0; i < k34_D13_soundCount; ++i)
delete[] _gK24_soundData[i]._firstSample;
// clear debug channels
DebugMan.clearAllDebugChannels();
}
2016-07-20 16:42:37 +02:00
bool DMEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsSavingDuringRuntime) ||
(f == kSupportsLoadingDuringRuntime);
}
void DMEngine::f22_delay(uint16 verticalBlank) {
_system->delayMillis(verticalBlank * 20); // Google says most Amiga games had a refreshrate of 50 hz
2016-07-07 00:46:51 +02:00
}
uint16 DMEngine::f30_getScaledProduct(uint16 val, uint16 scale, uint16 vale2) {
return ((uint32)val * vale2) >> scale;
}
2016-08-26 22:47:44 +02:00
void DMEngine::f463_initializeGame() {
_displayMan->f479_loadGraphics();
_displayMan->f460_initializeGraphicData();
warning(false, "Dummy code in f463_initializeGame, setting palette");
2016-08-26 22:50:01 +02:00
_displayMan->loadPalette(g21_PalDungeonView[0]);
_displayMan->f94_loadFloorSet(k0_FloorSetStone);
_displayMan->f95_loadWallSet(k0_WallSetStone);
2016-08-01 15:24:47 +02:00
f503_loadSounds();
warning(false, "MISSING CODE: F0437_STARTEND_DrawTitle");
2016-08-26 22:50:01 +02:00
_textMan->f54_textInitialize();
_objectMan->loadObjectNames();
_eventMan->initMouse();
do {
2016-07-20 16:42:37 +02:00
f441_processEntrance();
if (_engineShouldQuit)
return;
} while (f435_loadgame(1) != k1_LoadgameSuccess);
2016-08-26 22:50:01 +02:00
//F0396_MENUS_LoadSpellAreaLinesBitmap() is not needed, every bitmap has been loaded
// 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();
2016-08-26 22:50:01 +02:00
if (_g298_newGame)
_moveSens->f267_getMoveResult(Thing::_party, kM1_MapXNotOnASquare, 0, _dungeonMan->_g306_partyMapX, _dungeonMan->_g307_partyMapY);
2016-07-07 00:46:51 +02:00
_eventMan->f78_showMouse();
_eventMan->f357_discardAllInput();
}
void DMEngine::f448_initMemoryManager() {
2016-07-11 11:37:01 +02:00
warning(false, "STUB FUNCTION");
for (uint16 i = 0; i < 16; ++i)
_displayMan->_g347_paletteTopAndBottomScreen[i] = g21_PalDungeonView[0][i];
}
void DMEngine::f462_startGame() {
static Box boxScreenTop(0, 319, 0, 32); // @ G0061_s_Graphic562_Box_ScreenTop
static Box boxScreenRight(224, 319, 33, 169); // @ G0062_s_Graphic562_Box_ScreenRight
static Box boxScreenBottom(0, 319, 169, 199); // @ G0063_s_Graphic562_Box_ScreenBottom
2016-08-26 22:50:01 +02:00
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;
2016-07-11 10:52:38 +02:00
_eventMan->_g443_primaryKeyboardInput = g458_primaryKeyboardInput_interface;
_eventMan->_g444_secondaryKeyboardInput = g459_secondaryKeyboardInput_movement;
2016-08-26 22:47:44 +02:00
f3_processNewPartyMap(_dungeonMan->_g309_partyMapIndex);
2016-07-02 13:47:19 +02:00
if (!_g298_newGame) {
_displayMan->_g578_useByteBoxCoordinates = false;
f22_delay(1);
_displayMan->D24_fillScreenBox(boxScreenTop, k0_ColorBlack);
_displayMan->D24_fillScreenBox(boxScreenRight, k0_ColorBlack);
_displayMan->D24_fillScreenBox(boxScreenBottom, k0_ColorBlack);
} else {
2016-07-02 00:27:05 +02:00
_displayMan->_g578_useByteBoxCoordinates = false;
_displayMan->D24_fillScreenBox(boxScreenTop, k0_ColorBlack);
_displayMan->D24_fillScreenBox(boxScreenRight, k0_ColorBlack);
_displayMan->D24_fillScreenBox(boxScreenBottom, k0_ColorBlack);
}
2016-07-11 11:37:01 +02:00
warning(false, "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) {
2016-08-26 22:50:01 +02:00
_groupMan->f194_removeAllActiveGroups();
2016-08-26 22:47:44 +02:00
_dungeonMan->f174_setCurrentMapAndPartyMap(mapIndex);
_displayMan->f96_loadCurrentMapGraphics();
2016-08-26 22:50:01 +02:00
_groupMan->f195_addAllActiveGroups();
2016-07-07 00:46:51 +02:00
_inventoryMan->f337_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);
2016-06-19 00:54:28 +02:00
_objectMan = new ObjectMan(this);
_inventoryMan = new InventoryMan(this);
_textMan = new TextMan(this);
_moveSens = new MovesensMan(this);
_groupMan = new GroupMan(this);
_timeline = new Timeline(this);
2016-07-07 00:46:51 +02:00
_projexpl = new ProjExpl(this);
2016-07-25 16:27:24 +02:00
_dialog = new DialogMan(this);
_displayMan->setUpScreens(320, 200);
f463_initializeGame();
while (true) {
2016-08-26 22:47:44 +02:00
f2_gameloop();
if (_engineShouldQuit)
return Common::kNoError;
f444_endGame(_championMan->_g303_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() {
if (_g298_newGame) {
warning(false, "DUMMY CODE: SETTING PARTY POS AND DIRECTION");
_dungeonMan->_g306_partyMapX = 9;
_dungeonMan->_g307_partyMapY = 9;
_dungeonMan->_g308_partyDir = kDirWest;
}
2016-07-07 00:46:51 +02:00
_g318_waitForInputMaxVerticalBlankCount = 10;
while (true) {
if (_engineShouldQuit)
return;
2016-08-26 22:50:01 +02:00
for (;;) {
if (_g327_newPartyMapIndex != kM1_mapIndexNone) {
f3_processNewPartyMap(_g327_newPartyMapIndex);
_moveSens->f267_getMoveResult(Thing::_party, kM1_MapXNotOnASquare, 0, _dungeonMan->_g306_partyMapX, _dungeonMan->_g307_partyMapY);
_g327_newPartyMapIndex = kM1_mapIndexNone;
_eventMan->f357_discardAllInput();
}
_timeline->f261_processTimeline();
if (_g327_newPartyMapIndex == kM1_mapIndexNone)
break;
}
2016-08-26 22:50:01 +02:00
if (!_inventoryMan->_g432_inventoryChampionOrdinal && !_championMan->_g300_partyIsSleeping) {
Box box(0, 223, 0, 135);
warning(false, "DUMMY CODE: clearing screen to black");
_displayMan->f135_fillBoxBitmap(_displayMan->_g296_bitmapViewport, box, k0_ColorBlack, k112_byteWidthViewport, k136_heightViewport); // dummy code
_displayMan->f128_drawDungeon(_dungeonMan->_g308_partyDir, _dungeonMan->_g306_partyMapX, _dungeonMan->_g307_partyMapY);
if (_g325_setMousePointerToObjectInMainLoop) {
_g325_setMousePointerToObjectInMainLoop = false;
_eventMan->f78_showMouse();
_eventMan->f68_setPointerToObject(_objectMan->_g412_objectIconForMousePointer);
_eventMan->f77_hideMouse();
2016-07-11 11:37:01 +02:00
}
if (_eventMan->_g326_refreshMousePointerInMainLoop) {
_eventMan->_g326_refreshMousePointerInMainLoop = false;
_eventMan->_g598_mousePointerBitmapUpdated = true;
_eventMan->f78_showMouse();
_eventMan->f77_hideMouse();
}
}
2016-07-12 08:53:34 +02:00
// F0363_COMMAND_HighlightBoxDisable();
// F0065_SOUND_PlayPendingSound_CPSD();
_championMan->f320_applyAndDrawPendingDamageAndWounds();
2016-08-26 22:50:01 +02:00
if (_championMan->_g303_partyDead)
break;
2016-07-07 00:46:51 +02:00
_g313_gameTime++;
2016-08-26 22:50:01 +02:00
if (!(_g313_gameTime & 511))
_inventoryMan->f338_decreaseTorchesLightPower();
2016-07-12 08:53:34 +02:00
if (_championMan->_g407_party._freezeLifeTicks)
2016-08-26 22:50:01 +02:00
_championMan->_g407_party._freezeLifeTicks -= 1;
2016-07-12 08:53:34 +02:00
2016-08-26 22:47:44 +02:00
_menuMan->f390_refreshActionAreaAndSetChampDirMaxDamageReceived();
if (!(_g313_gameTime & (_championMan->_g300_partyIsSleeping ? 15 : 63)))
_championMan->f331_applyTimeEffects();
2016-07-12 08:53:34 +02:00
if (_g310_disabledMovementTicks)
_g310_disabledMovementTicks--;
if (_g311_projectileDisableMovementTicks)
_g311_projectileDisableMovementTicks--;
2016-07-07 00:46:51 +02:00
_textMan->f44_messageAreaClearExpiredRows();
2016-07-07 00:46:51 +02:00
_g321_stopWaitingForPlayerInput = false;
uint16 vblankCounter = 0;
2016-07-11 14:55:56 +02:00
do {
_eventMan->processInput();
if (_g332_stopPressingEye) {
_g331_pressingEye = false;
_g332_stopPressingEye = false;
_inventoryMan->f353_drawStopPressingEye();
} else if (_g334_stopPressingMouth) {
_g333_pressingMouth = false;
_g334_stopPressingMouth = false;
_inventoryMan->f350_drawStopPressingMouth();
}
_eventMan->f380_processCommandQueue();
if (_engineShouldQuit)
return;
2016-07-11 14:55:56 +02:00
_displayMan->updateScreen();
// if (!_g321_stopWaitingForPlayerInput) {
2016-07-12 08:53:34 +02:00
// F0363_COMMAND_HighlightBoxDisable();
2016-07-11 14:55:56 +02:00
// }
2016-07-02 23:10:05 +02:00
_system->delayMillis(2);
if (++vblankCounter >= _g318_waitForInputMaxVerticalBlankCount * 5)
_g321_stopWaitingForPlayerInput = true;
} while (!_g321_stopWaitingForPlayerInput || !_g301_gameTimeTicking);
}
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;
}
2016-07-20 16:42:37 +02:00
void DMEngine::f441_processEntrance() {
_eventMan->_g441_primaryMouseInput = g445_PrimaryMouseInput_Entrance;
_eventMan->_g442_secondaryMouseInput = nullptr;
_eventMan->_g443_primaryKeyboardInput = nullptr;
_eventMan->_g444_secondaryKeyboardInput = nullptr;
_g562_entranceDoorAnimSteps[0] = new byte[128 * 161 * 12];
for (uint16 idx = 1; idx < 8; idx++)
_g562_entranceDoorAnimSteps[idx] = _g562_entranceDoorAnimSteps[idx - 1] + 128 * 161;
2016-07-20 16:42:37 +02:00
_g562_entranceDoorAnimSteps[8] = _g562_entranceDoorAnimSteps[7] + 128 * 161;
_g562_entranceDoorAnimSteps[9] = _g562_entranceDoorAnimSteps[8] + 128 * 161 * 2;
_displayMan->f466_loadIntoBitmap(k3_entranceRightDoorGraphicIndice, _g562_entranceDoorAnimSteps[4]);
_displayMan->f466_loadIntoBitmap(k2_entranceLeftDoorGraphicIndice, _g562_entranceDoorAnimSteps[0]);
_g564_interfaceCredits = _displayMan->f489_getNativeBitmapOrGraphic(k5_creditsGraphicIndice);
_displayMan->_g578_useByteBoxCoordinates = false;
Box displayBox;
displayBox._x1 = 0;
displayBox._x2 = 100;
displayBox._y1 = 0;
displayBox._y2 = 160;
for (uint16 idx = 1; idx < 4; idx++) {
_displayMan->f132_blitToBitmap(_g562_entranceDoorAnimSteps[0], _g562_entranceDoorAnimSteps[idx], displayBox, idx << 2, 0, k64_byteWidth, k64_byteWidth, kM1_ColorNoTransparency, 161, 161);
displayBox._x2 -= 4;
2016-07-20 16:42:37 +02:00
}
displayBox._x2 = 127;
for (uint16 idx = 5; idx < 8; idx++) {
displayBox._x1 += 4;
_displayMan->f132_blitToBitmap(_g562_entranceDoorAnimSteps[4], _g562_entranceDoorAnimSteps[idx], displayBox, 0, 0, k64_byteWidth, k64_byteWidth, kM1_ColorNoTransparency, 161, 161);
2016-07-20 16:42:37 +02:00
}
2016-07-20 16:42:37 +02:00
do {
f439_drawEntrance();
_eventMan->f78_showMouse();
_eventMan->f357_discardAllInput();
_g298_newGame = k99_modeWaitingOnEntrance;
do {
_eventMan->processInput();
if (_engineShouldQuit)
return;
2016-07-20 16:42:37 +02:00
_eventMan->f380_processCommandQueue();
_displayMan->updateScreen();
} while (_g298_newGame == k99_modeWaitingOnEntrance);
} while (_g298_newGame == k202_CommandEntranceDrawCredits);
//Strangerke: CHECKME: Earlier versions were using G0566_puc_Graphic534_Sound01Switch
f060_SOUND_Play(k01_soundSWITCH, 112, 0x40, 0x40);
2016-07-20 16:42:37 +02:00
f22_delay(20);
_eventMan->f78_showMouse();
if (_g298_newGame)
f438_STARTEND_OpenEntranceDoors();
2016-07-20 16:42:37 +02:00
delete[] _g562_entranceDoorAnimSteps[0];
for (uint16 i = 0; i < 10; ++i)
_g562_entranceDoorAnimSteps[i] = nullptr;
}
void DMEngine::f444_endGame(bool doNotDrawCreditsOnly) {
// TODO: localization
2016-07-29 23:14:29 +02:00
static Box G0013_s_Graphic562_Box_Endgame_Restart_Outer = Box(103, 217, 145, 159);
static Box G0014_s_Graphic562_Box_Endgame_Restart_Inner = Box(105, 215, 147, 157);
static Box G0012_s_Graphic562_Box_Endgame_TheEnd = Box(120, 199, 95, 108);
static Box G0015_s_Graphic562_Box_Endgame_ChampionMirror = Box(11, 74, 7, 49);
static Box G0016_s_Graphic562_Box_Endgame_ChampionPortrait = Box(27, 58, 13, 41);
int16 L1409_i_Multiple;
#define AL1409_i_Color L1409_i_Multiple
#define AL1409_i_ChampionIndex L1409_i_Multiple
#define AL1409_i_VerticalBlankCount L1409_i_Multiple
int16 L1410_i_Multiple;
#define AL1410_i_Counter L1410_i_Multiple
#define AL1410_i_Y L1410_i_Multiple
int16 L1411_i_Multiple;
#define AL1411_i_X L1411_i_Multiple
#define AL1411_i_SkillIndex L1411_i_Multiple
int16 L1412_i_SkillLevel;
char L1415_c_ChampionTitleFirstCharacter;
Champion* L1416_ps_Champion;
uint16 L1419_aui_Palette[16];
uint16 L1420_aui_Palette_TopAndBottomScreen[16];
uint16 L1421_aui_Palette_DarkBlue[16];
char L1422_ac_String[20];
// Strangerke: Not so sure it's useless.
bool L1423_B_WaitBeforeDrawingRestart; /* BUG0_00 Useless code */
L1423_B_WaitBeforeDrawingRestart = true; /* BUG0_00 Useless code */
_eventMan->f67_setMousePointerToNormal(k0_pointerArrow);
_eventMan->f78_showMouse();
_eventMan->_g441_primaryMouseInput = nullptr;
_eventMan->_g442_secondaryMouseInput = nullptr;
_eventMan->_g443_primaryKeyboardInput = nullptr;
_eventMan->_g444_secondaryKeyboardInput = nullptr;
if (doNotDrawCreditsOnly && !_g302_gameWon) {
f064_SOUND_RequestPlay_CPSD(k06_soundSCREAM, _dungeonMan->_g306_partyMapX, _dungeonMan->_g307_partyMapY, k0_soundModePlayImmediately);
f22_delay(240);
}
if (_displayMan->_g322_paletteSwitchingEnabled) {
for (uint16 i = 0; i < 16; ++i)
L1420_aui_Palette_TopAndBottomScreen[i] = _displayMan->_g347_paletteTopAndBottomScreen[i];
for (AL1410_i_Counter = 0; AL1410_i_Counter <= 7; AL1410_i_Counter++) {
f22_delay(1);
for (AL1409_i_Color = 0; AL1409_i_Color < 16; AL1409_i_Color++) {
_displayMan->_g346_paletteMiddleScreen[AL1409_i_Color] = _displayMan->f431_getDarkenedColor(_displayMan->_g346_paletteMiddleScreen[AL1409_i_Color]);
_displayMan->_g347_paletteTopAndBottomScreen[AL1409_i_Color] = _displayMan->f431_getDarkenedColor(_displayMan->_g347_paletteTopAndBottomScreen[AL1409_i_Color]);
}
}
_displayMan->_g322_paletteSwitchingEnabled = false;
f22_delay(1);
for (uint16 i = 0; i < 16; ++i)
_displayMan->_g347_paletteTopAndBottomScreen[i] = L1420_aui_Palette_TopAndBottomScreen[i];
} else
_displayMan->f436_STARTEND_FadeToPalette(_displayMan->_g345_aui_BlankBuffer);
if (doNotDrawCreditsOnly) {
if (_g302_gameWon) {
// Strangerke: Related to portraits. Game data could be missing for earlier versions of the game.
_displayMan->fillScreen(k12_ColorDarkestGray);
for (AL1409_i_ChampionIndex = k0_ChampionFirst; AL1409_i_ChampionIndex < _championMan->_g305_partyChampionCount; AL1409_i_ChampionIndex++) {
AL1410_i_Y = AL1409_i_ChampionIndex * 48;
L1416_ps_Champion = &_championMan->_gK71_champions[AL1409_i_ChampionIndex];
_displayMan->f21_blitToScreen(_displayMan->f489_getNativeBitmapOrGraphic(k208_wallOrn_43_champMirror), &G0015_s_Graphic562_Box_Endgame_ChampionMirror, k32_byteWidth, k10_ColorFlesh, 43);
_displayMan->f21_blitToScreen(L1416_ps_Champion->_portrait, &G0016_s_Graphic562_Box_Endgame_ChampionPortrait, k16_byteWidth, k1_ColorDarkGary, 29);
_textMan->f443_endgamePrintString(87, AL1410_i_Y += 14, k9_ColorGold, L1416_ps_Champion->_name);
AL1411_i_X = (6 * strlen(L1416_ps_Champion->_name)) + 87;
L1415_c_ChampionTitleFirstCharacter = L1416_ps_Champion->_title[0];
if ((L1415_c_ChampionTitleFirstCharacter != ',') && (L1415_c_ChampionTitleFirstCharacter != ';') && (L1415_c_ChampionTitleFirstCharacter != '-')) {
AL1411_i_X += 6;
}
_textMan->f443_endgamePrintString(AL1411_i_X, AL1410_i_Y++, k9_ColorGold, L1416_ps_Champion->_title);
for (AL1411_i_SkillIndex = k0_ChampionSkillFighter; AL1411_i_SkillIndex <= k3_ChampionSkillWizard; AL1411_i_SkillIndex++) {
L1412_i_SkillLevel = MIN((uint16)16, _championMan->f303_getSkillLevel(AL1409_i_ChampionIndex, AL1411_i_SkillIndex | (k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience)));
if (L1412_i_SkillLevel == 1)
continue;
strcpy(L1422_ac_String, G0428_apc_SkillLevelNames[L1412_i_SkillLevel - 2]);
strcat(L1422_ac_String, " ");
strcat(L1422_ac_String, g417_baseSkillName[AL1411_i_SkillIndex]);
_textMan->f443_endgamePrintString(105, AL1410_i_Y = AL1410_i_Y + 8, k13_ColorLightestGray, L1422_ac_String);
}
G0015_s_Graphic562_Box_Endgame_ChampionMirror._y1 += 48;
G0015_s_Graphic562_Box_Endgame_ChampionMirror._y2 += 48;
G0016_s_Graphic562_Box_Endgame_ChampionPortrait._y1 += 48;
G0016_s_Graphic562_Box_Endgame_ChampionPortrait._y1 += 48;
}
_displayMan->f436_STARTEND_FadeToPalette(_displayMan->_g347_paletteTopAndBottomScreen);
_engineShouldQuit = true;
return;
}
T0444017:
_displayMan->fillScreen(k0_ColorBlack);
_displayMan->f21_blitToScreen(_displayMan->f489_getNativeBitmapOrGraphic(k6_theEndIndice), &G0012_s_Graphic562_Box_Endgame_TheEnd, k40_byteWidth, kM1_ColorNoTransparency, 14);
for (uint16 i = 0; i < 16; ++i)
L1421_aui_Palette_DarkBlue[i] = D01_RGB_DARK_BLUE;
for (uint16 i = 0; i < 16; ++i)
L1419_aui_Palette[i] = L1421_aui_Palette_DarkBlue[i];
L1419_aui_Palette[15] = D09_RGB_WHITE;
_displayMan->f436_STARTEND_FadeToPalette(L1419_aui_Palette);
if (L1423_B_WaitBeforeDrawingRestart) { /* BUG0_00 Useless code */
f22_delay(300);
} /* BUG0_00 Useless code */
if (_g524_restartGameAllowed) {
_displayMan->_g578_useByteBoxCoordinates = false;
_displayMan->D24_fillScreenBox(G0013_s_Graphic562_Box_Endgame_Restart_Outer, k12_ColorDarkestGray);
_displayMan->D24_fillScreenBox(G0014_s_Graphic562_Box_Endgame_Restart_Inner, k0_ColorBlack);
_textMan->f53_printToLogicalScreen(110, 154, k4_ColorCyan, k0_ColorBlack, "RESTART THIS GAME");
L1419_aui_Palette[1] = D03_RGB_PINK;
L1419_aui_Palette[4] = D09_RGB_WHITE;
_eventMan->_g441_primaryMouseInput = g446_PrimaryMouseInput_RestartGame;
_eventMan->f357_discardAllInput();
_eventMan->f77_hideMouse();
_displayMan->f436_STARTEND_FadeToPalette(L1419_aui_Palette);
for (AL1409_i_VerticalBlankCount = 900; --AL1409_i_VerticalBlankCount && !_g523_restartGameRequest; f22_delay(1)) {
_eventMan->f380_processCommandQueue();
}
_eventMan->f78_showMouse();
if (_g523_restartGameRequest) {
_displayMan->f436_STARTEND_FadeToPalette(L1421_aui_Palette_DarkBlue);
_displayMan->fillScreen(k0_ColorBlack);
_displayMan->f436_STARTEND_FadeToPalette(g21_PalDungeonView[0]);
_g298_newGame = k0_modeLoadSavedGame;
if (f435_loadgame(1) != kM1_LoadgameFailure) {
f462_startGame();
_g523_restartGameRequest = false;
_eventMan->f77_hideMouse();
_eventMan->f357_discardAllInput();
return;
}
}
}
_displayMan->f436_STARTEND_FadeToPalette(L1421_aui_Palette_DarkBlue);
}
Box box(0, 319, 0, 199);
_displayMan->f132_blitToBitmap(_displayMan->f489_getNativeBitmapOrGraphic(k5_creditsGraphicIndice), _displayMan->_g348_bitmapScreen, box, 0, 0, 160, 160, kM1_ColorNoTransparency);
_displayMan->f436_STARTEND_FadeToPalette(g19_PalCredits);
_eventMan->f541_waitForMouseOrKeyActivity();
if (_engineShouldQuit)
return;
if (_g524_restartGameAllowed && doNotDrawCreditsOnly) {
L1423_B_WaitBeforeDrawingRestart = false;
_displayMan->f436_STARTEND_FadeToPalette(L1421_aui_Palette_DarkBlue);
goto T0444017;
}
_engineShouldQuit = true;
return;
}
2016-07-20 16:42:37 +02:00
void DMEngine::f439_drawEntrance() {
2016-07-23 09:32:38 +02:00
static Box K0079_s_Box_Entrance_DoorsUpperHalf = Box(0, 231, 0, 80);
static Box K0152_s_Box_Entrance_DoorsLowerHalf = Box(0, 231, 81, 160);
static Box G0010_s_Graphic562_Box_Entrance_ClosedDoorLeft = Box(0, 104, 30, 190);
static Box G0011_s_Graphic562_Box_Entrance_ClosedDoorRight = Box(105, 231, 30, 190);
2016-07-20 16:42:37 +02:00
uint16 L1397_ui_ColumnIndex;
byte* L1398_apuc_MicroDungeonCurrentMapData[32];
Square L1399_auc_MicroDungeonSquares[25];
_dungeonMan->_g309_partyMapIndex = k255_mapIndexEntrance;
_displayMan->_g297_drawFloorAndCeilingRequested = true;
_dungeonMan->_g273_currMapWidth = 5;
_dungeonMan->_g274_currMapHeight = 5;
_dungeonMan->_g271_currMapData = L1398_apuc_MicroDungeonCurrentMapData;
Map map; // uninitialized, won't be used
_dungeonMan->_g269_currMap = &map;
2016-07-20 16:42:37 +02:00
for (uint16 i = 0; i < 25; ++i)
L1399_auc_MicroDungeonSquares[i] = Square(k0_ElementTypeWall, 0);
for (L1397_ui_ColumnIndex = 0; L1397_ui_ColumnIndex < 5; L1397_ui_ColumnIndex++) {
L1398_apuc_MicroDungeonCurrentMapData[L1397_ui_ColumnIndex] = (byte*)&L1399_auc_MicroDungeonSquares[L1397_ui_ColumnIndex * 5];
L1399_auc_MicroDungeonSquares[L1397_ui_ColumnIndex + 10] = Square(k1_CorridorElemType, 0);
}
L1399_auc_MicroDungeonSquares[7] = Square(k1_CorridorElemType, 0);
_displayMan->f436_STARTEND_FadeToPalette(_displayMan->_g345_aui_BlankBuffer);
2016-07-20 16:42:37 +02:00
// note, a global variable is used here in the original
_displayMan->f466_loadIntoBitmap(k4_entranceGraphicIndice, _displayMan->_g348_bitmapScreen);
_displayMan->f128_drawDungeon(kDirSouth, 2, 0);
warning(false, "IGNORED CODE: G0324_B_DrawViewportRequested = false;");
_displayMan->_g578_useByteBoxCoordinates = false, _displayMan->f132_blitToBitmap(_displayMan->_g348_bitmapScreen, _g562_entranceDoorAnimSteps[8], K0079_s_Box_Entrance_DoorsUpperHalf, 0, 30, k160_byteWidthScreen, k128_byteWidth, kM1_ColorNoTransparency, 200, 161);
_displayMan->_g578_useByteBoxCoordinates = false, _displayMan->f132_blitToBitmap(_displayMan->_g348_bitmapScreen, _g562_entranceDoorAnimSteps[8], K0152_s_Box_Entrance_DoorsLowerHalf, 0, 111, k160_byteWidthScreen, k128_byteWidth, kM1_ColorNoTransparency, 200, 161);
_displayMan->f21_blitToScreen(_g562_entranceDoorAnimSteps[0], &G0010_s_Graphic562_Box_Entrance_ClosedDoorLeft, k64_byteWidth, kM1_ColorNoTransparency, 161);
_displayMan->f21_blitToScreen(_g562_entranceDoorAnimSteps[4], &G0011_s_Graphic562_Box_Entrance_ClosedDoorRight, k64_byteWidth, kM1_ColorNoTransparency, 161);
_displayMan->f436_STARTEND_FadeToPalette(g20_PalEntrance);
2016-07-20 16:42:37 +02:00
}
} // End of namespace DM