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/)
*/
2016-08-18 17:50:56 +02:00
# include "common/config-manager.h"
2016-04-26 14:44:01 +02:00
# include "common/scummsys.h"
2016-05-02 20:58:55 +02:00
# include "common/system.h"
2016-04-26 14:44:01 +02:00
# include "common/debug.h"
# include "common/debug-channels.h"
# include "common/error.h"
# include "engines/util.h"
2016-05-02 20:58:55 +02:00
# include "engines/engine.h"
# include "graphics/palette.h"
# include "common/file.h"
2016-05-21 21:09:09 +02:00
# include "common/events.h"
2016-07-11 11:37:01 +02:00
# include "common/array.h"
# include "common/algorithm.h"
2016-04-26 14:44:01 +02:00
# include "dm/dm.h"
2016-06-15 22:42:08 +02:00
# include "gfx.h"
# include "dungeonman.h"
# include "eventman.h"
2016-06-17 14:29:05 +02:00
# include "menus.h"
2016-06-18 11:36:31 +02:00
# include "champion.h"
# include "loadsave.h"
2016-06-19 00:54:28 +02:00
# include "objectman.h"
2016-06-19 16:17:28 +02:00
# include "inventory.h"
2016-06-22 20:32:30 +02:00
# include "text.h"
2016-08-26 22:37:14 +02:00
# include "movesens.h"
2016-08-26 22:41:19 +02:00
# include "group.h"
2016-06-30 19:59:35 +02:00
# 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"
2016-08-12 13:04:45 +02:00
# include <graphics/cursorman.h>
2016-08-15 11:56:21 +02:00
# include <advancedDetector.h>
2016-08-16 19:15:35 +02:00
# include "sounds.h"
2016-08-18 19:18:14 +02:00
# include <graphics/surface.h>
2016-08-18 19:51:36 +02:00
# include <common/translation.h>
# include <gui/saveload.h>
2016-04-26 14:44:01 +02:00
namespace DM {
2016-08-27 10:54:29 +02:00
const char * debugGetDirectionName ( Direction dir ) {
static const char * directionNames [ ] = { " North " , " East " , " South " , " West " } ;
2016-08-10 14:44:54 +02:00
if ( dir < 0 | | dir > 3 )
return " Invalid direction " ;
return directionNames [ dir ] ;
}
2016-07-30 10:37:29 +02:00
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 ) ;
}
2016-06-30 15:48:23 +02:00
uint16 returnPrevVal ( uint16 val ) {
2016-07-25 14:35:26 +02:00
return ( Direction ) ( ( val + 3 ) & 3 ) ;
2016-06-30 15:48:23 +02:00
}
uint16 returnNextVal ( uint16 val ) {
return ( val + 1 ) & 0x3 ;
}
2016-07-30 10:37:29 +02:00
bool isOrientedWestEast ( Direction dir ) {
return dir & 1 ;
}
2016-05-21 21:09:09 +02:00
2016-07-04 14:22:17 +02:00
uint16 toggleFlag ( uint16 & val , uint16 mask ) {
return val ^ = mask ;
2016-07-04 17:14:32 +02:00
}
2016-08-23 23:36:18 +02:00
uint16 bitmapByteCount ( uint16 pixelWidth , uint16 height ) {
2016-07-04 17:14:32 +02:00
return pixelWidth / 2 * height ;
2016-07-04 20:54:17 +02:00
}
2016-08-23 23:36:18 +02:00
uint16 normalizeModulo4 ( uint16 val ) {
2016-07-04 20:54:17 +02:00
return val & 3 ;
2016-06-29 22:08:10 +02:00
}
2016-05-04 12:50:06 +02:00
2016-08-23 23:36:18 +02:00
int32 filterTime ( int32 mapTime ) {
2016-07-25 16:18:33 +02:00
return mapTime & 0x00FFFFFF ;
2016-07-07 00:46:51 +02:00
}
2016-08-23 23:36:18 +02:00
int32 setMapAndTime ( int32 & mapTime , uint32 map , uint32 time ) {
2016-07-25 16:18:33 +02:00
return ( mapTime ) = ( ( time ) | ( ( ( long ) ( map ) ) < < 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
2016-08-23 23:36:18 +02:00
uint16 getMap ( int32 mapTime ) {
2016-07-25 16:18:33 +02:00
return ( ( uint16 ) ( ( mapTime ) > > 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
2016-08-23 23:36:18 +02:00
Thing thingWithNewCell ( Thing thing , int16 cell ) {
2016-07-07 00:46:51 +02:00
return Thing ( ( ( thing . toUint16 ( ) ) & 0x3FFF ) | ( ( cell ) < < 14 ) ) ;
}
2016-08-23 23:36:18 +02:00
int16 getDistance ( int16 mapx1 , int16 mapy1 , int16 mapx2 , int16 mapy2 ) {
2016-07-07 00:46:51 +02:00
return ABS ( mapx1 - mapx2 ) + ABS ( mapy1 - mapy2 ) ;
}
2016-08-23 15:39:05 +02:00
DMEngine : : DMEngine ( OSystem * syst , const DMADGameDescription * desc ) : Engine ( syst ) , _console ( nullptr ) , _gameVersion ( desc ) {
2016-05-04 11:23:52 +02:00
// register random source
2016-07-30 10:37:29 +02:00
_rnd = new Common : : RandomSource ( " dm " ) ;
2016-04-26 14:44:01 +02:00
2016-06-17 23:08:04 +02:00
_dungeonMan = nullptr ;
2016-06-18 11:36:31 +02:00
_displayMan = nullptr ;
2016-06-17 23:08:04 +02:00
_eventMan = nullptr ;
_menuMan = nullptr ;
2016-06-18 11:36:31 +02:00
_championMan = nullptr ;
2016-06-19 00:54:28 +02:00
_objectMan = nullptr ;
2016-06-19 16:17:28 +02:00
_inventoryMan = nullptr ;
2016-06-22 20:32:30 +02:00
_textMan = nullptr ;
2016-07-25 16:13:53 +02:00
_moveSens = nullptr ;
2016-08-26 22:41:19 +02:00
_groupMan = nullptr ;
2016-06-30 19:59:35 +02:00
_timeline = nullptr ;
2016-07-07 00:46:51 +02:00
_projexpl = nullptr ;
2016-07-25 16:27:24 +02:00
_displayMan = nullptr ;
2016-08-16 19:15:35 +02:00
_sound = nullptr ;
2016-08-26 22:50:01 +02:00
2016-07-29 22:27:43 +02:00
_engineShouldQuit = false ;
2016-08-23 23:36:18 +02:00
_dungeonId = 0 ;
_newGameFl = 0 ;
_restartGameRequest = false ;
_stopWaitingForPlayerInput = true ;
_gameTimeTicking = false ;
_restartGameAllowed = false ;
_gameId = 0 ;
_pressingEye = false ;
_stopPressingEye = false ;
_pressingMouth = false ;
_stopPressingMouth = false ;
_highlightBoxInversionRequested = false ;
_projectileDisableMovementTicks = 0 ;
_lastProjectileDisabledMovementDirection = 0 ;
_gameWon = false ;
_newPartyMapIndex = kM1_mapIndexNone ;
_setMousePointerToObjectInMainLoop = false ;
_disabledMovementTicks = 0 ;
_gameTime = 0 ;
_stringBuildBuffer [ 0 ] = ' \0 ' ;
_waitForInputMaxVerticalBlankCount = 0 ;
2016-08-09 12:22:46 +02:00
_savedScreenForOpenEntranceDoors = nullptr ;
2016-07-20 16:42:37 +02:00
for ( uint16 i = 0 ; i < 10 ; + + i )
2016-08-23 23:36:18 +02:00
_entranceDoorAnimSteps [ i ] = nullptr ;
_interfaceCredits = nullptr ;
2016-04-26 14:44:01 +02:00
debug ( " DMEngine::DMEngine " ) ;
2016-08-18 19:18:14 +02:00
_saveThumbnail = nullptr ;
2016-08-19 11:49:29 +02:00
_canLoadFromGMM = false ;
_loadSaveSlotAtRuntime = - 1 ;
2016-04-26 14:44:01 +02:00
}
DMEngine : : ~ DMEngine ( ) {
debug ( " DMEngine::~DMEngine " ) ;
// dispose of resources
delete _rnd ;
2016-05-02 20:58:55 +02:00
delete _console ;
delete _displayMan ;
2016-05-03 17:55:04 +02:00
delete _dungeonMan ;
2016-06-15 10:41:33 +02:00
delete _eventMan ;
2016-06-17 14:29:05 +02:00
delete _menuMan ;
2016-06-18 11:36:31 +02:00
delete _championMan ;
2016-06-19 00:54:28 +02:00
delete _objectMan ;
2016-06-19 16:17:28 +02:00
delete _inventoryMan ;
2016-06-22 20:32:30 +02:00
delete _textMan ;
2016-07-25 16:13:53 +02:00
delete _moveSens ;
2016-08-26 22:41:19 +02:00
delete _groupMan ;
2016-06-30 19:59:35 +02:00
delete _timeline ;
2016-07-07 00:46:51 +02:00
delete _projexpl ;
2016-07-25 16:27:24 +02:00
delete _dialog ;
2016-08-16 19:15:35 +02:00
delete _sound ;
2016-04-26 14:44:01 +02:00
2016-08-18 19:18:14 +02:00
delete _saveThumbnail ;
2016-08-01 15:24:47 +02:00
2016-08-09 12:22:46 +02:00
delete [ ] _savedScreenForOpenEntranceDoors ;
2016-04-26 14:44:01 +02:00
// clear debug channels
DebugMan . clearAllDebugChannels ( ) ;
}
2016-07-20 16:42:37 +02:00
bool DMEngine : : hasFeature ( EngineFeature f ) const {
return
( f = = kSupportsSavingDuringRuntime ) | |
( f = = kSupportsLoadingDuringRuntime ) ;
}
2016-08-19 11:49:29 +02:00
Common : : Error DMEngine : : loadGameState ( int slot ) {
2016-08-23 23:36:18 +02:00
if ( loadgame ( slot ) ! = kM1_LoadgameFailure ) {
2016-08-19 11:49:29 +02:00
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _palDungeonView [ 0 ] ) ;
2016-08-23 23:36:18 +02:00
_newGameFl = k0_modeLoadSavedGame ;
2016-08-19 11:49:29 +02:00
2016-08-23 23:36:18 +02:00
startGame ( ) ;
_restartGameRequest = false ;
2016-08-25 08:12:23 +02:00
_eventMan - > hideMouse ( ) ;
_eventMan - > discardAllInput ( ) ;
2016-08-19 11:49:29 +02:00
return Common : : kNoError ;
}
return Common : : kNoGameDataFoundError ;
}
bool DMEngine : : canLoadGameStateCurrently ( ) {
return _canLoadFromGMM ;
}
2016-08-23 23:36:18 +02:00
void DMEngine : : delay ( uint16 verticalBlank ) {
2016-08-11 12:10:43 +02:00
for ( uint16 i = 0 ; i < verticalBlank * 2 ; + + i ) {
2016-08-12 13:04:45 +02:00
_eventMan - > processInput ( ) ;
2016-08-11 12:10:43 +02:00
_displayMan - > updateScreen ( ) ;
_system - > delayMillis ( 10 ) ; // Google says most Amiga games had a refreshrate of 50 hz
}
2016-07-07 00:46:51 +02:00
}
2016-08-23 23:36:18 +02:00
uint16 DMEngine : : getScaledProduct ( uint16 val , uint16 scale , uint16 vale2 ) {
2016-07-07 00:46:51 +02:00
return ( ( uint32 ) val * vale2 ) > > scale ;
}
2016-08-23 23:36:18 +02:00
void DMEngine : : initializeGame ( ) {
initMemoryManager ( ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > loadGraphics ( ) ;
_displayMan - > initializeGraphicData ( ) ;
_displayMan - > loadFloorSet ( k0_FloorSetStone ) ;
_displayMan - > loadWallSet ( k0_WallSetStone ) ;
2016-08-09 13:46:12 +02:00
2016-08-25 22:38:03 +02:00
_sound - > loadSounds ( ) ; // @ F0506_AMIGA_AllocateData
2016-08-09 13:46:12 +02:00
2016-08-19 18:16:23 +02:00
if ( ! ConfMan . hasKey ( " save_slot " ) ) // skip drawing title if loading from launcher
2016-08-23 23:36:18 +02:00
drawTittle ( ) ;
2016-08-19 18:16:23 +02:00
2016-08-25 22:38:03 +02:00
_textMan - > initialize ( ) ;
2016-08-26 22:50:01 +02:00
_objectMan - > loadObjectNames ( ) ;
2016-06-18 17:18:01 +02:00
_eventMan - > initMouse ( ) ;
2016-08-18 17:50:56 +02:00
2016-08-18 21:12:36 +02:00
int16 saveSlot = - 1 ;
2016-07-29 22:27:43 +02:00
do {
2016-08-18 19:51:36 +02:00
// if loading from the launcher
2016-08-18 17:50:56 +02:00
if ( ConfMan . hasKey ( " save_slot " ) ) {
saveSlot = ConfMan . getInt ( " save_slot " ) ;
2016-08-18 19:51:36 +02:00
} else { // else show the entrance
2016-08-23 23:36:18 +02:00
processEntrance ( ) ;
2016-08-18 17:50:56 +02:00
if ( _engineShouldQuit )
return ;
2016-08-18 21:12:36 +02:00
2016-08-23 23:36:18 +02:00
if ( _newGameFl = = k0_modeLoadSavedGame ) { // if resume was clicked, bring up ScummVM load screen
2016-08-18 21:12:36 +02:00
GUI : : SaveLoadChooser * dialog = new GUI : : SaveLoadChooser ( _ ( " Restore game: " ) , _ ( " Restore " ) , false ) ;
saveSlot = dialog - > runModalWithCurrentTarget ( ) ;
delete dialog ;
}
2016-08-18 19:51:36 +02:00
}
2016-08-23 23:36:18 +02:00
} while ( loadgame ( saveSlot ) ! = k1_LoadgameSuccess ) ;
2016-08-09 13:46:12 +02:00
2016-08-25 21:59:02 +02:00
_displayMan - > loadIntoBitmap ( k11_MenuSpellAreLinesIndice , _menuMan - > _bitmapSpellAreaLines ) ; // @ F0396_MENUS_LoadSpellAreaLinesBitmap
2016-06-18 17:18:01 +02:00
2016-07-02 17:46:05 +02:00
// There was some memory wizardy for the Amiga platform, I skipped that part
2016-08-25 18:32:03 +02:00
_displayMan - > allocateFlippedWallBitmaps ( ) ;
2016-07-02 17:46:05 +02:00
2016-08-23 23:36:18 +02:00
startGame ( ) ;
if ( _newGameFl )
2016-08-25 22:09:30 +02:00
_moveSens - > getMoveResult ( Thing : : _party , kM1_MapXNotOnASquare , 0 , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
_eventMan - > discardAllInput ( ) ;
2016-06-18 17:18:01 +02:00
}
2016-08-23 23:36:18 +02:00
void DMEngine : : initMemoryManager ( ) {
2016-08-15 07:58:04 +02:00
static uint16 palSwoosh [ 16 ] = { 0x000 , 0xFFF , 0xFFF , 0xFFF , 0xFFF , 0xFFF , 0xFFF , 0xFFF , 0x000 , 0xFFF , 0xAAA , 0xFFF , 0xAAA , 0x444 , 0xFF0 , 0xFF0 } ; // @ K0057_aui_Palette_Swoosh
2016-08-25 18:32:03 +02:00
_displayMan - > buildPaletteChangeCopperList ( palSwoosh , palSwoosh ) ;
2016-08-11 19:21:23 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i ) {
2016-08-25 18:32:03 +02:00
_displayMan - > _paletteTopAndBottomScreen [ i ] = _displayMan - > _palDungeonView [ 0 ] [ i ] ;
_displayMan - > _paletteMiddleScreen [ i ] = _displayMan - > _palDungeonView [ 0 ] [ i ] ;
2016-08-11 19:21:23 +02:00
}
2016-07-04 14:22:17 +02:00
}
2016-06-18 17:18:01 +02:00
2016-08-23 23:36:18 +02:00
void DMEngine : : startGame ( ) {
2016-07-30 10:26:23 +02:00
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-23 23:36:18 +02:00
_pressingEye = false ;
_stopPressingEye = false ;
_pressingMouth = false ;
_stopPressingMouth = false ;
_highlightBoxInversionRequested = false ;
2016-08-25 08:12:23 +02:00
_eventMan - > _highlightBoxEnabled = false ;
2016-08-23 07:54:16 +02:00
_championMan - > _partyIsSleeping = false ;
2016-08-23 23:36:18 +02:00
_championMan - > _actingChampionOrdinal = indexToOrdinal ( kM1_ChampionNone ) ;
2016-08-25 21:59:02 +02:00
_menuMan - > _actionAreaContainsIcons = true ;
2016-08-25 08:12:23 +02:00
_eventMan - > _useChampionIconOrdinalAsMousePointerBitmap = indexToOrdinal ( kM1_ChampionNone ) ;
2016-06-18 19:42:05 +02:00
2016-08-25 08:12:23 +02:00
_eventMan - > _primaryMouseInput = _eventMan - > _primaryMouseInputInterface ;
_eventMan - > _secondaryMouseInput = _eventMan - > _secondaryMouseInputMovement ;
_eventMan - > _primaryKeyboardInput = _eventMan - > _primaryKeyboardInputInterface ;
_eventMan - > _secondaryKeyboardInput = _eventMan - > _secondaryKeyboardInputMovement ;
2016-06-18 19:42:05 +02:00
2016-08-24 08:03:55 +02:00
processNewPartyMap ( _dungeonMan - > _partyMapIndex ) ;
2016-06-18 17:18:01 +02:00
2016-08-23 23:36:18 +02:00
if ( ! _newGameFl ) {
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _paletteTopAndBottomScreen ) ;
_displayMan - > _useByteBoxCoordinates = false ;
2016-08-23 23:36:18 +02:00
delay ( 1 ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > fillScreenBox ( boxScreenTop , k0_ColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenRight , k0_ColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenBottom , k0_ColorBlack ) ;
2016-06-19 00:49:23 +02:00
} else {
2016-08-25 18:32:03 +02:00
_displayMan - > _useByteBoxCoordinates = false ;
_displayMan - > fillScreenBox ( boxScreenTop , k0_ColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenRight , k0_ColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenBottom , k0_ColorBlack ) ;
2016-06-18 19:42:05 +02:00
}
2016-06-18 17:18:01 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > buildPaletteChangeCopperList ( _displayMan - > _palDungeonView [ 0 ] , _displayMan - > _paletteTopAndBottomScreen ) ;
2016-08-25 21:59:02 +02:00
_menuMan - > drawMovementArrows ( ) ;
2016-08-23 07:54:16 +02:00
_championMan - > resetDataToStartGame ( ) ;
2016-08-23 23:36:18 +02:00
_gameTimeTicking = true ;
2016-06-18 17:18:01 +02:00
}
2016-05-03 17:55:04 +02:00
2016-08-23 23:36:18 +02:00
void DMEngine : : processNewPartyMap ( uint16 mapIndex ) {
2016-08-25 21:17:48 +02:00
_groupMan - > removeAllActiveGroups ( ) ;
2016-08-24 08:03:55 +02:00
_dungeonMan - > setCurrentMapAndPartyMap ( mapIndex ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > loadCurrentMapGraphics ( ) ;
2016-08-25 21:17:48 +02:00
_groupMan - > addAllActiveGroups ( ) ;
2016-08-25 21:25:18 +02:00
_inventoryMan - > setDungeonViewPalette ( ) ;
2016-06-18 19:58:19 +02:00
}
2016-04-26 14:44:01 +02:00
Common : : Error DMEngine : : run ( ) {
2016-08-23 23:36:18 +02:00
initConstants ( ) ;
2016-06-29 23:17:04 +02:00
2016-06-18 17:18:01 +02:00
// scummvm/engine specific
2016-04-26 14:44:01 +02:00
initGraphics ( 320 , 200 , false ) ;
_console = new Console ( this ) ;
2016-05-02 20:58:55 +02:00
_displayMan = new DisplayMan ( this ) ;
2016-05-03 17:55:04 +02:00
_dungeonMan = new DungeonMan ( this ) ;
2016-06-15 10:41:33 +02:00
_eventMan = new EventManager ( this ) ;
2016-06-17 14:29:05 +02:00
_menuMan = new MenuMan ( this ) ;
2016-06-18 11:36:31 +02:00
_championMan = new ChampionMan ( this ) ;
2016-06-19 00:54:28 +02:00
_objectMan = new ObjectMan ( this ) ;
2016-06-19 16:17:28 +02:00
_inventoryMan = new InventoryMan ( this ) ;
2016-06-22 20:32:30 +02:00
_textMan = new TextMan ( this ) ;
2016-07-25 16:13:53 +02:00
_moveSens = new MovesensMan ( this ) ;
2016-08-26 22:41:19 +02:00
_groupMan = new GroupMan ( this ) ;
2016-06-30 19:59:35 +02:00
_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 ) ;
2016-08-16 19:38:52 +02:00
_sound = SoundMan : : getSoundMan ( this , _gameVersion ) ;
2016-05-15 17:52:39 +02:00
_displayMan - > setUpScreens ( 320 , 200 ) ;
2016-08-23 23:36:18 +02:00
initializeGame ( ) ;
2016-06-18 17:18:01 +02:00
while ( true ) {
2016-08-23 23:36:18 +02:00
gameloop ( ) ;
2016-08-19 11:49:29 +02:00
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return Common : : kNoError ;
2016-08-19 11:49:29 +02:00
if ( _loadSaveSlotAtRuntime = = - 1 )
2016-08-23 23:36:18 +02:00
endGame ( _championMan - > _partyDead ) ;
2016-08-19 11:49:29 +02:00
else {
loadGameState ( _loadSaveSlotAtRuntime ) ;
2016-08-25 21:59:02 +02:00
_menuMan - > drawEnabledMenus ( ) ;
2016-08-19 11:49:29 +02:00
_displayMan - > updateScreen ( ) ;
_loadSaveSlotAtRuntime = - 1 ;
}
2016-06-18 17:18:01 +02:00
}
2016-06-16 23:48:18 +02:00
2016-06-18 17:18:01 +02:00
return Common : : kNoError ;
}
2016-06-16 23:48:18 +02:00
2016-08-23 23:36:18 +02:00
void DMEngine : : gameloop ( ) {
2016-08-19 11:49:29 +02:00
_canLoadFromGMM = true ;
2016-08-23 23:36:18 +02:00
_waitForInputMaxVerticalBlankCount = 10 ;
2016-05-02 20:58:55 +02:00
while ( true ) {
2016-08-19 11:49:29 +02:00
if ( _engineShouldQuit ) {
_canLoadFromGMM = false ;
2016-07-29 22:27:43 +02:00
return ;
2016-08-19 11:49:29 +02:00
}
2016-08-10 14:44:54 +02:00
2016-08-26 22:51:17 +02:00
// DEBUG CODE
2016-08-23 07:54:16 +02:00
for ( int16 i = 0 ; i < _championMan - > _partyChampionCount ; + + i ) {
Champion & champ = _championMan - > _champions [ i ] ;
2016-08-26 22:51:17 +02:00
if ( _console - > _debugGodmodeHP )
champ . _currHealth = champ . _maxHealth ;
if ( _console - > _debugGodmodeMana )
champ . _currMana = champ . _maxMana ;
if ( _console - > _debugGodmodeStamina )
champ . _currStamina = champ . _maxStamina ;
}
2016-08-26 22:50:01 +02:00
2016-07-30 10:37:29 +02:00
for ( ; ; ) {
2016-08-10 14:44:54 +02:00
2016-08-26 22:51:17 +02:00
2016-08-23 23:36:18 +02:00
if ( _newPartyMapIndex ! = kM1_mapIndexNone ) {
processNewPartyMap ( _newPartyMapIndex ) ;
2016-08-25 22:09:30 +02:00
_moveSens - > getMoveResult ( Thing : : _party , kM1_MapXNotOnASquare , 0 , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY ) ;
2016-08-23 23:36:18 +02:00
_newPartyMapIndex = kM1_mapIndexNone ;
2016-08-25 08:12:23 +02:00
_eventMan - > discardAllInput ( ) ;
2016-07-30 10:37:29 +02:00
}
2016-08-25 22:38:03 +02:00
_timeline - > processTimeline ( ) ;
2016-07-30 10:37:29 +02:00
2016-08-23 23:36:18 +02:00
if ( _newPartyMapIndex = = kM1_mapIndexNone )
2016-07-30 10:37:29 +02:00
break ;
}
2016-08-26 22:50:01 +02:00
2016-08-25 21:25:18 +02:00
if ( ! _inventoryMan - > _inventoryChampionOrdinal & & ! _championMan - > _partyIsSleeping ) {
2016-08-26 22:50:13 +02:00
Box box ( 0 , 223 , 0 , 135 ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > fillBoxBitmap ( _displayMan - > _bitmapViewport , box , k0_ColorBlack , k112_byteWidthViewport , k136_heightViewport ) ; // (possibly dummy code)
_displayMan - > drawDungeon ( _dungeonMan - > _partyDir , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY ) ;
2016-08-23 23:36:18 +02:00
if ( _setMousePointerToObjectInMainLoop ) {
_setMousePointerToObjectInMainLoop = false ;
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
2016-08-25 22:19:34 +02:00
_eventMan - > setPointerToObject ( _objectMan - > _objectIconForMousePointer ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > hideMouse ( ) ;
2016-07-11 11:37:01 +02:00
2016-08-26 22:50:13 +02:00
}
2016-08-25 08:12:23 +02:00
if ( _eventMan - > _refreshMousePointerInMainLoop ) {
_eventMan - > _refreshMousePointerInMainLoop = false ;
_eventMan - > _mousePointerBitmapUpdated = true ;
_eventMan - > showMouse ( ) ;
_eventMan - > hideMouse ( ) ;
2016-08-26 22:50:13 +02:00
}
}
2016-08-25 08:12:23 +02:00
_eventMan - > highlightBoxDisable ( ) ;
2016-08-25 22:38:03 +02:00
_sound - > playPendingSound ( ) ;
2016-08-23 07:54:16 +02:00
_championMan - > applyAndDrawPendingDamageAndWounds ( ) ;
if ( _championMan - > _partyDead )
2016-08-26 22:50:01 +02:00
break ;
2016-07-30 11:20:47 +02:00
2016-08-23 23:36:18 +02:00
_gameTime + + ;
2016-08-26 22:50:01 +02:00
2016-08-23 23:36:18 +02:00
if ( ! ( _gameTime & 511 ) )
2016-08-25 21:25:18 +02:00
_inventoryMan - > decreaseTorchesLightPower ( ) ;
2016-07-12 08:53:34 +02:00
2016-08-23 07:54:16 +02:00
if ( _championMan - > _party . _freezeLifeTicks )
_championMan - > _party . _freezeLifeTicks - = 1 ;
2016-07-12 08:53:34 +02:00
2016-08-25 21:59:02 +02:00
_menuMan - > refreshActionAreaAndSetChampDirMaxDamageReceived ( ) ;
2016-08-26 22:38:51 +02:00
2016-08-23 23:36:18 +02:00
if ( ! ( _gameTime & ( _championMan - > _partyIsSleeping ? 15 : 63 ) ) )
2016-08-23 07:54:16 +02:00
_championMan - > applyTimeEffects ( ) ;
2016-07-12 08:53:34 +02:00
2016-08-23 23:36:18 +02:00
if ( _disabledMovementTicks )
_disabledMovementTicks - - ;
2016-07-12 08:53:34 +02:00
2016-08-23 23:36:18 +02:00
if ( _projectileDisableMovementTicks )
_projectileDisableMovementTicks - - ;
2016-07-07 00:46:51 +02:00
2016-08-25 22:38:03 +02:00
_textMan - > clearExpiredRows ( ) ;
2016-08-23 23:36:18 +02:00
_stopWaitingForPlayerInput = false ;
2016-07-13 19:12:55 +02:00
uint16 vblankCounter = 0 ;
2016-07-11 14:55:56 +02:00
do {
_eventMan - > processInput ( ) ;
2016-08-23 23:36:18 +02:00
if ( _stopPressingEye ) {
_pressingEye = false ;
_stopPressingEye = false ;
2016-08-25 21:25:18 +02:00
_inventoryMan - > drawStopPressingEye ( ) ;
2016-08-23 23:36:18 +02:00
} else if ( _stopPressingMouth ) {
_pressingMouth = false ;
_stopPressingMouth = false ;
2016-08-25 21:25:18 +02:00
_inventoryMan - > drawStopPressingMouth ( ) ;
2016-07-11 14:55:56 +02:00
}
2016-08-25 08:12:23 +02:00
_eventMan - > processCommandQueue ( ) ;
2016-08-19 11:49:29 +02:00
if ( _engineShouldQuit | | _loadSaveSlotAtRuntime ! = - 1 ) {
_canLoadFromGMM = false ;
2016-07-29 22:27:43 +02:00
return ;
2016-08-19 11:49:29 +02:00
}
2016-07-11 14:55:56 +02:00
_displayMan - > updateScreen ( ) ;
2016-08-23 23:36:18 +02:00
if ( ! _stopWaitingForPlayerInput ) {
2016-08-25 08:12:23 +02:00
_eventMan - > highlightBoxDisable ( ) ;
2016-08-09 08:40:29 +02:00
}
2016-07-02 23:10:05 +02:00
2016-07-13 19:12:55 +02:00
_system - > delayMillis ( 2 ) ;
2016-08-23 23:36:18 +02:00
if ( + + vblankCounter > = _waitForInputMaxVerticalBlankCount * 4 )
_stopWaitingForPlayerInput = true ;
2016-07-13 19:12:55 +02:00
2016-08-23 23:36:18 +02:00
} while ( ! _stopWaitingForPlayerInput | | ! _gameTimeTicking ) ;
2016-05-02 20:58:55 +02:00
}
2016-08-19 11:49:29 +02:00
_canLoadFromGMM = false ;
2016-06-16 23:48:18 +02:00
}
2016-08-23 23:36:18 +02:00
int16 DMEngine : : ordinalToIndex ( int16 val ) {
2016-06-23 23:12:39 +02:00
return val - 1 ;
}
2016-08-23 23:36:18 +02:00
int16 DMEngine : : indexToOrdinal ( int16 val ) {
2016-06-23 23:12:39 +02:00
return val + 1 ;
}
2016-08-23 23:36:18 +02:00
void DMEngine : : processEntrance ( ) {
2016-08-25 08:12:23 +02:00
_eventMan - > _primaryMouseInput = _eventMan - > _primaryMouseInputEntrance ;
_eventMan - > _secondaryMouseInput = nullptr ;
_eventMan - > _primaryKeyboardInput = nullptr ;
_eventMan - > _secondaryKeyboardInput = nullptr ;
2016-08-23 23:36:18 +02:00
_entranceDoorAnimSteps [ 0 ] = new byte [ 128 * 161 * 12 ] ;
2016-07-30 10:26:23 +02:00
for ( uint16 idx = 1 ; idx < 8 ; idx + + )
2016-08-23 23:36:18 +02:00
_entranceDoorAnimSteps [ idx ] = _entranceDoorAnimSteps [ idx - 1 ] + 128 * 161 ;
2016-07-30 10:26:23 +02:00
2016-08-23 23:36:18 +02:00
_entranceDoorAnimSteps [ 8 ] = _entranceDoorAnimSteps [ 7 ] + 128 * 161 ;
_entranceDoorAnimSteps [ 9 ] = _entranceDoorAnimSteps [ 8 ] + 128 * 161 * 2 ;
2016-07-20 16:42:37 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > loadIntoBitmap ( k3_entranceRightDoorGraphicIndice , _entranceDoorAnimSteps [ 4 ] ) ;
_displayMan - > loadIntoBitmap ( k2_entranceLeftDoorGraphicIndice , _entranceDoorAnimSteps [ 0 ] ) ;
_interfaceCredits = _displayMan - > getNativeBitmapOrGraphic ( k5_creditsGraphicIndice ) ;
_displayMan - > _useByteBoxCoordinates = false ;
2016-08-26 19:12:17 +02:00
Box displayBox ( 0 , 100 , 0 , 160 ) ;
2016-07-30 10:26:23 +02:00
for ( uint16 idx = 1 ; idx < 4 ; idx + + ) {
2016-08-25 18:32:03 +02:00
_displayMan - > blitToBitmap ( _entranceDoorAnimSteps [ 0 ] , _entranceDoorAnimSteps [ idx ] , displayBox , idx < < 2 , 0 , k64_byteWidth , k64_byteWidth , kM1_ColorNoTransparency , 161 , 161 ) ;
2016-07-30 10:26:23 +02:00
displayBox . _x2 - = 4 ;
2016-07-20 16:42:37 +02:00
}
2016-07-30 10:26:23 +02:00
displayBox . _x2 = 127 ;
for ( uint16 idx = 5 ; idx < 8 ; idx + + ) {
displayBox . _x1 + = 4 ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToBitmap ( _entranceDoorAnimSteps [ 4 ] , _entranceDoorAnimSteps [ idx ] , displayBox , 0 , 0 , k64_byteWidth , k64_byteWidth , kM1_ColorNoTransparency , 161 , 161 ) ;
2016-07-20 16:42:37 +02:00
}
2016-07-30 10:26:23 +02:00
2016-07-20 16:42:37 +02:00
do {
2016-08-23 23:36:18 +02:00
drawEntrance ( ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
_eventMan - > discardAllInput ( ) ;
2016-08-23 23:36:18 +02:00
_newGameFl = k99_modeWaitingOnEntrance ;
2016-07-20 16:42:37 +02:00
do {
_eventMan - > processInput ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
2016-08-25 08:12:23 +02:00
_eventMan - > processCommandQueue ( ) ;
2016-07-20 16:42:37 +02:00
_displayMan - > updateScreen ( ) ;
2016-08-23 23:36:18 +02:00
} while ( _newGameFl = = k99_modeWaitingOnEntrance ) ;
} while ( _newGameFl = = k202_CommandEntranceDrawCredits ) ;
2016-07-30 11:20:47 +02:00
2016-07-20 16:42:37 +02:00
//Strangerke: CHECKME: Earlier versions were using G0566_puc_Graphic534_Sound01Switch
2016-08-25 22:38:03 +02:00
_sound - > play ( k01_soundSWITCH , 112 , 0x40 , 0x40 ) ;
2016-08-23 23:36:18 +02:00
delay ( 20 ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
2016-08-23 23:36:18 +02:00
if ( _newGameFl )
openEntranceDoors ( ) ;
2016-07-30 10:26:23 +02:00
2016-08-23 23:36:18 +02:00
delete [ ] _entranceDoorAnimSteps [ 0 ] ;
2016-07-20 16:42:37 +02:00
for ( uint16 i = 0 ; i < 10 ; + + i )
2016-08-23 23:36:18 +02:00
_entranceDoorAnimSteps [ i ] = nullptr ;
2016-07-20 16:42:37 +02:00
}
2016-08-23 23:36:18 +02:00
void DMEngine : : endGame ( bool doNotDrawCreditsOnly ) {
2016-08-15 23:26:43 +02:00
static Box boxEndgameRestartOuterEN ( 103 , 217 , 145 , 159 ) ;
static Box boxEndgameRestartInnerEN ( 105 , 215 , 147 , 157 ) ;
2016-08-15 20:25:40 +02:00
2016-08-15 23:26:43 +02:00
static Box boxEndgameRestartOuterDE ( 82 , 238 , 145 , 159 ) ;
static Box boxEndgameRestartInnerDE ( 84 , 236 , 147 , 157 ) ;
2016-08-15 20:25:40 +02:00
2016-08-15 23:26:43 +02:00
static Box boxEndgameRestartOuterFR ( 100 , 220 , 145 , 159 ) ;
static Box boxEndgameRestartInnerFR ( 102 , 218 , 147 , 157 ) ;
2016-08-15 20:25:40 +02:00
Box restartOuterBox ;
Box restartInnerBox ;
switch ( getGameLanguage ( ) ) { // localized
default :
case Common : : EN_ANY :
2016-08-15 23:26:43 +02:00
restartOuterBox = boxEndgameRestartOuterEN ;
restartInnerBox = boxEndgameRestartInnerEN ;
2016-08-15 20:25:40 +02:00
break ;
2016-08-16 09:28:57 +02:00
case Common : : DE_DEU :
2016-08-15 23:26:43 +02:00
restartOuterBox = boxEndgameRestartOuterDE ;
restartInnerBox = boxEndgameRestartInnerDE ;
2016-08-15 20:25:40 +02:00
break ;
case Common : : FR_FRA :
2016-08-15 23:26:43 +02:00
restartOuterBox = boxEndgameRestartOuterFR ;
restartInnerBox = boxEndgameRestartInnerFR ;
2016-08-15 20:25:40 +02:00
break ;
}
2016-08-15 23:26:43 +02:00
static Box theEndBox ( 120 , 199 , 95 , 108 ) ;
static Box championMirrorBox ( 11 , 74 , 7 , 49 ) ;
static Box championPortraitBox ( 27 , 58 , 13 , 41 ) ;
2016-07-30 11:20:47 +02:00
bool waitBeforeDrawingRestart = true ;
2016-07-29 22:27:43 +02:00
2016-08-25 08:12:23 +02:00
_eventMan - > setMousePointerToNormal ( k0_pointerArrow ) ;
_eventMan - > showMouse ( ) ;
_eventMan - > _primaryMouseInput = nullptr ;
_eventMan - > _secondaryMouseInput = nullptr ;
_eventMan - > _primaryKeyboardInput = nullptr ;
_eventMan - > _secondaryKeyboardInput = nullptr ;
2016-08-23 23:36:18 +02:00
if ( doNotDrawCreditsOnly & & ! _gameWon ) {
2016-08-25 22:38:03 +02:00
_sound - > requestPlay ( k06_soundSCREAM , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY , k0_soundModePlayImmediately ) ;
2016-08-23 23:36:18 +02:00
delay ( 240 ) ;
2016-07-29 22:27:43 +02:00
}
2016-08-09 08:40:29 +02:00
2016-08-25 18:32:03 +02:00
if ( _displayMan - > _paletteSwitchingEnabled ) {
2016-07-30 11:20:47 +02:00
uint16 oldPalTopAndBottomScreen [ 16 ] ;
2016-07-29 22:27:43 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i )
2016-08-25 18:32:03 +02:00
oldPalTopAndBottomScreen [ i ] = _displayMan - > _paletteTopAndBottomScreen [ i ] ;
2016-07-30 11:20:47 +02:00
for ( int i = 0 ; i < = 7 ; i + + ) {
2016-08-23 23:36:18 +02:00
delay ( 1 ) ;
2016-07-30 11:20:47 +02:00
for ( int colIdx = 0 ; colIdx < 16 ; colIdx + + ) {
2016-08-25 18:32:03 +02:00
_displayMan - > _paletteMiddleScreen [ colIdx ] = _displayMan - > getDarkenedColor ( _displayMan - > _paletteMiddleScreen [ colIdx ] ) ;
_displayMan - > _paletteTopAndBottomScreen [ colIdx ] = _displayMan - > getDarkenedColor ( _displayMan - > _paletteTopAndBottomScreen [ colIdx ] ) ;
2016-07-29 22:27:43 +02:00
}
}
2016-08-25 18:32:03 +02:00
_displayMan - > _paletteSwitchingEnabled = false ;
2016-08-23 23:36:18 +02:00
delay ( 1 ) ;
2016-07-29 22:27:43 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i )
2016-08-25 18:32:03 +02:00
_displayMan - > _paletteTopAndBottomScreen [ i ] = oldPalTopAndBottomScreen [ i ] ;
2016-07-30 10:26:23 +02:00
} else
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _blankBuffer ) ;
2016-07-30 10:26:23 +02:00
2016-07-30 11:20:47 +02:00
uint16 darkBluePalette [ 16 ] ;
2016-07-29 22:27:43 +02:00
if ( doNotDrawCreditsOnly ) {
2016-08-23 23:36:18 +02:00
if ( _gameWon ) {
2016-07-29 22:27:43 +02:00
// Strangerke: Related to portraits. Game data could be missing for earlier versions of the game.
_displayMan - > fillScreen ( k12_ColorDarkestGray ) ;
2016-08-23 07:54:16 +02:00
for ( int16 championIndex = k0_ChampionFirst ; championIndex < _championMan - > _partyChampionCount ; championIndex + + ) {
2016-07-30 11:20:47 +02:00
int16 textPosY = championIndex * 48 ;
2016-08-23 07:54:16 +02:00
Champion * curChampion = & _championMan - > _champions [ championIndex ] ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( k208_wallOrn_43_champMirror ) , & championMirrorBox , k32_byteWidth , k10_ColorFlesh , 43 ) ;
_displayMan - > blitToScreen ( curChampion - > _portrait , & championPortraitBox , k16_byteWidth , k1_ColorDarkGary , 29 ) ;
2016-08-25 22:38:03 +02:00
_textMan - > printEndGameString ( 87 , textPosY + = 14 , k9_ColorGold , curChampion - > _name ) ;
2016-07-30 11:20:47 +02:00
int textPosX = ( 6 * strlen ( curChampion - > _name ) ) + 87 ;
char championTitleFirstCharacter = curChampion - > _title [ 0 ] ;
if ( ( championTitleFirstCharacter ! = ' , ' ) & & ( championTitleFirstCharacter ! = ' ; ' ) & & ( championTitleFirstCharacter ! = ' - ' ) )
textPosX + = 6 ;
2016-08-25 22:38:03 +02:00
_textMan - > printEndGameString ( textPosX , textPosY + + , k9_ColorGold , curChampion - > _title ) ;
2016-07-30 11:20:47 +02:00
for ( int16 idx = k0_ChampionSkillFighter ; idx < = k3_ChampionSkillWizard ; idx + + ) {
2016-08-23 07:54:16 +02:00
uint16 skillLevel = MIN < uint16 > ( 16 , _championMan - > getSkillLevel ( championIndex , idx | ( k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience ) ) ) ;
2016-07-30 11:20:47 +02:00
if ( skillLevel = = 1 )
2016-07-29 22:27:43 +02:00
continue ;
2016-07-30 11:20:47 +02:00
char displStr [ 20 ] ;
2016-08-25 21:25:18 +02:00
strcpy ( displStr , _inventoryMan - > _skillLevelNames [ skillLevel - 2 ] ) ;
2016-07-30 11:20:47 +02:00
strcat ( displStr , " " ) ;
2016-08-21 14:25:06 +02:00
strcat ( displStr , _championMan - > _baseSkillName [ idx ] ) ;
2016-08-25 22:38:03 +02:00
_textMan - > printEndGameString ( 105 , textPosY = textPosY + 8 , k13_ColorLightestGray , displStr ) ;
2016-07-29 22:27:43 +02:00
}
2016-07-30 11:20:47 +02:00
championMirrorBox . _y1 + = 48 ;
championMirrorBox . _y2 + = 48 ;
championPortraitBox . _y1 + = 48 ;
championPortraitBox . _y1 + = 48 ;
2016-07-29 22:27:43 +02:00
}
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _paletteTopAndBottomScreen ) ;
2016-07-29 22:27:43 +02:00
_engineShouldQuit = true ;
return ;
}
T0444017 :
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( k6_theEndIndice ) , & theEndBox , k40_byteWidth , kM1_ColorNoTransparency , 14 ) ;
2016-07-29 22:27:43 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i )
2016-07-30 11:20:47 +02:00
darkBluePalette [ i ] = D01_RGB_DARK_BLUE ;
uint16 curPalette [ 16 ] ;
for ( uint16 i = 0 ; i < 15 ; + + i )
curPalette [ i ] = darkBluePalette [ i ] ;
curPalette [ 15 ] = D09_RGB_WHITE ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( curPalette ) ;
2016-08-11 12:10:43 +02:00
_displayMan - > updateScreen ( ) ;
2016-07-30 11:20:47 +02:00
if ( waitBeforeDrawingRestart )
2016-08-23 23:36:18 +02:00
delay ( 300 ) ;
2016-07-29 22:27:43 +02:00
2016-08-23 23:36:18 +02:00
if ( _restartGameAllowed ) {
2016-08-25 18:32:03 +02:00
_displayMan - > _useByteBoxCoordinates = false ;
_displayMan - > fillScreenBox ( restartOuterBox , k12_ColorDarkestGray ) ;
_displayMan - > fillScreenBox ( restartInnerBox , k0_ColorBlack ) ;
2016-08-15 20:25:40 +02:00
switch ( getGameLanguage ( ) ) { // localized
default :
2016-08-26 19:12:17 +02:00
case Common : : EN_ANY :
_textMan - > printToLogicalScreen ( 110 , 154 , k4_ColorCyan , k0_ColorBlack , " RESTART THIS GAME " ) ;
break ;
case Common : : DE_DEU :
_textMan - > printToLogicalScreen ( 110 , 154 , k4_ColorCyan , k0_ColorBlack , " DIESES SPIEL NEU STARTEN " ) ;
break ;
case Common : : FR_FRA :
_textMan - > printToLogicalScreen ( 110 , 154 , k4_ColorCyan , k0_ColorBlack , " RECOMMENCER CE JEU " ) ;
break ;
2016-08-15 20:25:40 +02:00
}
2016-07-30 11:20:47 +02:00
curPalette [ 1 ] = D03_RGB_PINK ;
curPalette [ 4 ] = D09_RGB_WHITE ;
2016-08-25 08:12:23 +02:00
_eventMan - > _primaryMouseInput = _eventMan - > _primaryMouseInputRestartGame ;
_eventMan - > discardAllInput ( ) ;
_eventMan - > hideMouse ( ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( curPalette ) ;
2016-08-23 23:36:18 +02:00
for ( int16 verticalBlankCount = 900 ; - - verticalBlankCount & & ! _restartGameRequest ; delay ( 1 ) )
2016-08-25 08:12:23 +02:00
_eventMan - > processCommandQueue ( ) ;
2016-07-30 11:20:47 +02:00
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
2016-08-23 23:36:18 +02:00
if ( _restartGameRequest ) {
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( darkBluePalette ) ;
2016-07-29 22:27:43 +02:00
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _palDungeonView [ 0 ] ) ;
2016-08-23 23:36:18 +02:00
_newGameFl = k0_modeLoadSavedGame ;
if ( loadgame ( 1 ) ! = kM1_LoadgameFailure ) {
startGame ( ) ;
_restartGameRequest = false ;
2016-08-25 08:12:23 +02:00
_eventMan - > hideMouse ( ) ;
_eventMan - > discardAllInput ( ) ;
2016-07-29 22:27:43 +02:00
return ;
}
}
}
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( darkBluePalette ) ;
2016-07-29 22:27:43 +02:00
}
2016-07-30 10:26:23 +02:00
Box box ( 0 , 319 , 0 , 199 ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( k5_creditsGraphicIndice ) , & box , k160_byteWidthScreen , kM1_ColorNoTransparency , k200_heightScreen ) ;
2016-07-30 10:26:23 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _palCredits ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > waitForMouseOrKeyActivity ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
2016-08-23 23:36:18 +02:00
if ( _restartGameAllowed & & doNotDrawCreditsOnly ) {
2016-07-30 11:20:47 +02:00
waitBeforeDrawingRestart = false ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( darkBluePalette ) ;
2016-07-29 22:27:43 +02:00
goto T0444017 ;
}
_engineShouldQuit = true ;
return ;
}
2016-08-23 23:36:18 +02:00
void DMEngine : : drawEntrance ( ) {
2016-07-31 21:48:37 +02:00
static Box doorsUpperHalfBox = Box ( 0 , 231 , 0 , 80 ) ;
static Box doorsLowerHalfBox = Box ( 0 , 231 , 81 , 160 ) ;
static Box closedDoorLeftBox = Box ( 0 , 104 , 30 , 190 ) ;
static Box closedDoorRightBox = Box ( 105 , 231 , 30 , 190 ) ;
2016-08-15 07:58:04 +02:00
/* Atari ST: { 0x000, 0x333, 0x444, 0x420, 0x654, 0x210, 0x040, 0x050, 0x432, 0x700, 0x543, 0x321, 0x222, 0x555, 0x310, 0x777 }, RGB colors are different */
static uint16 palEntrance [ 16 ] = { 0x000 , 0x666 , 0x888 , 0x840 , 0xCA8 , 0x0C0 , 0x080 , 0x0A0 , 0x864 , 0xF00 , 0xA86 , 0x642 , 0x444 , 0xAAA , 0x620 , 0xFFF } ; // @ G0020_aui_Graphic562_Palette_Entrance
2016-07-20 16:42:37 +02:00
2016-07-31 21:48:37 +02:00
byte * microDungeonCurrentMapData [ 32 ] ;
2016-07-20 16:42:37 +02:00
2016-08-24 08:03:55 +02:00
_dungeonMan - > _partyMapIndex = k255_mapIndexEntrance ;
2016-08-25 18:32:03 +02:00
_displayMan - > _drawFloorAndCeilingRequested = true ;
2016-08-24 08:03:55 +02:00
_dungeonMan - > _currMapWidth = 5 ;
_dungeonMan - > _currMapHeight = 5 ;
_dungeonMan - > _currMapData = microDungeonCurrentMapData ;
2016-07-20 16:42:37 +02:00
Map map ; // uninitialized, won't be used
2016-08-24 08:03:55 +02:00
_dungeonMan - > _currMap = & map ;
2016-07-31 21:48:37 +02:00
Square microDungeonSquares [ 25 ] ;
2016-07-20 16:42:37 +02:00
for ( uint16 i = 0 ; i < 25 ; + + i )
2016-07-31 21:48:37 +02:00
microDungeonSquares [ i ] = Square ( k0_ElementTypeWall , 0 ) ;
for ( int16 idx = 0 ; idx < 5 ; idx + + ) {
microDungeonCurrentMapData [ idx ] = ( byte * ) & microDungeonSquares [ idx * 5 ] ;
microDungeonSquares [ idx + 10 ] = Square ( k1_CorridorElemType , 0 ) ;
2016-07-20 16:42:37 +02:00
}
2016-07-31 21:48:37 +02:00
microDungeonSquares [ 7 ] = Square ( k1_CorridorElemType , 0 ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _blankBuffer ) ;
2016-07-20 16:42:37 +02:00
// note, a global variable is used here in the original
2016-08-25 18:32:03 +02:00
_displayMan - > loadIntoBitmap ( k4_entranceGraphicIndice , _displayMan - > _bitmapScreen ) ;
_displayMan - > drawDungeon ( kDirSouth , 2 , 0 ) ;
2016-07-20 16:42:37 +02:00
2016-08-09 12:22:46 +02:00
if ( ! _savedScreenForOpenEntranceDoors )
_savedScreenForOpenEntranceDoors = new byte [ k200_heightScreen * k160_byteWidthScreen * 2 ] ;
2016-08-25 18:32:03 +02:00
memcpy ( _savedScreenForOpenEntranceDoors , _displayMan - > _bitmapScreen , 320 * 200 ) ;
2016-08-09 12:22:46 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > _useByteBoxCoordinates = false , _displayMan - > blitToBitmap ( _displayMan - > _bitmapScreen , _entranceDoorAnimSteps [ 8 ] , doorsUpperHalfBox , 0 , 30 , k160_byteWidthScreen , k128_byteWidth , kM1_ColorNoTransparency , 200 , 161 ) ;
_displayMan - > _useByteBoxCoordinates = false , _displayMan - > blitToBitmap ( _displayMan - > _bitmapScreen , _entranceDoorAnimSteps [ 8 ] , doorsLowerHalfBox , 0 , 111 , k160_byteWidthScreen , k128_byteWidth , kM1_ColorNoTransparency , 200 , 161 ) ;
2016-07-20 16:42:37 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > blitToScreen ( _entranceDoorAnimSteps [ 0 ] , & closedDoorLeftBox , k64_byteWidth , kM1_ColorNoTransparency , 161 ) ;
_displayMan - > blitToScreen ( _entranceDoorAnimSteps [ 4 ] , & closedDoorRightBox , k64_byteWidth , kM1_ColorNoTransparency , 161 ) ;
_displayMan - > startEndFadeToPalette ( palEntrance ) ;
2016-07-20 16:42:37 +02:00
}
2016-08-09 11:54:04 +02:00
2016-08-23 23:36:18 +02:00
void DMEngine : : openEntranceDoors ( ) {
2016-08-09 13:49:49 +02:00
Box rightDoorBox ( 109 , 231 , 30 , 193 ) ;
2016-08-25 18:32:03 +02:00
byte * rightDoorBitmap = _displayMan - > getNativeBitmapOrGraphic ( k3_entranceRightDoorGraphicIndice ) ;
2016-08-09 13:49:49 +02:00
Box leftDoorBox ( 0 , 100 , 30 , 193 ) ;
2016-08-09 11:54:04 +02:00
uint16 leftDoorBlitFrom = 0 ;
2016-08-25 18:32:03 +02:00
byte * leftDoorBitmap = _displayMan - > getNativeBitmapOrGraphic ( k2_entranceLeftDoorGraphicIndice ) ;
2016-08-09 11:54:04 +02:00
Box screenBox ( 0 , 319 , 0 , 199 ) ;
2016-08-09 12:22:46 +02:00
for ( uint16 animStep = 1 ; animStep < 32 ; + + animStep ) {
2016-08-09 11:54:04 +02:00
if ( ( animStep % 3 ) = = 1 ) {
// Strangerke: CHECKME: Earlier versions of the game were using G0565_puc_Graphic535_Sound02DoorRattle instead of k02_soundDOOR_RATTLE 2
2016-08-25 22:38:03 +02:00
_sound - > play ( k02_soundDOOR_RATTLE , 145 , 0x40 , 0x40 ) ;
2016-08-09 11:54:04 +02:00
}
2016-08-25 18:32:03 +02:00
_displayMan - > blitToScreen ( _savedScreenForOpenEntranceDoors , & screenBox , 160 , kM1_ColorNoTransparency , 200 ) ;
_displayMan - > blitToBitmap ( leftDoorBitmap , _displayMan - > _bitmapScreen , leftDoorBox , leftDoorBlitFrom , 0 , 64 , k160_byteWidthScreen ,
2016-08-12 14:55:35 +02:00
kM1_ColorNoTransparency , 161 , k200_heightScreen ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToBitmap ( rightDoorBitmap , _displayMan - > _bitmapScreen , rightDoorBox , 0 , 0 , 64 , k160_byteWidthScreen ,
2016-08-12 14:55:35 +02:00
kM1_ColorNoTransparency , 161 , k200_heightScreen ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > discardAllInput ( ) ;
2016-08-09 11:54:04 +02:00
_displayMan - > updateScreen ( ) ;
leftDoorBox . _x2 - = 4 ;
leftDoorBlitFrom + = 4 ;
rightDoorBox . _x1 + = 4 ;
2016-08-23 23:36:18 +02:00
delay ( 3 ) ;
2016-08-09 12:22:46 +02:00
}
delete [ ] _savedScreenForOpenEntranceDoors ;
2016-08-09 13:17:54 +02:00
_savedScreenForOpenEntranceDoors = nullptr ;
2016-08-09 11:54:04 +02:00
}
2016-08-23 23:36:18 +02:00
void DMEngine : : drawTittle ( ) {
2016-08-26 19:12:17 +02:00
static Box boxTitleStrikesBackDestination ( 0 , 319 , 118 , 174 ) ;
static Box boxTitleStrikesBackSource ( 0 , 319 , 0 , 56 ) ;
static Box boxTitlePresents ( 0 , 319 , 90 , 105 ) ;
static Box boxTitleDungeonChaos ( 0 , 319 , 0 , 79 ) ;
2016-08-19 18:16:23 +02:00
2016-08-25 18:32:03 +02:00
_displayMan - > _useByteBoxCoordinates = false ;
2016-08-19 18:16:23 +02:00
2016-08-26 19:12:17 +02:00
byte * allocatedMem = new byte [ 145600 * 2 ] ;
byte * titleSteps = allocatedMem ;
byte * bitmapTitle = titleSteps ;
_displayMan - > loadIntoBitmap ( k1_titleGraphicsIndice , titleSteps ) ;
2016-08-19 18:16:23 +02:00
2016-08-26 19:12:17 +02:00
titleSteps + = 320 * 200 ;
uint16 blitPalette [ 16 ] ;
2016-08-19 18:16:23 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i )
2016-08-26 19:12:17 +02:00
blitPalette [ i ] = D01_RGB_DARK_BLUE ;
2016-08-19 18:16:23 +02:00
2016-08-26 19:12:17 +02:00
_displayMan - > startEndFadeToPalette ( blitPalette ) ;
2016-08-19 18:16:23 +02:00
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-22 17:29:56 +02:00
// uncomment this to draw 'Presents'
//_displayMan->f132_blitToBitmap(L1384_puc_Bitmap_Title, _displayMan->_g348_bitmapScreen, G0005_s_Graphic562_Box_Title_Presents, 0, 137, k160_byteWidthScreen, k160_byteWidthScreen, kM1_ColorNoTransparency, k200_heightScreen, k200_heightScreen);
2016-08-26 19:12:17 +02:00
blitPalette [ 15 ] = D09_RGB_WHITE ;
_displayMan - > startEndFadeToPalette ( blitPalette ) ;
byte * masterStrikesBack = titleSteps ;
_displayMan - > blitToBitmap ( bitmapTitle , masterStrikesBack , boxTitleStrikesBackSource , 0 , 80 , k160_byteWidthScreen , k160_byteWidthScreen , kM1_ColorNoTransparency , 200 , 57 ) ;
titleSteps + = 320 * 57 ;
byte * bitmapDungeonChaos = titleSteps ; /* Unreferenced on Atari ST */
_displayMan - > blitToBitmap ( bitmapTitle , bitmapDungeonChaos , boxTitleDungeonChaos , 0 , 0 , k160_byteWidthScreen , k160_byteWidthScreen , kM1_ColorNoTransparency , 200 , 80 ) ;
titleSteps + = 320 * 80 ;
bitmapTitle = bitmapDungeonChaos ;
uint16 destinationHeight = 12 ;
int16 destinationPixelWidth = 48 ;
byte * shrinkedTitle [ 20 ] ; /* Only the first 18 entries are actually used */
int16 blitCoordinates [ 20 ] [ 5 ] ; /* Only the first 18 entries are actually used */
for ( int16 i = 0 ; i < 18 ; i + + ) {
shrinkedTitle [ i ] = titleSteps ;
_displayMan - > blitToBitmapShrinkWithPalChange ( bitmapTitle , titleSteps , 320 , 80 , destinationPixelWidth , destinationHeight , _displayMan - > _palChangesNoChanges ) ;
blitCoordinates [ i ] [ 0 ] = ( 320 - destinationPixelWidth ) / 2 ;
blitCoordinates [ i ] [ 1 ] = blitCoordinates [ i ] [ 0 ] + destinationPixelWidth - 1 ;
blitCoordinates [ i ] [ 2 ] = ( 160 - destinationHeight ) / 2 ;
blitCoordinates [ i ] [ 3 ] = blitCoordinates [ i ] [ 2 ] + destinationHeight - 1 ;
titleSteps + = ( blitCoordinates [ i ] [ 4 ] = ( ( destinationPixelWidth + 15 ) / 16 ) * 8 ) * destinationHeight * 2 ;
destinationHeight + = 4 ;
destinationPixelWidth + = 16 ;
2016-08-19 18:16:23 +02:00
}
2016-08-26 19:12:17 +02:00
blitPalette [ 15 ] = D01_RGB_DARK_BLUE ;
_displayMan - > startEndFadeToPalette ( blitPalette ) ;
2016-08-19 18:16:23 +02:00
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-26 19:12:17 +02:00
blitPalette [ 3 ] = D05_RGB_DARK_GOLD ;
blitPalette [ 4 ] = D02_RGB_LIGHT_BROWN ;
blitPalette [ 5 ] = D06_RGB_GOLD ;
blitPalette [ 6 ] = D04_RGB_LIGHTER_BROWN ;
blitPalette [ 8 ] = D08_RGB_YELLOW ;
blitPalette [ 15 ] = D07_RGB_RED ;
blitPalette [ 10 ] = D01_RGB_DARK_BLUE ;
blitPalette [ 12 ] = D01_RGB_DARK_BLUE ;
_displayMan - > startEndFadeToPalette ( blitPalette ) ;
2016-08-23 23:36:18 +02:00
delay ( 1 ) ;
2016-08-26 19:12:17 +02:00
for ( int16 i = 0 ; i < 18 ; i + + ) {
2016-08-23 23:36:18 +02:00
delay ( 2 ) ;
2016-08-26 19:12:17 +02:00
Box box ( blitCoordinates [ i ] ) ;
_displayMan - > blitToBitmap ( shrinkedTitle [ i ] , _displayMan - > _bitmapScreen , box , 0 , 0 , blitCoordinates [ i ] [ 4 ] , k160_byteWidthScreen , kM1_ColorNoTransparency , blitCoordinates [ i ] [ 3 ] - blitCoordinates [ i ] [ 2 ] + 1 , k200_heightScreen ) ;
2016-08-19 18:16:23 +02:00
}
2016-08-26 19:12:17 +02:00
delay ( 25 ) ;
_displayMan - > blitToBitmap ( masterStrikesBack , _displayMan - > _bitmapScreen , boxTitleStrikesBackDestination , 0 , 0 , k160_byteWidthScreen , k160_byteWidthScreen , k0_ColorBlack , 57 , k200_heightScreen ) ;
blitPalette [ 10 ] = D00_RGB_BLACK ;
blitPalette [ 12 ] = D07_RGB_RED ;
_displayMan - > startEndFadeToPalette ( blitPalette ) ;
delete [ ] allocatedMem ;
delay ( 75 ) ;
2016-08-19 18:16:23 +02:00
}
2016-08-23 23:36:18 +02:00
void DMEngine : : entranceDrawCredits ( ) {
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _blankBuffer ) ;
_displayMan - > loadIntoBitmap ( k5_creditsGraphicIndice , _displayMan - > _bitmapScreen ) ;
_displayMan - > startEndFadeToPalette ( _displayMan - > _palCredits ) ;
2016-08-23 23:36:18 +02:00
delay ( 50 ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > waitForMouseOrKeyActivity ( ) ;
2016-08-23 23:36:18 +02:00
_newGameFl = k202_modeEntranceDrawCredits ;
2016-08-12 16:29:52 +02:00
}
2016-08-23 23:36:18 +02:00
void DMEngine : : fuseSequnce ( ) {
2016-08-11 12:15:08 +02:00
int16 L1424_i_Multiple ;
# define AL1424_B_RemoveFluxcagesFromLoadChaosSquare L1424_i_Multiple
# define AL1424_i_Attack L1424_i_Multiple
# define AL1424_i_CreatureTypeSwitchCount L1424_i_Multiple
# define AL1424_i_MapX L1424_i_Multiple
# define AL1424_i_TextStringThingCount L1424_i_Multiple
int16 L1425_i_Multiple ;
# define AL1425_i_FluxcageMapX L1425_i_Multiple
# define AL1425_i_MapY L1425_i_Multiple
# define AL1425_i_CycleCount L1425_i_Multiple
# define AL1425_i_TextStringThingIndex L1425_i_Multiple
int16 L1426_i_Multiple ;
# define AL1426_i_FluxcageMapY L1426_i_Multiple
# define AL1426_i_FuseSequenceUpdateCount L1426_i_Multiple
# define AL1426_i_TextStringThingCount L1426_i_Multiple
Thing L1427_T_Thing ;
2016-08-27 10:54:29 +02:00
Group * L1428_ps_Group ;
Explosion * L1429_ps_Explosion ;
2016-08-11 12:15:08 +02:00
Thing L1430_T_NextThing ;
int16 L1431_i_LordChaosMapX ;
int16 L1432_i_LordChaosMapY ;
Thing L1433_T_LordChaosThing ;
char L1434_c_TextFirstCharacter ;
Thing L1435_aT_TextStringThings [ 8 ] ;
char L1436_ac_String [ 200 ] ;
2016-08-23 23:36:18 +02:00
_gameWon = true ;
2016-08-25 21:25:18 +02:00
if ( _inventoryMan - > _inventoryChampionOrdinal ) {
_inventoryMan - > toggleInventory ( k4_ChampionCloseInventory ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-25 08:12:23 +02:00
_eventMan - > highlightBoxDisable ( ) ;
2016-08-23 07:54:16 +02:00
_championMan - > _party . _magicalLightAmount = 200 ;
2016-08-25 21:25:18 +02:00
_inventoryMan - > setDungeonViewPalette ( ) ;
2016-08-23 07:54:16 +02:00
_championMan - > _party . _fireShieldDefense = _championMan - > _party . _spellShieldDefense = _championMan - > _party . _shieldDefense = 100 ;
2016-08-25 22:38:03 +02:00
_timeline - > refreshAllChampionStatusBoxes ( ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-24 08:03:55 +02:00
L1431_i_LordChaosMapX = _dungeonMan - > _partyMapX ;
L1432_i_LordChaosMapY = _dungeonMan - > _partyMapY ;
L1431_i_LordChaosMapX + = _dirIntoStepCountEast [ _dungeonMan - > _partyDir ] , L1432_i_LordChaosMapY + = _dirIntoStepCountNorth [ _dungeonMan - > _partyDir ] ;
2016-08-25 21:17:48 +02:00
L1428_ps_Group = ( Group * ) _dungeonMan - > getThingData ( L1433_T_LordChaosThing = _groupMan - > groupGetThing ( L1431_i_LordChaosMapX , L1432_i_LordChaosMapY ) ) ;
2016-08-11 12:15:08 +02:00
L1428_ps_Group - > _health [ 0 ] = 10000 ;
2016-08-24 08:03:55 +02:00
_dungeonMan - > setGroupCells ( L1428_ps_Group , k255_CreatureTypeSingleCenteredCreature , _dungeonMan - > _partyMapIndex ) ;
_dungeonMan - > setGroupDirections ( L1428_ps_Group , returnOppositeDir ( _dungeonMan - > _partyDir ) , _dungeonMan - > _partyMapIndex ) ;
2016-08-11 12:15:08 +02:00
AL1424_B_RemoveFluxcagesFromLoadChaosSquare = true ;
2016-08-24 08:03:55 +02:00
AL1425_i_FluxcageMapX = _dungeonMan - > _partyMapX ;
AL1426_i_FluxcageMapY = _dungeonMan - > _partyMapY ;
2016-08-11 12:15:08 +02:00
T0446002 :
2016-08-24 08:03:55 +02:00
L1427_T_Thing = _dungeonMan - > getSquareFirstObject ( AL1425_i_FluxcageMapX , AL1426_i_FluxcageMapY ) ;
2016-08-11 12:15:08 +02:00
while ( L1427_T_Thing ! = Thing : : _endOfList ) {
if ( L1427_T_Thing . getType ( ) = = k15_ExplosionThingType ) {
2016-08-24 08:03:55 +02:00
L1429_ps_Explosion = ( Explosion * ) _dungeonMan - > getThingData ( L1427_T_Thing ) ;
2016-08-11 12:15:08 +02:00
if ( L1429_ps_Explosion - > getType ( ) = = k50_ExplosionType_Fluxcage ) {
2016-08-24 08:03:55 +02:00
_dungeonMan - > unlinkThingFromList ( L1427_T_Thing , Thing ( 0 ) , AL1425_i_FluxcageMapX , AL1426_i_FluxcageMapY ) ;
2016-08-11 12:15:08 +02:00
L1429_ps_Explosion - > setNextThing ( Thing : : _none ) ;
goto T0446002 ;
}
}
2016-08-24 08:03:55 +02:00
L1427_T_Thing = _dungeonMan - > getNextThing ( L1427_T_Thing ) ;
2016-08-11 12:15:08 +02:00
}
if ( AL1424_B_RemoveFluxcagesFromLoadChaosSquare ) {
AL1424_B_RemoveFluxcagesFromLoadChaosSquare = false ;
AL1425_i_FluxcageMapX = L1431_i_LordChaosMapX ;
AL1426_i_FluxcageMapY = L1432_i_LordChaosMapY ;
goto T0446002 ;
}
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
2016-08-25 22:19:34 +02:00
_projexpl - > createExplosion ( Thing : : _explFireBall , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-25 22:38:03 +02:00
_sound - > requestPlay ( k17_soundBUZZ , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k1_soundModePlayIfPrioritized ) ;
2016-08-11 12:15:08 +02:00
L1428_ps_Group - > _type = k25_CreatureTypeLordOrder ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
2016-08-25 22:19:34 +02:00
_projexpl - > createExplosion ( Thing : : _explHarmNonMaterial , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
for ( AL1425_i_CycleCount = 4 ; - - AL1425_i_CycleCount ; ) {
for ( AL1424_i_CreatureTypeSwitchCount = 5 ; - - AL1424_i_CreatureTypeSwitchCount ; ) {
2016-08-25 22:38:03 +02:00
_sound - > requestPlay ( k17_soundBUZZ , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k1_soundModePlayIfPrioritized ) ;
2016-08-11 12:15:08 +02:00
L1428_ps_Group - > _type = ( AL1424_i_CreatureTypeSwitchCount & 0x0001 ) ? k25_CreatureTypeLordOrder : k23_CreatureTypeLordChaos ;
2016-08-23 23:36:18 +02:00
for ( AL1426_i_FuseSequenceUpdateCount = AL1425_i_CycleCount ; AL1426_i_FuseSequenceUpdateCount - - ; fuseSequenceUpdate ( ) ) ;
2016-08-11 12:15:08 +02:00
}
}
2016-08-25 22:19:34 +02:00
_projexpl - > createExplosion ( Thing : : _explFireBall , 255 , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
_projexpl - > createExplosion ( Thing : : _explHarmNonMaterial , 255 , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
L1428_ps_Group - > _type = k26_CreatureTypeGreyLord ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > _doNotDrawFluxcagesDuringEndgame = true ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-24 08:03:55 +02:00
for ( AL1424_i_MapX = 0 ; AL1424_i_MapX < _dungeonMan - > _currMapWidth ; AL1424_i_MapX + + ) {
for ( AL1425_i_MapY = 0 ; AL1425_i_MapY < _dungeonMan - > _currMapHeight ; AL1425_i_MapY + + ) {
2016-08-25 21:17:48 +02:00
if ( ( ( L1427_T_Thing = _groupMan - > groupGetThing ( AL1424_i_MapX , AL1425_i_MapY ) ) ! = Thing : : _endOfList ) & & ( ( AL1424_i_MapX ! = L1431_i_LordChaosMapX ) | | ( AL1425_i_MapY ! = L1432_i_LordChaosMapY ) ) ) {
_groupMan - > groupDelete ( AL1424_i_MapX , AL1425_i_MapY ) ;
2016-08-11 12:15:08 +02:00
}
}
}
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
/* Count and get list of text things located at 0, 0 in the current map. Their text is then printed as messages in the order specified by their first letter (which is not printed) */
2016-08-24 08:03:55 +02:00
L1427_T_Thing = _dungeonMan - > getSquareFirstThing ( 0 , 0 ) ;
2016-08-11 12:15:08 +02:00
AL1424_i_TextStringThingCount = 0 ;
while ( L1427_T_Thing ! = Thing : : _endOfList ) {
if ( L1427_T_Thing . getType ( ) = = k2_TextstringType ) {
L1435_aT_TextStringThings [ AL1424_i_TextStringThingCount + + ] = L1427_T_Thing ;
}
2016-08-24 08:03:55 +02:00
L1427_T_Thing = _dungeonMan - > getNextThing ( L1427_T_Thing ) ;
2016-08-11 12:15:08 +02:00
}
L1434_c_TextFirstCharacter = ' A ' ;
AL1426_i_TextStringThingCount = AL1424_i_TextStringThingCount ;
while ( AL1424_i_TextStringThingCount - - ) {
for ( AL1425_i_TextStringThingIndex = 0 ; AL1425_i_TextStringThingIndex < AL1426_i_TextStringThingCount ; AL1425_i_TextStringThingIndex + + ) {
2016-08-24 08:03:55 +02:00
_dungeonMan - > decodeText ( L1436_ac_String , L1435_aT_TextStringThings [ AL1425_i_TextStringThingIndex ] , ( TextType ) ( k1_TextTypeMessage | k0x8000_DecodeEvenIfInvisible ) ) ;
2016-08-11 12:15:08 +02:00
if ( L1436_ac_String [ 1 ] = = L1434_c_TextFirstCharacter ) {
2016-08-25 22:38:03 +02:00
_textMan - > clearAllRows ( ) ;
2016-08-11 12:15:08 +02:00
L1436_ac_String [ 1 ] = ' \n ' ; /* New line */
2016-08-25 22:38:03 +02:00
_textMan - > printMessage ( k15_ColorWhite , & L1436_ac_String [ 1 ] ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
delay ( 780 ) ;
2016-08-11 12:15:08 +02:00
L1434_c_TextFirstCharacter + + ;
break ;
}
}
}
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
2016-08-25 22:19:34 +02:00
_projexpl - > createExplosion ( Thing : : _explHarmNonMaterial , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-09 11:54:04 +02:00
2016-08-23 23:36:18 +02:00
delay ( 600 ) ;
_restartGameAllowed = false ;
endGame ( true ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-09 11:54:04 +02:00
2016-08-23 23:36:18 +02:00
void DMEngine : : fuseSequenceUpdate ( ) {
2016-08-25 22:38:03 +02:00
_timeline - > processTimeline ( ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > drawDungeon ( _dungeonMan - > _partyDir , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY ) ;
2016-08-25 22:38:03 +02:00
_sound - > playPendingSound ( ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > discardAllInput ( ) ;
2016-08-11 12:11:16 +02:00
_displayMan - > updateScreen ( ) ;
2016-08-23 23:36:18 +02:00
delay ( 2 ) ;
_gameTime + + ; /* BUG0_71 Some timings are too short on fast computers.
2016-08-11 12:11:16 +02:00
The ending animation when Lord Chaos is fused plays too quickly because the execution speed is not limited */
}
2016-08-09 11:54:04 +02:00
2016-08-23 15:39:05 +02:00
Common : : Language DMEngine : : getGameLanguage ( ) { return _gameVersion - > _desc . language ; }
2016-04-26 14:44:01 +02:00
} // End of namespace DM