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-09-03 10:38:43 +02:00
# include "advancedDetector.h"
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"
2016-05-02 20:58:55 +02:00
# 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-09-03 10:38:43 +02:00
# include "common/translation.h"
# include "engines/util.h"
# include "engines/engine.h"
# include "graphics/cursorman.h"
# include "graphics/palette.h"
# include "graphics/surface.h"
# include "gui/saveload.h"
2016-04-26 14:44:01 +02:00
# include "dm/dm.h"
2016-09-03 10:38:43 +02:00
# include "dm/gfx.h"
# include "dm/dungeonman.h"
# include "dm/eventman.h"
# include "dm/menus.h"
# include "dm/champion.h"
# include "dm/loadsave.h"
# include "dm/objectman.h"
# include "dm/inventory.h"
# include "dm/text.h"
# include "dm/movesens.h"
# include "dm/group.h"
# include "dm/timeline.h"
# include "dm/projexpl.h"
# include "dm/dialog.h"
# include "dm/sounds.h"
2016-04-26 14:44:01 +02:00
namespace DM {
2016-10-11 07:37:12 +02:00
bool DMEngine : : isDemo ( ) const {
return ( bool ) ( _gameVersion - > _desc . flags & ADGF_DEMO ) ;
}
2016-09-11 10:45:20 +02:00
Direction DMEngine : : turnDirRight ( int16 dir ) {
Direction result = ( Direction ) ( ( dir + 1 ) & 3 ) ;
return result ;
2016-08-10 14:44:54 +02:00
}
2016-09-11 10:45:20 +02:00
Direction DMEngine : : returnOppositeDir ( int16 dir ) {
Direction result = ( Direction ) ( ( dir + 2 ) & 3 ) ;
return result ;
2016-07-30 10:37:29 +02:00
}
2016-09-11 10:45:20 +02:00
Direction DMEngine : : turnDirLeft ( int16 dir ) {
Direction result = ( Direction ) ( ( dir + 3 ) & 3 ) ;
return result ;
2016-07-30 10:37:29 +02:00
}
2016-09-11 10:45:20 +02:00
bool DMEngine : : isOrientedWestEast ( int16 dir ) {
2016-07-30 10:37:29 +02:00
return dir & 1 ;
}
2016-05-21 21:09:09 +02:00
2016-09-11 10:45:20 +02:00
uint16 DMEngine : : normalizeModulo4 ( int16 dir ) {
return dir & 3 ;
2016-06-29 22:08:10 +02:00
}
2016-05-04 12:50:06 +02:00
2016-09-11 09:46:35 +02:00
int32 DMEngine : : filterTime ( int32 mapTime ) {
2016-07-25 16:18:33 +02:00
return mapTime & 0x00FFFFFF ;
2016-07-07 00:46:51 +02:00
}
2016-09-19 07:05:37 +02:00
int32 DMEngine : : setMapAndTime ( uint32 map , uint32 time ) {
return ( time | ( map < < 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
2016-09-11 09:46:35 +02:00
uint16 DMEngine : : getMap ( int32 mapTime ) {
2016-09-19 07:05:37 +02:00
return ( ( uint16 ) ( mapTime > > 24 ) ) ;
}
int32 DMEngine : : setMap ( int32 mapTime , uint32 map ) {
return ( ( mapTime & 0x00FFFFFF ) | ( map < < 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
2016-09-11 09:46:35 +02:00
Thing DMEngine : : thingWithNewCell ( Thing thing , int16 cell ) {
2016-07-07 00:46:51 +02:00
return Thing ( ( ( thing . toUint16 ( ) ) & 0x3FFF ) | ( ( cell ) < < 14 ) ) ;
}
2016-09-11 09:46:35 +02:00
int16 DMEngine : : getDistance ( int16 mapx1 , int16 mapy1 , int16 mapx2 , int16 mapy2 ) {
2016-07-07 00:46:51 +02:00
return ABS ( mapx1 - mapx2 ) + ABS ( mapy1 - mapy2 ) ;
}
2017-01-31 18:15:31 +01:00
DMEngine : : DMEngine ( OSystem * syst , const DMADGameDescription * desc ) :
Engine ( syst ) , _console ( nullptr ) , _gameVersion ( desc ) ,
_thingNone ( 0 ) , _thingEndOfList ( 0xFFFE ) , _thingFirstExplosion ( 0xFF80 ) ,
_thingExplFireBall ( 0xFF80 ) , _thingExplSlime ( 0xFF81 ) , _thingExplLightningBolt ( 0xFF82 ) ,
_thingExplHarmNonMaterial ( 0xFF83 ) , _thingExplOpenDoor ( 0xFF84 ) , _thingExplPoisonBolt ( 0xFF86 ) ,
_thingExplPoisonCloud ( 0xFF87 ) , _thingExplSmoke ( 0xFFA8 ) , _thingExplFluxcage ( 0xFFB2 ) ,
_thingExplRebirthStep1 ( 0xFFE4 ) , _thingExplRebirthStep2 ( 0xFFE5 ) , _thingParty ( 0xFFFF )
{
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 ;
2016-09-19 21:45:14 +02:00
_gameMode = kDMModeLoadSavedGame ;
2016-08-23 23:36:18 +02:00
_restartGameRequest = false ;
_stopWaitingForPlayerInput = true ;
_gameTimeTicking = false ;
_restartGameAllowed = false ;
_pressingEye = false ;
_stopPressingEye = false ;
_pressingMouth = false ;
_stopPressingMouth = false ;
_highlightBoxInversionRequested = false ;
_projectileDisableMovementTicks = 0 ;
_lastProjectileDisabledMovementDirection = 0 ;
_gameWon = false ;
2016-09-11 00:33:54 +02:00
_newPartyMapIndex = kDMMapIndexNone ;
2016-08-23 23:36:18 +02:00
_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-09-20 23:14:30 +02:00
_dialog = nullptr ;
2016-04-26 14:44:01 +02:00
}
DMEngine : : ~ DMEngine ( ) {
debug ( " DMEngine::~DMEngine " ) ;
// dispose of resources
delete _rnd ;
2020-02-08 21:14:03 -08:00
//delete _console; Debugger is deleted by Engine
2016-05-02 20:58:55 +02:00
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-09-11 00:33:54 +02:00
if ( loadgame ( slot ) ! = kDMLoadgameFailure ) {
2016-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorBlack ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _palDungeonView [ 0 ] ) ;
2016-09-19 21:45:14 +02:00
_gameMode = kDMModeLoadSavedGame ;
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 ( ) ;
2016-09-15 07:34:38 +02:00
_displayMan - > loadFloorSet ( kDMFloorSetStone ) ;
_displayMan - > loadWallSet ( kDMWallSetStone ) ;
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-09-19 21:45:14 +02:00
if ( _gameMode = = kDMModeLoadSavedGame ) { // 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-09-11 00:33:54 +02:00
} while ( loadgame ( saveSlot ) ! = kDMLoadgameSuccess ) ;
2016-08-09 13:46:12 +02:00
2016-09-21 07:53:54 +02:00
_displayMan - > loadIntoBitmap ( kDMGraphicIdxMenuSpellAreLines , _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 ( ) ;
2016-09-19 21:45:14 +02:00
if ( _gameMode ! = kDMModeLoadSavedGame )
2017-01-31 18:15:31 +01:00
_moveSens - > getMoveResult ( _thingParty , kDMMapXNotOnASquare , 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-09-09 07:12:36 +02:00
_championMan - > _actingChampionOrdinal = indexToOrdinal ( kDMChampionNone ) ;
2016-08-25 21:59:02 +02:00
_menuMan - > _actionAreaContainsIcons = true ;
2016-09-09 07:12:36 +02:00
_eventMan - > _useChampionIconOrdinalAsMousePointerBitmap = indexToOrdinal ( kDMChampionNone ) ;
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-09-19 21:45:14 +02:00
if ( _gameMode = = kDMModeLoadSavedGame ) {
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-09-16 07:46:10 +02:00
_displayMan - > fillScreenBox ( boxScreenTop , kDMColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenRight , kDMColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenBottom , kDMColorBlack ) ;
2016-06-19 00:49:23 +02:00
} else {
2016-08-25 18:32:03 +02:00
_displayMan - > _useByteBoxCoordinates = false ;
2016-09-16 07:46:10 +02:00
_displayMan - > fillScreenBox ( boxScreenTop , kDMColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenRight , kDMColorBlack ) ;
_displayMan - > fillScreenBox ( boxScreenBottom , kDMColorBlack ) ;
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
2017-10-01 00:56:01 -05:00
initGraphics ( 320 , 200 ) ;
2016-04-26 14:44:01 +02:00
_console = new Console ( this ) ;
2020-02-08 21:14:03 -08:00
setDebugger ( _console ) ;
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-09-03 11:12:16 +02:00
_waitForInputMaxVerticalBlankCount = 15 ;
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-09-11 00:33:54 +02:00
if ( _newPartyMapIndex ! = kDMMapIndexNone ) {
2016-08-23 23:36:18 +02:00
processNewPartyMap ( _newPartyMapIndex ) ;
2017-01-31 18:15:31 +01:00
_moveSens - > getMoveResult ( _thingParty , kDMMapXNotOnASquare , 0 , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY ) ;
2016-09-11 00:33:54 +02:00
_newPartyMapIndex = kDMMapIndexNone ;
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-09-11 00:33:54 +02:00
if ( _newPartyMapIndex = = kDMMapIndexNone )
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-09-16 07:46:10 +02:00
_displayMan - > fillBoxBitmap ( _displayMan - > _bitmapViewport , box , kDMColorBlack , k112_byteWidthViewport , k136_heightViewport ) ; // (possibly dummy code)
2016-08-25 18:32:03 +02:00
_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-09-03 11:12:16 +02:00
if ( + + vblankCounter > _waitForInputMaxVerticalBlankCount )
2016-08-23 23:36:18 +02:00
_stopWaitingForPlayerInput = true ;
2016-09-03 11:12:16 +02:00
else if ( ! _stopWaitingForPlayerInput )
_system - > delayMillis ( 10 ) ;
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-09-21 07:53:54 +02:00
_displayMan - > loadIntoBitmap ( kDMGraphicIdxEntranceRightDoor , _entranceDoorAnimSteps [ 4 ] ) ;
_displayMan - > loadIntoBitmap ( kDMGraphicIdxEntranceLeftDoor , _entranceDoorAnimSteps [ 0 ] ) ;
_interfaceCredits = _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxCredits ) ;
2016-08-25 18:32:03 +02:00
_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-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( _entranceDoorAnimSteps [ 0 ] , _entranceDoorAnimSteps [ idx ] , displayBox , idx < < 2 , 0 , k64_byteWidth , k64_byteWidth , kDMColorNoTransparency , 161 , 161 ) ;
2016-09-16 21:17:02 +02:00
displayBox . _rect . right - = 4 ;
2016-07-20 16:42:37 +02:00
}
2016-09-16 21:17:02 +02:00
displayBox . _rect . right = 127 ;
2016-07-30 10:26:23 +02:00
for ( uint16 idx = 5 ; idx < 8 ; idx + + ) {
2016-09-16 21:17:02 +02:00
displayBox . _rect . left + = 4 ;
2016-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( _entranceDoorAnimSteps [ 4 ] , _entranceDoorAnimSteps [ idx ] , displayBox , 0 , 0 , k64_byteWidth , k64_byteWidth , kDMColorNoTransparency , 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-09-19 21:45:14 +02:00
_gameMode = kDMModeWaitingOnEntrance ;
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-09-19 21:45:14 +02:00
} while ( _gameMode = = kDMModeWaitingOnEntrance ) ;
} while ( _gameMode = = kDMModeEntranceDrawCredits ) ;
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-09-19 00:17:36 +02:00
_sound - > play ( kDMSoundIndexSwitch , 112 , 0x40 , 0x40 ) ;
2016-08-23 23:36:18 +02:00
delay ( 20 ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > showMouse ( ) ;
2016-09-19 21:45:14 +02:00
if ( _gameMode ! = kDMModeLoadSavedGame )
2016-08-23 23:36:18 +02:00
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-09-19 00:17:36 +02:00
_sound - > requestPlay ( kDMSoundIndexScream , _dungeonMan - > _partyMapX , _dungeonMan - > _partyMapY , kDMSoundModePlayImmediately ) ;
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.
2016-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorDarkestGray ) ;
2016-09-09 07:12:36 +02:00
for ( int16 championIndex = kDMChampionFirst ; 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-09-21 07:53:54 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxWallOrnChampMirror ) , & championMirrorBox , k32_byteWidth , kDMColorFlesh , 43 ) ;
2016-09-16 07:46:10 +02:00
_displayMan - > blitToScreen ( curChampion - > _portrait , & championPortraitBox , k16_byteWidth , kDMColorDarkGary , 29 ) ;
_textMan - > printEndGameString ( 87 , textPosY + = 14 , kDMColorGold , 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-09-16 07:46:10 +02:00
_textMan - > printEndGameString ( textPosX , textPosY + + , kDMColorGold , curChampion - > _title ) ;
2016-09-09 07:32:32 +02:00
for ( int16 idx = kDMSkillFighter ; idx < = kDMSkillWizard ; idx + + ) {
2016-09-09 01:09:25 +02:00
uint16 skillLevel = MIN < uint16 > ( 16 , _championMan - > getSkillLevel ( championIndex , idx | ( kDMIgnoreObjectModifiers | kDMIgnoreTemporaryExperience ) ) ) ;
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
2016-09-12 20:52:04 +02:00
Common : : String displStr = Common : : String : : format ( " %s %s " , _inventoryMan - > _skillLevelNames [ skillLevel - 2 ] , _championMan - > _baseSkillName [ idx ] ) ;
2016-09-16 07:46:10 +02:00
_textMan - > printEndGameString ( 105 , textPosY = textPosY + 8 , kDMColorLightestGray , displStr . c_str ( ) ) ;
2016-07-29 22:27:43 +02:00
}
2016-09-16 21:17:02 +02:00
championMirrorBox . _rect . top + = 48 ;
championMirrorBox . _rect . bottom + = 48 ;
championPortraitBox . _rect . top + = 48 ;
championPortraitBox . _rect . top + = 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 :
2016-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorBlack ) ;
2016-09-21 07:53:54 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxTheEnd ) , & theEndBox , k40_byteWidth , kDMColorNoTransparency , 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 ;
2016-09-16 07:46:10 +02:00
_displayMan - > fillScreenBox ( restartOuterBox , kDMColorDarkestGray ) ;
_displayMan - > fillScreenBox ( restartInnerBox , kDMColorBlack ) ;
2016-08-15 20:25:40 +02:00
switch ( getGameLanguage ( ) ) { // localized
default :
2016-08-26 19:12:17 +02:00
case Common : : EN_ANY :
2016-09-16 07:46:10 +02:00
_textMan - > printToLogicalScreen ( 110 , 154 , kDMColorCyan , kDMColorBlack , " RESTART THIS GAME " ) ;
2016-08-26 19:12:17 +02:00
break ;
case Common : : DE_DEU :
2016-09-16 07:46:10 +02:00
_textMan - > printToLogicalScreen ( 110 , 154 , kDMColorCyan , kDMColorBlack , " DIESES SPIEL NEU STARTEN " ) ;
2016-08-26 19:12:17 +02:00
break ;
case Common : : FR_FRA :
2016-09-16 07:46:10 +02:00
_textMan - > printToLogicalScreen ( 110 , 154 , kDMColorCyan , kDMColorBlack , " RECOMMENCER CE JEU " ) ;
2016-08-26 19:12:17 +02:00
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-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorBlack ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > startEndFadeToPalette ( _displayMan - > _palDungeonView [ 0 ] ) ;
2016-09-19 21:45:14 +02:00
_gameMode = kDMModeLoadSavedGame ;
2016-09-11 00:33:54 +02:00
if ( loadgame ( 1 ) ! = kDMLoadgameFailure ) {
2016-08-23 23:36:18 +02:00
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-09-21 07:53:54 +02:00
_displayMan - > blitToScreen ( _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxCredits ) , & box , k160_byteWidthScreen , kDMColorNoTransparency , 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-09-11 00:33:54 +02:00
_dungeonMan - > _partyMapIndex = kDMMapIndexEntrance ;
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-09-11 21:22:22 +02:00
microDungeonSquares [ i ] = Square ( kDMElementTypeWall , 0 ) ;
2016-07-31 21:48:37 +02:00
for ( int16 idx = 0 ; idx < 5 ; idx + + ) {
microDungeonCurrentMapData [ idx ] = ( byte * ) & microDungeonSquares [ idx * 5 ] ;
2016-09-13 07:46:38 +02:00
microDungeonSquares [ idx + 10 ] = Square ( kDMElementTypeCorridor , 0 ) ;
2016-07-20 16:42:37 +02:00
}
2016-09-13 07:46:38 +02:00
microDungeonSquares [ 7 ] = Square ( kDMElementTypeCorridor , 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-09-21 07:53:54 +02:00
_displayMan - > loadIntoBitmap ( kDMGraphicIdxEntrance , _displayMan - > _bitmapScreen ) ;
2016-09-11 00:33:54 +02:00
_displayMan - > drawDungeon ( kDMDirSouth , 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-09-24 09:39:23 +02:00
_displayMan - > _useByteBoxCoordinates = false ;
_displayMan - > blitToBitmap ( _displayMan - > _bitmapScreen , _entranceDoorAnimSteps [ 8 ] , doorsUpperHalfBox , 0 , 30 , k160_byteWidthScreen , k128_byteWidth , kDMColorNoTransparency , 200 , 161 ) ;
_displayMan - > _useByteBoxCoordinates = false ;
_displayMan - > blitToBitmap ( _displayMan - > _bitmapScreen , _entranceDoorAnimSteps [ 8 ] , doorsLowerHalfBox , 0 , 111 , k160_byteWidthScreen , k128_byteWidth , kDMColorNoTransparency , 200 , 161 ) ;
2016-07-20 16:42:37 +02:00
2016-09-16 07:46:10 +02:00
_displayMan - > blitToScreen ( _entranceDoorAnimSteps [ 0 ] , & closedDoorLeftBox , k64_byteWidth , kDMColorNoTransparency , 161 ) ;
_displayMan - > blitToScreen ( _entranceDoorAnimSteps [ 4 ] , & closedDoorRightBox , k64_byteWidth , kDMColorNoTransparency , 161 ) ;
2016-08-25 18:32:03 +02:00
_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-09-21 07:53:54 +02:00
byte * rightDoorBitmap = _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxEntranceRightDoor ) ;
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-09-21 07:53:54 +02:00
byte * leftDoorBitmap = _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxEntranceLeftDoor ) ;
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-09-19 00:17:36 +02:00
_sound - > play ( kDMSoundIndexDoorRattle , 145 , 0x40 , 0x40 ) ;
2016-08-09 11:54:04 +02:00
}
2016-09-16 07:46:10 +02:00
_displayMan - > blitToScreen ( _savedScreenForOpenEntranceDoors , & screenBox , 160 , kDMColorNoTransparency , 200 ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToBitmap ( leftDoorBitmap , _displayMan - > _bitmapScreen , leftDoorBox , leftDoorBlitFrom , 0 , 64 , k160_byteWidthScreen ,
2016-09-16 07:46:10 +02:00
kDMColorNoTransparency , 161 , k200_heightScreen ) ;
2016-08-25 18:32:03 +02:00
_displayMan - > blitToBitmap ( rightDoorBitmap , _displayMan - > _bitmapScreen , rightDoorBox , 0 , 0 , 64 , k160_byteWidthScreen ,
2016-09-16 07:46:10 +02:00
kDMColorNoTransparency , 161 , k200_heightScreen ) ;
2016-08-25 08:12:23 +02:00
_eventMan - > discardAllInput ( ) ;
2016-08-09 11:54:04 +02:00
_displayMan - > updateScreen ( ) ;
2016-09-16 21:17:02 +02:00
leftDoorBox . _rect . right - = 4 ;
2016-08-09 11:54:04 +02:00
leftDoorBlitFrom + = 4 ;
2016-09-16 21:17:02 +02:00
rightDoorBox . _rect . left + = 4 ;
2016-08-09 11:54:04 +02:00
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 ;
2016-09-21 07:53:54 +02:00
_displayMan - > loadIntoBitmap ( kDMGraphicIdxTitle , 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-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorBlack ) ;
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 ;
2016-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( bitmapTitle , masterStrikesBack , boxTitleStrikesBackSource , 0 , 80 , k160_byteWidthScreen , k160_byteWidthScreen , kDMColorNoTransparency , 200 , 57 ) ;
2016-08-26 19:12:17 +02:00
titleSteps + = 320 * 57 ;
byte * bitmapDungeonChaos = titleSteps ; /* Unreferenced on Atari ST */
2016-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( bitmapTitle , bitmapDungeonChaos , boxTitleDungeonChaos , 0 , 0 , k160_byteWidthScreen , k160_byteWidthScreen , kDMColorNoTransparency , 200 , 80 ) ;
2016-08-26 19:12:17 +02:00
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-09-16 07:46:10 +02:00
_displayMan - > fillScreen ( kDMColorBlack ) ;
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-09-16 21:17:02 +02:00
Box box ( blitCoordinates [ i ] [ 0 ] , blitCoordinates [ i ] [ 1 ] , blitCoordinates [ i ] [ 2 ] , blitCoordinates [ i ] [ 3 ] ) ;
2016-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( shrinkedTitle [ i ] , _displayMan - > _bitmapScreen , box , 0 , 0 , blitCoordinates [ i ] [ 4 ] , k160_byteWidthScreen , kDMColorNoTransparency , 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 ) ;
2016-09-16 07:46:10 +02:00
_displayMan - > blitToBitmap ( masterStrikesBack , _displayMan - > _bitmapScreen , boxTitleStrikesBackDestination , 0 , 0 , k160_byteWidthScreen , k160_byteWidthScreen , kDMColorBlack , 57 , k200_heightScreen ) ;
2016-08-26 19:12:17 +02:00
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 ) ;
2016-09-21 07:53:54 +02:00
_displayMan - > loadIntoBitmap ( kDMGraphicIdxCredits , _displayMan - > _bitmapScreen ) ;
2016-08-25 18:32:03 +02:00
_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-09-19 21:45:14 +02:00
_gameMode = kDMModeEntranceDrawCredits ;
2016-08-12 16:29:52 +02:00
}
2016-08-27 14:20:06 +02:00
void DMEngine : : fuseSequence ( ) {
2016-08-23 23:36:18 +02:00
_gameWon = true ;
2016-08-27 14:24:11 +02:00
if ( _inventoryMan - > _inventoryChampionOrdinal )
2016-09-09 07:12:36 +02:00
_inventoryMan - > toggleInventory ( kDMChampionCloseInventory ) ;
2016-08-27 14:24:11 +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-27 14:20:06 +02:00
int16 lordChaosMapX = _dungeonMan - > _partyMapX ;
int16 lordChaosMapY = _dungeonMan - > _partyMapY ;
2017-11-08 16:46:05 -06:00
lordChaosMapX + = _dirIntoStepCountEast [ _dungeonMan - > _partyDir ] ;
lordChaosMapY + = _dirIntoStepCountNorth [ _dungeonMan - > _partyDir ] ;
2016-08-27 14:20:06 +02:00
Thing lordChaosThing = _groupMan - > groupGetThing ( lordChaosMapX , lordChaosMapY ) ;
Group * lordGroup = ( Group * ) _dungeonMan - > getThingData ( lordChaosThing ) ;
lordGroup - > _health [ 0 ] = 10000 ;
2016-09-18 12:52:01 +02:00
_dungeonMan - > setGroupCells ( lordGroup , kDMCreatureTypeSingleCenteredCreature , _dungeonMan - > _partyMapIndex ) ;
2016-08-27 14:20:06 +02:00
_dungeonMan - > setGroupDirections ( lordGroup , returnOppositeDir ( _dungeonMan - > _partyDir ) , _dungeonMan - > _partyMapIndex ) ;
bool removeFluxcagesFromLordChaosSquare = true ;
int16 fluxCageMapX = _dungeonMan - > _partyMapX ;
int16 fluxcageMapY = _dungeonMan - > _partyMapY ;
2016-08-27 17:41:53 +02:00
2016-09-03 15:52:59 +02:00
for ( ; ; ) {
2016-08-27 17:41:53 +02:00
Thing curThing = _dungeonMan - > getSquareFirstObject ( fluxCageMapX , fluxcageMapY ) ;
2017-01-31 18:15:31 +01:00
while ( curThing ! = _thingEndOfList ) {
2016-09-11 00:33:54 +02:00
if ( curThing . getType ( ) = = kDMThingTypeExplosion ) {
2016-08-27 17:41:53 +02:00
Explosion * curExplosion = ( Explosion * ) _dungeonMan - > getThingData ( curThing ) ;
2016-09-12 22:46:38 +02:00
if ( curExplosion - > getType ( ) = = kDMExplosionTypeFluxcage ) {
2016-08-27 17:41:53 +02:00
_dungeonMan - > unlinkThingFromList ( curThing , Thing ( 0 ) , fluxCageMapX , fluxcageMapY ) ;
2017-01-31 18:15:31 +01:00
curExplosion - > setNextThing ( _thingNone ) ;
2016-08-27 17:41:53 +02:00
continue ;
}
2016-08-11 12:15:08 +02:00
}
2016-08-27 17:41:53 +02:00
curThing = _dungeonMan - > getNextThing ( curThing ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-27 17:41:53 +02:00
if ( removeFluxcagesFromLordChaosSquare ) {
removeFluxcagesFromLordChaosSquare = false ;
fluxCageMapX = lordChaosMapX ;
fluxcageMapY = lordChaosMapY ;
} else
break ;
2016-08-11 12:15:08 +02:00
}
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-27 14:20:06 +02:00
for ( int16 attackId = 55 ; attackId < = 255 ; attackId + = 40 ) {
2017-01-31 18:15:31 +01:00
_projexpl - > createExplosion ( _thingExplFireBall , attackId , lordChaosMapX , lordChaosMapY , kDMCreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
2016-09-19 00:17:36 +02:00
_sound - > requestPlay ( kDMSoundIndexBuzz , lordChaosMapX , lordChaosMapY , kDMSoundModePlayIfPrioritized ) ;
2016-09-17 15:13:20 +02:00
lordGroup - > _type = kDMCreatureTypeLordOrder ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-27 14:20:06 +02:00
for ( int16 attackId = 55 ; attackId < = 255 ; attackId + = 40 ) {
2017-01-31 18:15:31 +01:00
_projexpl - > createExplosion ( _thingExplHarmNonMaterial , attackId , lordChaosMapX , lordChaosMapY , kDMCreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-27 14:24:11 +02:00
for ( int16 cycleCount = 3 ; cycleCount > 0 ; cycleCount - - ) {
for ( int16 switchCount = 4 ; switchCount > 0 ; switchCount - - ) {
2016-09-19 00:17:36 +02:00
_sound - > requestPlay ( kDMSoundIndexBuzz , lordChaosMapX , lordChaosMapY , kDMSoundModePlayIfPrioritized ) ;
2016-09-17 15:13:20 +02:00
lordGroup - > _type = ( switchCount & 0x0001 ) ? kDMCreatureTypeLordOrder : kDMCreatureTypeLordChaos ;
2016-08-27 14:24:11 +02:00
for ( int16 fuseSequenceUpdateCount = cycleCount - 1 ; fuseSequenceUpdateCount > = 0 ; fuseSequenceUpdateCount - - )
2016-08-27 14:20:06 +02:00
fuseSequenceUpdate ( ) ;
2016-08-11 12:15:08 +02:00
}
}
2017-01-31 18:15:31 +01:00
_projexpl - > createExplosion ( _thingExplFireBall , 255 , lordChaosMapX , lordChaosMapY , kDMCreatureTypeSingleCenteredCreature ) ;
_projexpl - > createExplosion ( _thingExplHarmNonMaterial , 255 , lordChaosMapX , lordChaosMapY , kDMCreatureTypeSingleCenteredCreature ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
2016-09-17 15:13:20 +02:00
lordGroup - > _type = kDMCreatureTypeGreyLord ;
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-27 14:20:06 +02:00
for ( int16 curMapX = 0 ; curMapX < _dungeonMan - > _currMapWidth ; curMapX + + ) {
for ( int curMapY = 0 ; curMapY < _dungeonMan - > _currMapHeight ; curMapY + + ) {
2016-08-27 17:41:53 +02:00
Thing curThing = _groupMan - > groupGetThing ( curMapX , curMapY ) ;
2017-01-31 18:15:31 +01:00
if ( ( curThing ! = _thingEndOfList ) & & ( ( curMapX ! = lordChaosMapX ) | | ( curMapY ! = lordChaosMapY ) ) ) {
2016-08-27 14:20:06 +02:00
_groupMan - > groupDelete ( curMapX , curMapY ) ;
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-27 17:41:53 +02:00
Thing curThing = _dungeonMan - > getSquareFirstThing ( 0 , 0 ) ;
2016-08-27 14:20:06 +02:00
int16 textStringThingCount = 0 ;
Thing textStringThings [ 8 ] ;
2017-01-31 18:15:31 +01:00
while ( curThing ! = _thingEndOfList ) {
2016-09-11 00:33:54 +02:00
if ( curThing . getType ( ) = = kDMstringTypeText )
2016-08-27 14:20:06 +02:00
textStringThings [ textStringThingCount + + ] = curThing ;
2016-08-27 14:24:11 +02:00
2016-08-27 14:20:06 +02:00
curThing = _dungeonMan - > getNextThing ( curThing ) ;
2016-08-11 12:15:08 +02:00
}
2016-08-27 14:20:06 +02:00
char textFirstChar = ' A ' ;
int16 maxCount = textStringThingCount ;
while ( textStringThingCount - - ) {
for ( int16 idx = 0 ; idx < maxCount ; idx + + ) {
char decodedString [ 200 ] ;
2016-09-13 07:46:38 +02:00
_dungeonMan - > decodeText ( decodedString , textStringThings [ idx ] , ( TextType ) ( kDMTextTypeMessage | kDMMaskDecodeEvenIfInvisible ) ) ;
2016-08-27 14:20:06 +02:00
if ( decodedString [ 1 ] = = textFirstChar ) {
2016-08-25 22:38:03 +02:00
_textMan - > clearAllRows ( ) ;
2016-08-27 14:20:06 +02:00
decodedString [ 1 ] = ' \n ' ; /* New line */
2016-09-16 07:46:10 +02:00
_textMan - > printMessage ( kDMColorWhite , & decodedString [ 1 ] ) ;
2016-08-23 23:36:18 +02:00
fuseSequenceUpdate ( ) ;
delay ( 780 ) ;
2016-08-27 14:20:06 +02:00
textFirstChar + + ;
2016-08-11 12:15:08 +02:00
break ;
}
}
}
2016-08-27 14:20:06 +02:00
for ( int16 attackId = 55 ; attackId < = 255 ; attackId + = 40 ) {
2017-01-31 18:15:31 +01:00
_projexpl - > createExplosion ( _thingExplHarmNonMaterial , attackId , lordChaosMapX , lordChaosMapY , kDMCreatureTypeSingleCenteredCreature ) ;
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-27 23:10:13 +02:00
Common : : Language DMEngine : : getGameLanguage ( ) {
return _gameVersion - > _desc . language ;
}
2016-04-26 14:44:01 +02:00
} // End of namespace DM