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-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-04-26 14:44:01 +02:00
namespace DM {
2016-07-11 11:37:01 +02:00
void warning ( bool repeat , const char * s , . . . ) {
va_list va ;
va_start ( va , s ) ;
Common : : String output = Common : : String : : vformat ( s , va ) ;
va_end ( va ) ;
if ( repeat ) {
: : warning ( output . c_str ( ) ) ;
} else {
static Common : : Array < Common : : String > stringsPrinted ;
if ( Common : : find ( stringsPrinted . begin ( ) , stringsPrinted . end ( ) , s ) = = stringsPrinted . end ( ) ) {
stringsPrinted . push_back ( output ) ;
: : warning ( output . c_str ( ) ) ;
}
}
}
2016-04-26 14:44:01 +02:00
2016-08-10 14:44:54 +02:00
const char * debugGetDirectionName ( Direction dir ) {
static const char * directionNames [ ] = { " North " , " East " , " South " , " West " } ;
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
}
uint16 M75_bitmapByteCount ( uint16 pixelWidth , uint16 height ) {
return pixelWidth / 2 * height ;
2016-07-04 20:54:17 +02:00
}
uint16 M21_normalizeModulo4 ( uint16 val ) {
return val & 3 ;
2016-06-29 22:08:10 +02:00
}
2016-05-04 12:50:06 +02:00
2016-07-25 16:18:33 +02:00
int32 M30_time ( int32 mapTime ) {
return mapTime & 0x00FFFFFF ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 16:18:33 +02:00
int32 M33_setMapAndTime ( int32 & mapTime , uint32 map , uint32 time ) {
return ( mapTime ) = ( ( time ) | ( ( ( long ) ( map ) ) < < 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 16:18:33 +02:00
uint16 M29_map ( int32 mapTime ) {
return ( ( uint16 ) ( ( mapTime ) > > 24 ) ) ;
2016-07-07 00:46:51 +02:00
}
Thing M15_thingWithNewCell ( Thing thing , int16 cell ) {
return Thing ( ( ( thing . toUint16 ( ) ) & 0x3FFF ) | ( ( cell ) < < 14 ) ) ;
}
int16 M38_distance ( int16 mapx1 , int16 mapy1 , int16 mapx2 , int16 mapy2 ) {
return ABS ( mapx1 - mapx2 ) + ABS ( mapy1 - mapy2 ) ;
}
2016-08-15 11:56:21 +02:00
DMEngine : : DMEngine ( OSystem * syst , const ADGameDescription * desc ) : Engine ( syst ) , _console ( nullptr ) , _gameVersion ( desc ) {
2016-06-29 22:08:10 +02:00
// Do not load data files
// Do not initialize graphics here
// Do not initialize audio devices here
// Do these from run
//Specify all default directories
//const Common::FSNode gameDataDir(ConfMan.get("example"));
//SearchMan.addSubDirectoryMatching(gameDataDir, "example2");
2016-04-26 14:44:01 +02:00
DebugMan . addDebugChannel ( kDMDebugExample , " example " , " example 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-26 22:50:01 +02:00
2016-07-29 22:27:43 +02:00
_engineShouldQuit = false ;
2016-07-19 18:04:14 +02:00
_g528_saveFormat = 0 ;
_g527_platform = 0 ;
_g526_dungeonId = 0 ;
2016-08-26 22:50:01 +02:00
_g298_newGame = false ;
_g523_restartGameRequest = false ;
_g321_stopWaitingForPlayerInput = true ;
2016-08-26 22:43:17 +02:00
_g301_gameTimeTicking = false ;
_g524_restartGameAllowed = false ;
2016-08-26 22:50:01 +02:00
_g525_gameId = 0 ;
2016-08-26 22:43:17 +02:00
_g331_pressingEye = false ;
_g332_stopPressingEye = false ;
2016-08-26 22:50:01 +02:00
_g333_pressingMouth = false ;
2016-08-26 22:43:17 +02:00
_g334_stopPressingMouth = false ;
_g340_highlightBoxInversionRequested = false ;
2016-08-26 22:50:01 +02:00
_g311_projectileDisableMovementTicks = 0 ;
_g312_lastProjectileDisabledMovementDirection = 0 ;
2016-07-07 00:46:51 +02:00
_g302_gameWon = false ;
_g327_newPartyMapIndex = kM1_mapIndexNone ;
2016-08-26 22:50:01 +02:00
_g325_setMousePointerToObjectInMainLoop = false ;
_g310_disabledMovementTicks = 0 ;
_g313_gameTime = 0 ;
_g353_stringBuildBuffer [ 0 ] = ' \0 ' ;
2016-07-12 11:30:25 +02:00
_g318_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 )
_g562_entranceDoorAnimSteps [ i ] = nullptr ;
_g564_interfaceCredits = nullptr ;
2016-04-26 14:44:01 +02:00
debug ( " DMEngine::DMEngine " ) ;
}
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-04-26 14:44:01 +02:00
2016-08-01 15:24:47 +02:00
for ( uint16 i = 0 ; i < k34_D13_soundCount ; + + i )
delete [ ] _gK24_soundData [ i ] . _firstSample ;
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-07-11 17:06:24 +02:00
void DMEngine : : f22_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
}
uint16 DMEngine : : f30_getScaledProduct ( uint16 val , uint16 scale , uint16 vale2 ) {
return ( ( uint32 ) val * vale2 ) > > scale ;
}
2016-08-26 22:47:44 +02:00
void DMEngine : : f463_initializeGame ( ) {
2016-08-11 16:06:06 +02:00
f448_initMemoryManager ( ) ;
2016-08-26 22:47:44 +02:00
_displayMan - > f479_loadGraphics ( ) ;
_displayMan - > f460_initializeGraphicData ( ) ;
2016-08-26 22:50:01 +02:00
_displayMan - > f94_loadFloorSet ( k0_FloorSetStone ) ;
_displayMan - > f95_loadWallSet ( k0_WallSetStone ) ;
2016-08-09 13:46:12 +02:00
f503_loadSounds ( ) ; // @ F0506_AMIGA_AllocateData
2016-08-09 08:27:21 +02:00
f437_STARTEND_drawTittle ( ) ;
2016-08-26 22:50:01 +02:00
_textMan - > f54_textInitialize ( ) ;
_objectMan - > loadObjectNames ( ) ;
2016-06-18 17:18:01 +02:00
_eventMan - > initMouse ( ) ;
2016-07-29 22:27:43 +02:00
do {
2016-07-20 16:42:37 +02:00
f441_processEntrance ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
} while ( f435_loadgame ( 1 ) ! = k1_LoadgameSuccess ) ;
2016-08-09 13:46:12 +02:00
_displayMan - > f466_loadIntoBitmap ( k11_MenuSpellAreLinesIndice , _menuMan - > _gK73_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
_displayMan - > f461_allocateFlippedWallBitmaps ( ) ;
2016-08-26 22:47:44 +02:00
f462_startGame ( ) ;
2016-08-26 22:50:01 +02:00
if ( _g298_newGame )
2016-07-25 16:13:53 +02:00
_moveSens - > f267_getMoveResult ( Thing : : _party , kM1_MapXNotOnASquare , 0 , _dungeonMan - > _g306_partyMapX , _dungeonMan - > _g307_partyMapY ) ;
2016-07-07 00:46:51 +02:00
_eventMan - > f78_showMouse ( ) ;
_eventMan - > f357_discardAllInput ( ) ;
2016-06-18 17:18:01 +02:00
}
2016-07-04 14:22:17 +02:00
void DMEngine : : f448_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-09 08:27:21 +02:00
warning ( false , " STUB METHOD: f448_initMemoryManager " ) ;
2016-08-15 07:58:04 +02:00
_displayMan - > f508_buildPaletteChangeCopperList ( palSwoosh , palSwoosh ) ;
2016-08-11 19:21:23 +02:00
for ( uint16 i = 0 ; i < 16 ; + + i ) {
2016-08-15 07:58:04 +02:00
_displayMan - > _g347_paletteTopAndBottomScreen [ i ] = _displayMan - > _palDungeonView [ 0 ] [ i ] ;
_displayMan - > _g346_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-07-04 14:22:17 +02:00
void DMEngine : : f462_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-26 22:43:17 +02:00
_g331_pressingEye = false ;
_g332_stopPressingEye = false ;
_g333_pressingMouth = false ;
_g334_stopPressingMouth = false ;
_g340_highlightBoxInversionRequested = false ;
2016-07-02 02:58:44 +02:00
_eventMan - > _g341_highlightBoxEnabled = false ;
2016-07-02 01:55:48 +02:00
_championMan - > _g300_partyIsSleeping = false ;
2016-08-26 22:47:44 +02:00
_championMan - > _g506_actingChampionOrdinal = M0_indexToOrdinal ( kM1_ChampionNone ) ;
2016-07-02 12:57:31 +02:00
_menuMan - > _g509_actionAreaContainsIcons = true ;
2016-08-26 22:47:44 +02:00
_eventMan - > _g599_useChampionIconOrdinalAsMousePointerBitmap = M0_indexToOrdinal ( kM1_ChampionNone ) ;
2016-06-18 19:42:05 +02:00
2016-07-02 02:58:44 +02:00
_eventMan - > _g441_primaryMouseInput = g447_PrimaryMouseInput_Interface ;
_eventMan - > _g442_secondaryMouseInput = g448_SecondaryMouseInput_Movement ;
2016-07-11 10:52:38 +02:00
_eventMan - > _g443_primaryKeyboardInput = g458_primaryKeyboardInput_interface ;
_eventMan - > _g444_secondaryKeyboardInput = g459_secondaryKeyboardInput_movement ;
2016-06-18 19:42:05 +02:00
2016-08-26 22:47:44 +02:00
f3_processNewPartyMap ( _dungeonMan - > _g309_partyMapIndex ) ;
2016-06-18 17:18:01 +02:00
2016-07-02 13:47:19 +02:00
if ( ! _g298_newGame ) {
2016-08-11 19:21:23 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _g347_paletteTopAndBottomScreen ) ;
2016-07-26 00:18:31 +02:00
_displayMan - > _g578_useByteBoxCoordinates = false ;
f22_delay ( 1 ) ;
2016-07-30 10:26:23 +02:00
_displayMan - > D24_fillScreenBox ( boxScreenTop , k0_ColorBlack ) ;
_displayMan - > D24_fillScreenBox ( boxScreenRight , k0_ColorBlack ) ;
_displayMan - > D24_fillScreenBox ( boxScreenBottom , k0_ColorBlack ) ;
2016-06-19 00:49:23 +02:00
} else {
2016-07-02 00:27:05 +02:00
_displayMan - > _g578_useByteBoxCoordinates = false ;
2016-07-30 10:26:23 +02:00
_displayMan - > D24_fillScreenBox ( boxScreenTop , k0_ColorBlack ) ;
_displayMan - > D24_fillScreenBox ( boxScreenRight , k0_ColorBlack ) ;
_displayMan - > D24_fillScreenBox ( boxScreenBottom , k0_ColorBlack ) ;
2016-06-18 19:42:05 +02:00
}
2016-06-18 17:18:01 +02:00
2016-08-15 07:58:04 +02:00
_displayMan - > f508_buildPaletteChangeCopperList ( _displayMan - > _palDungeonView [ 0 ] , _displayMan - > _g347_paletteTopAndBottomScreen ) ;
2016-08-26 22:47:44 +02:00
_menuMan - > f395_drawMovementArrows ( ) ;
_championMan - > f278_resetDataToStartGame ( ) ;
2016-08-26 22:43:17 +02:00
_g301_gameTimeTicking = true ;
2016-06-18 17:18:01 +02:00
}
2016-05-03 17:55:04 +02:00
2016-08-26 22:47:44 +02:00
void DMEngine : : f3_processNewPartyMap ( uint16 mapIndex ) {
2016-08-26 22:50:01 +02:00
_groupMan - > f194_removeAllActiveGroups ( ) ;
2016-08-26 22:47:44 +02:00
_dungeonMan - > f174_setCurrentMapAndPartyMap ( mapIndex ) ;
_displayMan - > f96_loadCurrentMapGraphics ( ) ;
2016-08-26 22:50:01 +02:00
_groupMan - > f195_addAllActiveGroups ( ) ;
2016-07-07 00:46:51 +02:00
_inventoryMan - > f337_setDungeonViewPalette ( ) ;
2016-06-18 19:58:19 +02:00
}
2016-04-26 14:44:01 +02:00
Common : : Error DMEngine : : run ( ) {
2016-06-29 23:17:04 +02:00
initArrays ( ) ;
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-05-15 17:52:39 +02:00
_displayMan - > setUpScreens ( 320 , 200 ) ;
2016-07-22 21:33:45 +02:00
f463_initializeGame ( ) ;
2016-06-18 17:18:01 +02:00
while ( true ) {
2016-08-26 22:47:44 +02:00
f2_gameloop ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return Common : : kNoError ;
f444_endGame ( _championMan - > _g303_partyDead ) ;
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-26 22:47:44 +02:00
void DMEngine : : f2_gameloop ( ) {
2016-07-30 11:20:47 +02:00
//HACK: Remove this block to get real starting position in the Hall of Champions
2016-07-26 00:18:31 +02:00
if ( _g298_newGame ) {
warning ( false , " DUMMY CODE: SETTING PARTY POS AND DIRECTION " ) ;
_dungeonMan - > _g306_partyMapX = 9 ;
_dungeonMan - > _g307_partyMapY = 9 ;
_dungeonMan - > _g308_partyDir = kDirWest ;
}
2016-07-07 00:46:51 +02:00
2016-07-12 11:30:25 +02:00
_g318_waitForInputMaxVerticalBlankCount = 10 ;
2016-05-02 20:58:55 +02:00
while ( true ) {
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
2016-08-10 14:44:54 +02:00
2016-08-26 22:51:17 +02:00
// DEBUG CODE
for ( int16 i = 0 ; i < _championMan - > _g305_partyChampionCount ; + + i ) {
Champion & champ = _championMan - > _gK71_champions [ i ] ;
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-07-30 10:37:29 +02:00
if ( _g327_newPartyMapIndex ! = kM1_mapIndexNone ) {
f3_processNewPartyMap ( _g327_newPartyMapIndex ) ;
_moveSens - > f267_getMoveResult ( Thing : : _party , kM1_MapXNotOnASquare , 0 , _dungeonMan - > _g306_partyMapX , _dungeonMan - > _g307_partyMapY ) ;
_g327_newPartyMapIndex = kM1_mapIndexNone ;
_eventMan - > f357_discardAllInput ( ) ;
}
_timeline - > f261_processTimeline ( ) ;
if ( _g327_newPartyMapIndex = = kM1_mapIndexNone )
break ;
}
2016-08-26 22:50:01 +02:00
2016-08-26 22:50:13 +02:00
if ( ! _inventoryMan - > _g432_inventoryChampionOrdinal & & ! _championMan - > _g300_partyIsSleeping ) {
Box box ( 0 , 223 , 0 , 135 ) ;
2016-08-26 22:50:30 +02:00
warning ( false , " DUMMY CODE: clearing screen to black " ) ;
2016-08-26 22:50:13 +02:00
_displayMan - > f135_fillBoxBitmap ( _displayMan - > _g296_bitmapViewport , box , k0_ColorBlack , k112_byteWidthViewport , k136_heightViewport ) ; // dummy code
_displayMan - > f128_drawDungeon ( _dungeonMan - > _g308_partyDir , _dungeonMan - > _g306_partyMapX , _dungeonMan - > _g307_partyMapY ) ;
if ( _g325_setMousePointerToObjectInMainLoop ) {
_g325_setMousePointerToObjectInMainLoop = false ;
_eventMan - > f78_showMouse ( ) ;
_eventMan - > f68_setPointerToObject ( _objectMan - > _g412_objectIconForMousePointer ) ;
_eventMan - > f77_hideMouse ( ) ;
2016-07-11 11:37:01 +02:00
2016-08-26 22:50:13 +02:00
}
if ( _eventMan - > _g326_refreshMousePointerInMainLoop ) {
_eventMan - > _g326_refreshMousePointerInMainLoop = false ;
_eventMan - > _g598_mousePointerBitmapUpdated = true ;
_eventMan - > f78_showMouse ( ) ;
_eventMan - > f77_hideMouse ( ) ;
}
}
2016-08-09 08:40:29 +02:00
_eventMan - > f363_highlightBoxDisable ( ) ;
2016-08-01 22:23:11 +02:00
f65_playPendingSound ( ) ;
2016-07-13 19:51:14 +02:00
_championMan - > f320_applyAndDrawPendingDamageAndWounds ( ) ;
2016-08-26 22:50:01 +02:00
if ( _championMan - > _g303_partyDead )
break ;
2016-07-30 11:20:47 +02:00
2016-07-07 00:46:51 +02:00
_g313_gameTime + + ;
2016-08-26 22:50:01 +02:00
if ( ! ( _g313_gameTime & 511 ) )
2016-07-11 15:20:00 +02:00
_inventoryMan - > f338_decreaseTorchesLightPower ( ) ;
2016-07-12 08:53:34 +02:00
if ( _championMan - > _g407_party . _freezeLifeTicks )
2016-08-26 22:50:01 +02:00
_championMan - > _g407_party . _freezeLifeTicks - = 1 ;
2016-07-12 08:53:34 +02:00
2016-08-26 22:47:44 +02:00
_menuMan - > f390_refreshActionAreaAndSetChampDirMaxDamageReceived ( ) ;
2016-08-26 22:38:51 +02:00
2016-07-30 10:26:23 +02:00
if ( ! ( _g313_gameTime & ( _championMan - > _g300_partyIsSleeping ? 15 : 63 ) ) )
2016-07-14 14:13:41 +02:00
_championMan - > f331_applyTimeEffects ( ) ;
2016-07-12 08:53:34 +02:00
if ( _g310_disabledMovementTicks )
_g310_disabledMovementTicks - - ;
2016-07-13 19:12:55 +02:00
if ( _g311_projectileDisableMovementTicks )
_g311_projectileDisableMovementTicks - - ;
2016-07-07 00:46:51 +02:00
2016-07-14 15:53:07 +02:00
_textMan - > f44_messageAreaClearExpiredRows ( ) ;
2016-07-07 00:46:51 +02:00
_g321_stopWaitingForPlayerInput = false ;
2016-07-13 19:12:55 +02:00
uint16 vblankCounter = 0 ;
2016-07-11 14:55:56 +02:00
do {
_eventMan - > processInput ( ) ;
if ( _g332_stopPressingEye ) {
_g331_pressingEye = false ;
_g332_stopPressingEye = false ;
_inventoryMan - > f353_drawStopPressingEye ( ) ;
} else if ( _g334_stopPressingMouth ) {
_g333_pressingMouth = false ;
_g334_stopPressingMouth = false ;
_inventoryMan - > f350_drawStopPressingMouth ( ) ;
}
_eventMan - > f380_processCommandQueue ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
2016-07-11 14:55:56 +02:00
_displayMan - > updateScreen ( ) ;
2016-08-09 08:40:29 +02:00
if ( ! _g321_stopWaitingForPlayerInput ) {
_eventMan - > f363_highlightBoxDisable ( ) ;
}
2016-07-02 23:10:05 +02:00
2016-07-13 19:12:55 +02:00
_system - > delayMillis ( 2 ) ;
if ( + + vblankCounter > = _g318_waitForInputMaxVerticalBlankCount * 5 )
_g321_stopWaitingForPlayerInput = true ;
} while ( ! _g321_stopWaitingForPlayerInput | | ! _g301_gameTimeTicking ) ;
2016-05-02 20:58:55 +02:00
}
2016-06-16 23:48:18 +02:00
}
2016-08-26 22:47:44 +02:00
int16 DMEngine : : M1_ordinalToIndex ( int16 val ) {
2016-06-23 23:12:39 +02:00
return val - 1 ;
}
2016-08-26 22:47:44 +02:00
int16 DMEngine : : M0_indexToOrdinal ( int16 val ) {
2016-06-23 23:12:39 +02:00
return val + 1 ;
}
2016-07-20 16:42:37 +02:00
void DMEngine : : f441_processEntrance ( ) {
_eventMan - > _g441_primaryMouseInput = g445_PrimaryMouseInput_Entrance ;
_eventMan - > _g442_secondaryMouseInput = nullptr ;
_eventMan - > _g443_primaryKeyboardInput = nullptr ;
_eventMan - > _g444_secondaryKeyboardInput = nullptr ;
_g562_entranceDoorAnimSteps [ 0 ] = new byte [ 128 * 161 * 12 ] ;
2016-07-30 10:26:23 +02:00
for ( uint16 idx = 1 ; idx < 8 ; idx + + )
_g562_entranceDoorAnimSteps [ idx ] = _g562_entranceDoorAnimSteps [ idx - 1 ] + 128 * 161 ;
2016-07-20 16:42:37 +02:00
_g562_entranceDoorAnimSteps [ 8 ] = _g562_entranceDoorAnimSteps [ 7 ] + 128 * 161 ;
_g562_entranceDoorAnimSteps [ 9 ] = _g562_entranceDoorAnimSteps [ 8 ] + 128 * 161 * 2 ;
_displayMan - > f466_loadIntoBitmap ( k3_entranceRightDoorGraphicIndice , _g562_entranceDoorAnimSteps [ 4 ] ) ;
_displayMan - > f466_loadIntoBitmap ( k2_entranceLeftDoorGraphicIndice , _g562_entranceDoorAnimSteps [ 0 ] ) ;
_g564_interfaceCredits = _displayMan - > f489_getNativeBitmapOrGraphic ( k5_creditsGraphicIndice ) ;
_displayMan - > _g578_useByteBoxCoordinates = false ;
2016-07-30 10:26:23 +02:00
Box displayBox ;
displayBox . _x1 = 0 ;
displayBox . _x2 = 100 ;
displayBox . _y1 = 0 ;
displayBox . _y2 = 160 ;
for ( uint16 idx = 1 ; idx < 4 ; idx + + ) {
_displayMan - > f132_blitToBitmap ( _g562_entranceDoorAnimSteps [ 0 ] , _g562_entranceDoorAnimSteps [ idx ] , displayBox , idx < < 2 , 0 , k64_byteWidth , k64_byteWidth , kM1_ColorNoTransparency , 161 , 161 ) ;
displayBox . _x2 - = 4 ;
2016-07-20 16:42:37 +02:00
}
2016-07-30 10:26:23 +02:00
displayBox . _x2 = 127 ;
for ( uint16 idx = 5 ; idx < 8 ; idx + + ) {
displayBox . _x1 + = 4 ;
_displayMan - > f132_blitToBitmap ( _g562_entranceDoorAnimSteps [ 4 ] , _g562_entranceDoorAnimSteps [ idx ] , displayBox , 0 , 0 , k64_byteWidth , k64_byteWidth , kM1_ColorNoTransparency , 161 , 161 ) ;
2016-07-20 16:42:37 +02:00
}
2016-07-30 10:26:23 +02:00
2016-07-20 16:42:37 +02:00
do {
f439_drawEntrance ( ) ;
_eventMan - > f78_showMouse ( ) ;
_eventMan - > f357_discardAllInput ( ) ;
_g298_newGame = k99_modeWaitingOnEntrance ;
do {
_eventMan - > processInput ( ) ;
2016-07-29 22:27:43 +02:00
if ( _engineShouldQuit )
return ;
2016-07-20 16:42:37 +02:00
_eventMan - > f380_processCommandQueue ( ) ;
_displayMan - > updateScreen ( ) ;
} while ( _g298_newGame = = k99_modeWaitingOnEntrance ) ;
} while ( _g298_newGame = = k202_CommandEntranceDrawCredits ) ;
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-07-30 10:26:23 +02:00
f060_SOUND_Play ( k01_soundSWITCH , 112 , 0x40 , 0x40 ) ;
2016-07-20 16:42:37 +02:00
f22_delay ( 20 ) ;
_eventMan - > f78_showMouse ( ) ;
2016-07-30 10:26:23 +02:00
if ( _g298_newGame )
f438_STARTEND_OpenEntranceDoors ( ) ;
2016-07-20 16:42:37 +02:00
delete [ ] _g562_entranceDoorAnimSteps [ 0 ] ;
for ( uint16 i = 0 ; i < 10 ; + + i )
_g562_entranceDoorAnimSteps [ i ] = nullptr ;
}
2016-07-29 22:27:43 +02:00
void DMEngine : : f444_endGame ( bool doNotDrawCreditsOnly ) {
// TODO: localization
2016-07-30 11:20:47 +02:00
static Box restartOuterBox = Box ( 103 , 217 , 145 , 159 ) ;
static Box restartInnerBox = Box ( 105 , 215 , 147 , 157 ) ;
static Box theEndBox = Box ( 120 , 199 , 95 , 108 ) ;
static Box championMirrorBox = Box ( 11 , 74 , 7 , 49 ) ;
static Box championPortraitBox = Box ( 27 , 58 , 13 , 41 ) ;
bool waitBeforeDrawingRestart = true ;
2016-07-29 22:27:43 +02:00
_eventMan - > f67_setMousePointerToNormal ( k0_pointerArrow ) ;
_eventMan - > f78_showMouse ( ) ;
_eventMan - > _g441_primaryMouseInput = nullptr ;
_eventMan - > _g442_secondaryMouseInput = nullptr ;
_eventMan - > _g443_primaryKeyboardInput = nullptr ;
_eventMan - > _g444_secondaryKeyboardInput = nullptr ;
if ( doNotDrawCreditsOnly & & ! _g302_gameWon ) {
f064_SOUND_RequestPlay_CPSD ( k06_soundSCREAM , _dungeonMan - > _g306_partyMapX , _dungeonMan - > _g307_partyMapY , k0_soundModePlayImmediately ) ;
f22_delay ( 240 ) ;
}
2016-08-09 08:40:29 +02:00
2016-07-29 22:27:43 +02:00
if ( _displayMan - > _g322_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-07-30 11:20:47 +02:00
oldPalTopAndBottomScreen [ i ] = _displayMan - > _g347_paletteTopAndBottomScreen [ i ] ;
for ( int i = 0 ; i < = 7 ; i + + ) {
2016-07-29 22:27:43 +02:00
f22_delay ( 1 ) ;
2016-07-30 11:20:47 +02:00
for ( int colIdx = 0 ; colIdx < 16 ; colIdx + + ) {
_displayMan - > _g346_paletteMiddleScreen [ colIdx ] = _displayMan - > f431_getDarkenedColor ( _displayMan - > _g346_paletteMiddleScreen [ colIdx ] ) ;
_displayMan - > _g347_paletteTopAndBottomScreen [ colIdx ] = _displayMan - > f431_getDarkenedColor ( _displayMan - > _g347_paletteTopAndBottomScreen [ colIdx ] ) ;
2016-07-29 22:27:43 +02:00
}
}
_displayMan - > _g322_paletteSwitchingEnabled = false ;
f22_delay ( 1 ) ;
for ( uint16 i = 0 ; i < 16 ; + + i )
2016-07-30 11:20:47 +02:00
_displayMan - > _g347_paletteTopAndBottomScreen [ i ] = oldPalTopAndBottomScreen [ i ] ;
2016-07-30 10:26:23 +02:00
} else
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _g345_aui_BlankBuffer ) ;
2016-07-30 11:20:47 +02:00
uint16 darkBluePalette [ 16 ] ;
2016-07-29 22:27:43 +02:00
if ( doNotDrawCreditsOnly ) {
if ( _g302_gameWon ) {
// Strangerke: Related to portraits. Game data could be missing for earlier versions of the game.
_displayMan - > fillScreen ( k12_ColorDarkestGray ) ;
2016-07-30 11:20:47 +02:00
for ( int16 championIndex = k0_ChampionFirst ; championIndex < _championMan - > _g305_partyChampionCount ; championIndex + + ) {
int16 textPosY = championIndex * 48 ;
Champion * curChampion = & _championMan - > _gK71_champions [ championIndex ] ;
_displayMan - > f21_blitToScreen ( _displayMan - > f489_getNativeBitmapOrGraphic ( k208_wallOrn_43_champMirror ) , & championMirrorBox , k32_byteWidth , k10_ColorFlesh , 43 ) ;
_displayMan - > f21_blitToScreen ( curChampion - > _portrait , & championPortraitBox , k16_byteWidth , k1_ColorDarkGary , 29 ) ;
_textMan - > f443_endgamePrintString ( 87 , textPosY + = 14 , k9_ColorGold , curChampion - > _name ) ;
int textPosX = ( 6 * strlen ( curChampion - > _name ) ) + 87 ;
char championTitleFirstCharacter = curChampion - > _title [ 0 ] ;
if ( ( championTitleFirstCharacter ! = ' , ' ) & & ( championTitleFirstCharacter ! = ' ; ' ) & & ( championTitleFirstCharacter ! = ' - ' ) )
textPosX + = 6 ;
_textMan - > f443_endgamePrintString ( textPosX , textPosY + + , k9_ColorGold , curChampion - > _title ) ;
for ( int16 idx = k0_ChampionSkillFighter ; idx < = k3_ChampionSkillWizard ; idx + + ) {
uint16 skillLevel = MIN < uint16 > ( 16 , _championMan - > f303_getSkillLevel ( championIndex , idx | ( k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience ) ) ) ;
if ( skillLevel = = 1 )
2016-07-29 22:27:43 +02:00
continue ;
2016-07-30 11:20:47 +02:00
char displStr [ 20 ] ;
strcpy ( displStr , G0428_apc_SkillLevelNames [ skillLevel - 2 ] ) ;
strcat ( displStr , " " ) ;
strcat ( displStr , g417_baseSkillName [ idx ] ) ;
_textMan - > f443_endgamePrintString ( 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-07-30 10:26:23 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _g347_paletteTopAndBottomScreen ) ;
2016-07-29 22:27:43 +02:00
_engineShouldQuit = true ;
return ;
}
T0444017 :
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-07-30 11:20:47 +02:00
_displayMan - > f21_blitToScreen ( _displayMan - > f489_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 ;
_displayMan - > f436_STARTEND_FadeToPalette ( curPalette ) ;
2016-08-11 12:10:43 +02:00
_displayMan - > updateScreen ( ) ;
2016-07-30 11:20:47 +02:00
if ( waitBeforeDrawingRestart )
2016-07-29 22:27:43 +02:00
f22_delay ( 300 ) ;
if ( _g524_restartGameAllowed ) {
_displayMan - > _g578_useByteBoxCoordinates = false ;
2016-07-30 11:20:47 +02:00
_displayMan - > D24_fillScreenBox ( restartOuterBox , k12_ColorDarkestGray ) ;
_displayMan - > D24_fillScreenBox ( restartInnerBox , k0_ColorBlack ) ;
2016-08-15 11:56:21 +02:00
// TODO: localization
2016-07-29 22:27:43 +02:00
_textMan - > f53_printToLogicalScreen ( 110 , 154 , k4_ColorCyan , k0_ColorBlack , " RESTART THIS GAME " ) ;
2016-07-30 11:20:47 +02:00
curPalette [ 1 ] = D03_RGB_PINK ;
curPalette [ 4 ] = D09_RGB_WHITE ;
2016-07-29 22:27:43 +02:00
_eventMan - > _g441_primaryMouseInput = g446_PrimaryMouseInput_RestartGame ;
_eventMan - > f357_discardAllInput ( ) ;
_eventMan - > f77_hideMouse ( ) ;
2016-07-30 11:20:47 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( curPalette ) ;
for ( int16 verticalBlankCount = 900 ; - - verticalBlankCount & & ! _g523_restartGameRequest ; f22_delay ( 1 ) )
2016-07-29 22:27:43 +02:00
_eventMan - > f380_processCommandQueue ( ) ;
2016-07-30 11:20:47 +02:00
2016-07-29 22:27:43 +02:00
_eventMan - > f78_showMouse ( ) ;
if ( _g523_restartGameRequest ) {
2016-07-30 11:20:47 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( darkBluePalette ) ;
2016-07-29 22:27:43 +02:00
_displayMan - > fillScreen ( k0_ColorBlack ) ;
2016-08-15 07:58:04 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _palDungeonView [ 0 ] ) ;
2016-07-29 22:27:43 +02:00
_g298_newGame = k0_modeLoadSavedGame ;
if ( f435_loadgame ( 1 ) ! = kM1_LoadgameFailure ) {
f462_startGame ( ) ;
_g523_restartGameRequest = false ;
_eventMan - > f77_hideMouse ( ) ;
_eventMan - > f357_discardAllInput ( ) ;
return ;
}
}
}
2016-07-30 11:20:47 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( 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-12 14:55:35 +02:00
_displayMan - > f21_blitToScreen ( _displayMan - > f489_getNativeBitmapOrGraphic ( k5_creditsGraphicIndice ) , & box , k160_byteWidthScreen , kM1_ColorNoTransparency , k200_heightScreen ) ;
2016-07-30 10:26:23 +02:00
2016-08-15 07:58:04 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _palCredits ) ;
2016-07-29 22:27:43 +02:00
_eventMan - > f541_waitForMouseOrKeyActivity ( ) ;
if ( _engineShouldQuit )
return ;
if ( _g524_restartGameAllowed & & doNotDrawCreditsOnly ) {
2016-07-30 11:20:47 +02:00
waitBeforeDrawingRestart = false ;
_displayMan - > f436_STARTEND_FadeToPalette ( darkBluePalette ) ;
2016-07-29 22:27:43 +02:00
goto T0444017 ;
}
_engineShouldQuit = true ;
return ;
}
2016-07-20 16:42:37 +02:00
void DMEngine : : f439_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
_dungeonMan - > _g309_partyMapIndex = k255_mapIndexEntrance ;
_displayMan - > _g297_drawFloorAndCeilingRequested = true ;
_dungeonMan - > _g273_currMapWidth = 5 ;
_dungeonMan - > _g274_currMapHeight = 5 ;
2016-07-31 21:48:37 +02:00
_dungeonMan - > _g271_currMapData = microDungeonCurrentMapData ;
2016-07-20 16:42:37 +02:00
Map map ; // uninitialized, won't be used
2016-07-22 21:33:45 +02:00
_dungeonMan - > _g269_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-07-30 10:26:23 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _g345_aui_BlankBuffer ) ;
2016-07-20 16:42:37 +02:00
// note, a global variable is used here in the original
_displayMan - > f466_loadIntoBitmap ( k4_entranceGraphicIndice , _displayMan - > _g348_bitmapScreen ) ;
_displayMan - > f128_drawDungeon ( kDirSouth , 2 , 0 ) ;
warning ( false , " IGNORED CODE: G0324_B_DrawViewportRequested = false; " ) ;
2016-08-09 12:22:46 +02:00
if ( ! _savedScreenForOpenEntranceDoors )
_savedScreenForOpenEntranceDoors = new byte [ k200_heightScreen * k160_byteWidthScreen * 2 ] ;
memcpy ( _savedScreenForOpenEntranceDoors , _displayMan - > _g348_bitmapScreen , 320 * 200 ) ;
2016-07-31 21:48:37 +02:00
_displayMan - > _g578_useByteBoxCoordinates = false , _displayMan - > f132_blitToBitmap ( _displayMan - > _g348_bitmapScreen , _g562_entranceDoorAnimSteps [ 8 ] , doorsUpperHalfBox , 0 , 30 , k160_byteWidthScreen , k128_byteWidth , kM1_ColorNoTransparency , 200 , 161 ) ;
_displayMan - > _g578_useByteBoxCoordinates = false , _displayMan - > f132_blitToBitmap ( _displayMan - > _g348_bitmapScreen , _g562_entranceDoorAnimSteps [ 8 ] , doorsLowerHalfBox , 0 , 111 , k160_byteWidthScreen , k128_byteWidth , kM1_ColorNoTransparency , 200 , 161 ) ;
2016-07-20 16:42:37 +02:00
2016-07-31 21:48:37 +02:00
_displayMan - > f21_blitToScreen ( _g562_entranceDoorAnimSteps [ 0 ] , & closedDoorLeftBox , k64_byteWidth , kM1_ColorNoTransparency , 161 ) ;
_displayMan - > f21_blitToScreen ( _g562_entranceDoorAnimSteps [ 4 ] , & closedDoorRightBox , k64_byteWidth , kM1_ColorNoTransparency , 161 ) ;
2016-08-15 07:58:04 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( palEntrance ) ;
2016-07-20 16:42:37 +02:00
}
2016-08-09 11:54:04 +02:00
void DMEngine : : f438_STARTEND_OpenEntranceDoors ( ) {
2016-08-09 13:49:49 +02:00
Box rightDoorBox ( 109 , 231 , 30 , 193 ) ;
2016-08-09 11:54:04 +02:00
byte * rightDoorBitmap = _displayMan - > f489_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 ;
byte * leftDoorBitmap = _displayMan - > f489_getNativeBitmapOrGraphic ( k2_entranceLeftDoorGraphicIndice ) ;
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
f060_SOUND_Play ( k02_soundDOOR_RATTLE , 145 , 0x40 , 0x40 ) ;
}
2016-08-09 12:22:46 +02:00
_displayMan - > f21_blitToScreen ( _savedScreenForOpenEntranceDoors , & screenBox , 160 , kM1_ColorNoTransparency , 200 ) ;
2016-08-12 14:55:35 +02:00
_displayMan - > f132_blitToBitmap ( leftDoorBitmap , _displayMan - > _g348_bitmapScreen , leftDoorBox , leftDoorBlitFrom , 0 , 64 , k160_byteWidthScreen ,
kM1_ColorNoTransparency , 161 , k200_heightScreen ) ;
_displayMan - > f132_blitToBitmap ( rightDoorBitmap , _displayMan - > _g348_bitmapScreen , rightDoorBox , 0 , 0 , 64 , k160_byteWidthScreen ,
kM1_ColorNoTransparency , 161 , k200_heightScreen ) ;
2016-08-09 11:54:04 +02:00
_eventMan - > f357_discardAllInput ( ) ;
_displayMan - > updateScreen ( ) ;
leftDoorBox . _x2 - = 4 ;
leftDoorBlitFrom + = 4 ;
rightDoorBox . _x1 + = 4 ;
f22_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-12 16:29:52 +02:00
void DMEngine : : f442_SARTEND_processCommand202_entranceDrawCredits ( ) {
_eventMan - > f78_showMouse ( ) ;
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _g345_aui_BlankBuffer ) ;
_displayMan - > f466_loadIntoBitmap ( k5_creditsGraphicIndice , _displayMan - > _g348_bitmapScreen ) ;
2016-08-15 07:58:04 +02:00
_displayMan - > f436_STARTEND_FadeToPalette ( _displayMan - > _palCredits ) ;
2016-08-12 16:29:52 +02:00
f22_delay ( 50 ) ;
_eventMan - > f541_waitForMouseOrKeyActivity ( ) ;
_g298_newGame = k202_modeEntranceDrawCredits ;
}
2016-08-11 12:15:08 +02:00
void DMEngine : : f446_STARTEND_fuseSequnce ( ) {
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 ;
Group * L1428_ps_Group ;
Explosion * L1429_ps_Explosion ;
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 ] ;
_g302_gameWon = true ;
if ( _inventoryMan - > _g432_inventoryChampionOrdinal ) {
_inventoryMan - > f355_toggleInventory ( k4_ChampionCloseInventory ) ;
}
_eventMan - > f363_highlightBoxDisable ( ) ;
_championMan - > _g407_party . _magicalLightAmount = 200 ;
_inventoryMan - > f337_setDungeonViewPalette ( ) ;
_championMan - > _g407_party . _fireShieldDefense = _championMan - > _g407_party . _spellShieldDefense = _championMan - > _g407_party . _shieldDefense = 100 ;
_timeline - > f260_timelineRefreshAllChampionStatusBoxes ( ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
L1431_i_LordChaosMapX = _dungeonMan - > _g306_partyMapX ;
L1432_i_LordChaosMapY = _dungeonMan - > _g307_partyMapY ;
L1431_i_LordChaosMapX + = _dirIntoStepCountEast [ _dungeonMan - > _g308_partyDir ] , L1432_i_LordChaosMapY + = _dirIntoStepCountNorth [ _dungeonMan - > _g308_partyDir ] ;
L1428_ps_Group = ( Group * ) _dungeonMan - > f156_getThingData ( L1433_T_LordChaosThing = _groupMan - > f175_groupGetThing ( L1431_i_LordChaosMapX , L1432_i_LordChaosMapY ) ) ;
L1428_ps_Group - > _health [ 0 ] = 10000 ;
_dungeonMan - > f146_setGroupCells ( L1428_ps_Group , k255_CreatureTypeSingleCenteredCreature , _dungeonMan - > _g309_partyMapIndex ) ;
_dungeonMan - > f148_setGroupDirections ( L1428_ps_Group , returnOppositeDir ( _dungeonMan - > _g308_partyDir ) , _dungeonMan - > _g309_partyMapIndex ) ;
AL1424_B_RemoveFluxcagesFromLoadChaosSquare = true ;
AL1425_i_FluxcageMapX = _dungeonMan - > _g306_partyMapX ;
AL1426_i_FluxcageMapY = _dungeonMan - > _g307_partyMapY ;
T0446002 :
L1427_T_Thing = _dungeonMan - > f162_getSquareFirstObject ( AL1425_i_FluxcageMapX , AL1426_i_FluxcageMapY ) ;
while ( L1427_T_Thing ! = Thing : : _endOfList ) {
if ( L1427_T_Thing . getType ( ) = = k15_ExplosionThingType ) {
L1429_ps_Explosion = ( Explosion * ) _dungeonMan - > f156_getThingData ( L1427_T_Thing ) ;
if ( L1429_ps_Explosion - > getType ( ) = = k50_ExplosionType_Fluxcage ) {
_dungeonMan - > f164_unlinkThingFromList ( L1427_T_Thing , Thing ( 0 ) , AL1425_i_FluxcageMapX , AL1426_i_FluxcageMapY ) ;
L1429_ps_Explosion - > setNextThing ( Thing : : _none ) ;
goto T0446002 ;
}
}
L1427_T_Thing = _dungeonMan - > f159_getNextThing ( L1427_T_Thing ) ;
}
if ( AL1424_B_RemoveFluxcagesFromLoadChaosSquare ) {
AL1424_B_RemoveFluxcagesFromLoadChaosSquare = false ;
AL1425_i_FluxcageMapX = L1431_i_LordChaosMapX ;
AL1426_i_FluxcageMapY = L1432_i_LordChaosMapY ;
goto T0446002 ;
}
f445_STARTEND_fuseSequenceUpdate ( ) ;
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
_projexpl - > f213_explosionCreate ( Thing : : _explFireBall , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
}
f064_SOUND_RequestPlay_CPSD ( k17_soundBUZZ , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k1_soundModePlayIfPrioritized ) ;
L1428_ps_Group - > _type = k25_CreatureTypeLordOrder ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
_projexpl - > f213_explosionCreate ( Thing : : _explHarmNonMaterial , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
}
for ( AL1425_i_CycleCount = 4 ; - - AL1425_i_CycleCount ; ) {
for ( AL1424_i_CreatureTypeSwitchCount = 5 ; - - AL1424_i_CreatureTypeSwitchCount ; ) {
f064_SOUND_RequestPlay_CPSD ( k17_soundBUZZ , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k1_soundModePlayIfPrioritized ) ;
L1428_ps_Group - > _type = ( AL1424_i_CreatureTypeSwitchCount & 0x0001 ) ? k25_CreatureTypeLordOrder : k23_CreatureTypeLordChaos ;
for ( AL1426_i_FuseSequenceUpdateCount = AL1425_i_CycleCount ; AL1426_i_FuseSequenceUpdateCount - - ; f445_STARTEND_fuseSequenceUpdate ( ) ) ;
}
}
_projexpl - > f213_explosionCreate ( Thing : : _explFireBall , 255 , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
_projexpl - > f213_explosionCreate ( Thing : : _explHarmNonMaterial , 255 , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
L1428_ps_Group - > _type = k26_CreatureTypeGreyLord ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
_displayMan - > _g77_doNotDrawFluxcagesDuringEndgame = true ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
for ( AL1424_i_MapX = 0 ; AL1424_i_MapX < _dungeonMan - > _g273_currMapWidth ; AL1424_i_MapX + + ) {
for ( AL1425_i_MapY = 0 ; AL1425_i_MapY < _dungeonMan - > _g274_currMapHeight ; AL1425_i_MapY + + ) {
if ( ( ( L1427_T_Thing = _groupMan - > f175_groupGetThing ( AL1424_i_MapX , AL1425_i_MapY ) ) ! = Thing : : _endOfList ) & & ( ( AL1424_i_MapX ! = L1431_i_LordChaosMapX ) | | ( AL1425_i_MapY ! = L1432_i_LordChaosMapY ) ) ) {
_groupMan - > f189_delete ( AL1424_i_MapX , AL1425_i_MapY ) ;
}
}
}
f445_STARTEND_fuseSequenceUpdate ( ) ;
/* 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) */
L1427_T_Thing = _dungeonMan - > f161_getSquareFirstThing ( 0 , 0 ) ;
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 ;
}
L1427_T_Thing = _dungeonMan - > f159_getNextThing ( L1427_T_Thing ) ;
}
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 + + ) {
_dungeonMan - > f168_decodeText ( L1436_ac_String , L1435_aT_TextStringThings [ AL1425_i_TextStringThingIndex ] , ( TextType ) ( k1_TextTypeMessage | k0x8000_DecodeEvenIfInvisible ) ) ;
if ( L1436_ac_String [ 1 ] = = L1434_c_TextFirstCharacter ) {
_textMan - > f43_messageAreaClearAllRows ( ) ;
L1436_ac_String [ 1 ] = ' \n ' ; /* New line */
_textMan - > f47_messageAreaPrintMessage ( k15_ColorWhite , & L1436_ac_String [ 1 ] ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
f22_delay ( 780 ) ;
L1434_c_TextFirstCharacter + + ;
break ;
}
}
}
for ( AL1424_i_Attack = 55 ; AL1424_i_Attack < = 255 ; AL1424_i_Attack + = 40 ) {
_projexpl - > f213_explosionCreate ( Thing : : _explHarmNonMaterial , AL1424_i_Attack , L1431_i_LordChaosMapX , L1432_i_LordChaosMapY , k255_CreatureTypeSingleCenteredCreature ) ;
f445_STARTEND_fuseSequenceUpdate ( ) ;
}
2016-08-09 11:54:04 +02:00
2016-08-11 12:15:08 +02:00
f22_delay ( 600 ) ;
_g524_restartGameAllowed = false ;
f444_endGame ( true ) ;
}
2016-08-09 11:54:04 +02:00
2016-08-11 12:11:16 +02:00
void DMEngine : : f445_STARTEND_fuseSequenceUpdate ( ) {
_timeline - > f261_processTimeline ( ) ;
_displayMan - > f128_drawDungeon ( _dungeonMan - > _g308_partyDir , _dungeonMan - > _g306_partyMapX , _dungeonMan - > _g307_partyMapY ) ;
f65_playPendingSound ( ) ;
_eventMan - > f357_discardAllInput ( ) ;
_displayMan - > updateScreen ( ) ;
2016-08-15 10:42:21 +02:00
f22_delay ( 2 ) ;
2016-08-12 16:29:52 +02:00
_g313_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-15 11:56:21 +02:00
Common : : Language DMEngine : : getGameLanguage ( ) { return _gameVersion - > language ; }
2016-04-26 14:44:01 +02:00
} // End of namespace DM