2018-10-19 23:22:30 +11: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 .
*
*/
2019-05-20 21:13:04 +10:00
# include "common/config-manager.h"
2020-02-06 22:35:51 +11:00
# include "common/keyboard.h"
# include "common/language.h"
2018-10-19 23:22:30 +11:00
# include "engines/util.h"
# include "graphics/thumbnail.h"
# include "common/error.h"
2020-02-05 23:16:21 +11:00
# include "dragons/actor.h"
# include "dragons/actorresource.h"
# include "dragons/background.h"
# include "dragons/bigfile.h"
# include "dragons/cursor.h"
# include "dragons/credits.h"
# include "dragons/dragonflg.h"
# include "dragons/dragonimg.h"
# include "dragons/dragonini.h"
# include "dragons/dragonobd.h"
# include "dragons/dragonrms.h"
# include "dragons/dragonvar.h"
# include "dragons/dragons.h"
# include "dragons/font.h"
# include "dragons/inventory.h"
# include "dragons/scene.h"
# include "dragons/screen.h"
# include "dragons/sequenceopcodes.h"
# include "dragons/scriptopcodes.h"
# include "dragons/bag.h"
# include "dragons/talk.h"
# include "dragons/sound.h"
2020-03-04 22:42:56 +11:00
# include "dragons/strplayer.h"
2018-10-19 23:22:30 +11:00
namespace Dragons {
2018-12-13 22:30:30 +11:00
# define DRAGONS_TICK_INTERVAL 17
2019-01-15 07:19:54 +11:00
static DragonsEngine * _engine = nullptr ;
DragonsEngine * getEngine ( ) {
return _engine ;
}
2020-02-08 23:43:58 +11:00
DragonsEngine : : DragonsEngine ( OSystem * syst , const ADGameDescription * desc ) : Engine ( syst ) {
_language = desc - > language ;
2020-03-12 10:22:44 +11:00
_bigfileArchive = nullptr ;
_dragonRMS = nullptr ;
_backgroundResourceLoader = nullptr ;
_screen = nullptr ;
2018-12-18 22:52:18 +11:00
_sequenceOpcodes = new SequenceOpcodes ( this ) ;
2020-03-12 10:22:44 +11:00
_scriptOpcodes = nullptr ;
2019-01-15 07:19:54 +11:00
_engine = this ;
2019-03-03 22:25:00 +11:00
_inventory = new Inventory ( this ) ;
2019-03-05 21:39:44 +11:00
_cursor = new Cursor ( this ) ;
2020-03-12 10:22:44 +11:00
_credits = nullptr ;
_talk = nullptr ;
_fontManager = nullptr ;
_strPlayer = nullptr ;
_sceneUpdateFunction = nullptr ;
_vsyncUpdateFunction = nullptr ;
2019-03-17 10:25:40 +11:00
2019-03-19 20:49:34 +11:00
_leftMouseButtonUp = false ;
2019-09-05 22:40:07 +10:00
_leftMouseButtonDown = false ;
2019-03-17 10:25:40 +11:00
_rightMouseButtonUp = false ;
2019-03-20 00:09:29 +11:00
_iKeyUp = false ;
2019-08-17 10:38:43 +10:00
_downKeyUp = false ;
_upKeyUp = false ;
_enterKeyUp = false ;
2019-09-05 22:40:07 +10:00
_leftKeyDown = false ;
_leftKeyUp = false ;
_rightKeyDown = false ;
_rightKeyUp = false ;
2019-09-19 07:28:17 +10:00
_wKeyDown = false ;
_aKeyDown = false ;
_sKeyDown = false ;
_dKeyDown = false ;
_oKeyDown = false ;
_pKeyDown = false ;
2019-10-25 18:42:16 +11:00
_debugMode = false ;
2020-02-04 22:23:55 +11:00
_isGamePaused = false ;
2020-03-07 23:05:11 +11:00
_inMenu = false ;
2019-10-25 18:42:16 +11:00
2020-03-02 22:03:55 +11:00
_bit_flags_8006fbd8 = 0 ;
2019-05-19 20:30:58 +10:00
reset ( ) ;
2018-10-19 23:22:30 +11:00
}
DragonsEngine : : ~ DragonsEngine ( ) {
2018-12-18 22:52:18 +11:00
delete _sequenceOpcodes ;
2019-01-22 22:11:00 +11:00
delete _scriptOpcodes ;
2018-10-19 23:22:30 +11:00
}
2018-11-07 22:27:05 +11:00
void DragonsEngine : : updateEvents ( ) {
Common : : Event event ;
2019-03-19 20:49:34 +11:00
_leftMouseButtonUp = false ;
2019-03-17 10:25:40 +11:00
_rightMouseButtonUp = false ;
2019-03-20 00:09:29 +11:00
_iKeyUp = false ;
2019-08-17 10:38:43 +10:00
_downKeyUp = false ;
_upKeyUp = false ;
_enterKeyUp = false ;
2019-09-05 22:40:07 +10:00
_leftKeyUp = false ;
_rightKeyUp = false ;
2018-11-07 22:27:05 +11:00
while ( _eventMan - > pollEvent ( event ) ) {
// _input->processEvent(event);
switch ( event . type ) {
2020-02-07 17:26:38 +01:00
case Common : : EVENT_QUIT :
quitGame ( ) ;
break ;
case Common : : EVENT_MOUSEMOVE :
_cursor - > updatePosition ( event . mouse . x , event . mouse . y ) ;
break ;
case Common : : EVENT_LBUTTONUP :
_leftMouseButtonUp = true ;
_leftMouseButtonDown = false ;
break ;
case Common : : EVENT_LBUTTONDOWN :
_leftMouseButtonDown = true ;
break ;
case Common : : EVENT_RBUTTONUP :
_rightMouseButtonUp = true ;
break ;
case Common : : EVENT_KEYUP :
if ( event . kbd . keycode = = Common : : KEYCODE_i ) {
_iKeyUp = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_DOWN ) {
_downKeyUp = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_UP ) {
_upKeyUp = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_RETURN | |
event . kbd . keycode = = Common : : KEYCODE_KP_ENTER ) {
_enterKeyUp = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_LEFT ) {
_leftKeyUp = true ;
_leftKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_RIGHT ) {
_rightKeyUp = true ;
_rightKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_w ) {
_wKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_a ) {
_aKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_s ) {
_sKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_d ) {
_dKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_o ) {
_oKeyDown = false ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_p ) {
_pKeyDown = false ;
}
break ;
case Common : : EVENT_KEYDOWN :
if ( event . kbd . keycode = = Common : : KEYCODE_LEFT ) {
_leftKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_RIGHT ) {
_rightKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_w ) {
_wKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_a ) {
_aKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_s ) {
_sKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_d ) {
_dKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_o ) {
_oKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_p ) {
_pKeyDown = true ;
} else if ( event . kbd . keycode = = Common : : KEYCODE_TAB ) {
_debugMode = ! _debugMode ;
}
break ;
default :
break ;
2018-11-07 22:27:05 +11:00
}
}
}
2019-02-02 23:42:01 +11:00
2018-10-19 23:22:30 +11:00
Common : : Error DragonsEngine : : run ( ) {
2018-11-07 22:27:05 +11:00
_screen = new Screen ( ) ;
2020-02-08 23:43:58 +11:00
_bigfileArchive = new BigfileArchive ( this , " bigfile.dat " ) ;
2019-05-28 07:58:50 +10:00
_talk = new Talk ( this , _bigfileArchive ) ;
2019-01-26 22:36:45 +11:00
_dragonFLG = new DragonFLG ( _bigfileArchive ) ;
2020-02-07 15:25:30 +01:00
_dragonImg = new DragonImg ( _bigfileArchive ) ;
2019-01-22 22:11:00 +11:00
_dragonOBD = new DragonOBD ( _bigfileArchive ) ;
_dragonRMS = new DragonRMS ( _bigfileArchive , _dragonOBD ) ;
2019-01-26 22:36:45 +11:00
_dragonVAR = new DragonVAR ( _bigfileArchive ) ;
2018-11-07 22:27:05 +11:00
_dragonINIResource = new DragonINIResource ( _bigfileArchive ) ;
2019-07-05 20:31:52 +10:00
_fontManager = new FontManager ( this , _screen , _bigfileArchive ) ;
2019-12-10 22:38:53 +11:00
_credits = new Credits ( this , _fontManager , _bigfileArchive ) ;
2018-12-03 18:06:01 +11:00
ActorResourceLoader * actorResourceLoader = new ActorResourceLoader ( _bigfileArchive ) ;
2018-12-18 10:28:15 +11:00
_actorManager = new ActorManager ( actorResourceLoader ) ;
2019-01-26 22:36:45 +11:00
_scriptOpcodes = new ScriptOpcodes ( this , _dragonFLG ) ;
2019-05-02 22:12:04 +10:00
_backgroundResourceLoader = new BackgroundResourceLoader ( _bigfileArchive , _dragonRMS ) ;
2020-02-05 23:16:21 +11:00
_scene = new Scene ( this , _screen , _scriptOpcodes , _actorManager , _dragonRMS , _dragonINIResource , _backgroundResourceLoader ) ;
2018-11-07 22:27:05 +11:00
2019-12-16 10:21:02 +11:00
_sound = new SoundManager ( this , _bigfileArchive , _dragonRMS ) ;
2020-03-04 22:42:56 +11:00
_strPlayer = new StrPlayer ( this , _screen ) ;
2019-12-11 20:23:56 +00:00
2019-05-20 21:13:04 +10:00
if ( ConfMan . hasKey ( " save_slot " ) ) {
loadGameState ( ConfMan . getInt ( " save_slot " ) ) ;
} else {
2020-03-04 22:42:56 +11:00
_strPlayer - > playVideo ( " crystald.str " ) ;
2020-03-06 10:21:26 +11:00
_strPlayer - > playVideo ( " illusion.str " ) ;
2020-03-04 22:42:56 +11:00
_strPlayer - > playVideo ( " labintro.str " ) ;
2020-03-07 23:05:11 +11:00
init ( ) ;
mainMenu ( ) ;
2019-05-20 21:13:04 +10:00
loadScene ( 0 ) ;
}
2018-11-07 22:27:05 +11:00
_scene - > draw ( ) ;
_screen - > updateScreen ( ) ;
2018-12-13 22:30:30 +11:00
gameLoop ( ) ;
2018-11-07 22:27:05 +11:00
2018-12-18 10:28:15 +11:00
delete _scene ;
delete _actorManager ;
2018-11-07 22:27:05 +11:00
delete _backgroundResourceLoader ;
2019-01-26 22:36:45 +11:00
delete _dragonFLG ;
2020-02-07 15:25:30 +01:00
delete _dragonImg ;
2018-11-07 22:27:05 +11:00
delete _dragonRMS ;
2019-01-26 22:36:45 +11:00
delete _dragonVAR ;
2019-07-05 20:31:52 +10:00
delete _fontManager ;
2018-11-07 22:27:05 +11:00
delete _bigfileArchive ;
delete _screen ;
2019-12-16 10:21:02 +11:00
delete _sound ;
2020-03-04 22:42:56 +11:00
delete _strPlayer ;
2018-11-07 22:27:05 +11:00
2018-10-19 23:22:30 +11:00
debug ( " Ok " ) ;
return Common : : kNoError ;
}
2020-02-07 23:05:14 +11:00
uint16 DragonsEngine : : ipt_img_file_related ( ) {
2020-02-07 17:26:38 +01:00
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
2019-03-20 00:09:29 +11:00
assert ( flicker ) ;
2019-03-19 20:49:34 +11:00
2020-02-07 14:31:14 +01:00
int16 tileX = flicker - > actor - > _x_pos / 32 ;
int16 tileY = flicker - > actor - > _y_pos / 8 ;
2019-03-19 20:49:34 +11:00
2020-02-07 18:06:57 +01:00
for ( int i = 0 ; i < _dragonINIResource - > totalRecords ( ) ; i + + ) {
2020-02-07 23:05:14 +11:00
DragonINI * ini = getINI ( i ) ;
2020-02-20 09:57:29 +11:00
if ( ( ini - > sceneId = = getCurrentSceneId ( ) ) & & ( ini - > flags = = 0 ) ) {
Img * img = _dragonImg - > getImg ( ini - > imgId ) ;
2019-03-20 00:09:29 +11:00
if ( ( img - > x < = tileX ) & & ( ( ( tileX < = img - > x + img - > w & & ( img - > y < = tileY ) ) & & ( tileY < = img - > y + img - > h ) ) ) ) {
return i + 1 ;
}
}
}
return 0 ;
}
2019-03-19 20:49:34 +11:00
2020-02-07 23:05:14 +11:00
void DragonsEngine : : gameLoop ( ) {
2020-02-11 22:42:37 +11:00
uint16 prevImgIniId = 0 ;
2020-02-14 23:02:47 +11:00
InventoryState uVar6 ;
InventoryState uVar7 ;
2020-02-06 22:35:51 +11:00
uint16 sequenceId ;
2019-03-19 20:49:34 +11:00
2019-05-01 13:25:51 +10:00
_cursor - > _cursorActivationSeqOffset = 0 ;
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 0 ;
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-03-19 20:49:34 +11:00
setFlags ( ENGINE_FLAG_8 ) ;
2020-02-07 08:34:58 +11:00
while ( ! shouldQuit ( ) ) {
2019-03-20 00:09:29 +11:00
_scene - > draw ( ) ;
_screen - > updateScreen ( ) ;
2019-03-19 20:49:34 +11:00
wait ( ) ;
2019-03-20 00:09:29 +11:00
updateHandler ( ) ;
updateEvents ( ) ;
2019-07-19 07:44:41 +10:00
runSceneUpdaterFunction ( ) ; //TODO is this the right place for this logic?
2019-03-20 00:09:29 +11:00
if ( getCurrentSceneId ( ) ! = 2 ) {
_sceneId1 = getCurrentSceneId ( ) ;
2019-03-19 20:49:34 +11:00
}
2019-03-20 00:09:29 +11:00
2020-02-11 22:03:06 +11:00
updateFlickerIdleAnimation ( ) ;
2020-02-07 16:48:53 +01:00
if ( _bit_flags_8006fbd8 = = 0 ) {
2019-03-19 20:49:34 +11:00
setFlags ( ENGINE_FLAG_8 ) ;
}
2019-03-20 00:09:29 +11:00
if ( _dragonINIResource - > getFlickerRecord ( ) - > sceneId = = getCurrentSceneId ( ) ) {
2020-02-11 22:42:37 +11:00
uint16 imgIniId = ipt_img_file_related ( ) ;
if ( imgIniId ! = 0 & & imgIniId ! = ( prevImgIniId & 0xffff ) ) {
byte * obd = _dragonOBD - > getFromOpt ( imgIniId - 1 ) ;
2019-11-18 20:31:17 +11:00
ScriptOpCall scriptOpCall ( obd + 8 , READ_LE_UINT32 ( obd ) ) ;
2019-05-27 11:59:08 +10:00
2020-02-07 08:34:58 +11:00
if ( _scriptOpcodes - > runScript4 ( scriptOpCall ) ) {
2019-05-27 11:59:08 +10:00
scriptOpCall . _codeEnd = scriptOpCall . _code + 4 + READ_LE_UINT16 ( scriptOpCall . _code + 2 ) ;
scriptOpCall . _code + = 4 ;
_scriptOpcodes - > runScript ( scriptOpCall ) ;
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-05-27 11:59:08 +10:00
}
2019-03-19 20:49:34 +11:00
}
2020-02-11 22:42:37 +11:00
prevImgIniId = imgIniId ;
2020-02-07 17:26:38 +01:00
} else {
2020-02-11 22:42:37 +11:00
prevImgIniId = 0 ;
2019-03-19 20:49:34 +11:00
}
2019-03-21 23:15:52 +11:00
2019-03-20 00:09:29 +11:00
if ( _cursor - > updateINIUnderCursor ( ) = = 0 | |
2020-02-20 09:57:29 +11:00
( ! ( _cursor - > _iniUnderCursor & 0x8000 ) & & ( getINI ( _cursor - > _iniUnderCursor - 1 ) - > flags & 0x4000 ) ! = 0 ) ) { //TODO check this. This logic looks a bit strange.
2019-05-01 13:25:51 +10:00
_cursor - > _cursorActivationSeqOffset = 0 ;
2020-02-07 17:26:38 +01:00
} else {
2019-05-01 13:25:51 +10:00
_cursor - > _cursorActivationSeqOffset = 5 ;
2019-03-19 20:49:34 +11:00
}
2019-03-20 00:09:29 +11:00
if ( _rightMouseButtonUp & & isInputEnabled ( ) ) {
_cursor - > selectPreviousCursor ( ) ;
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-03-19 20:49:34 +11:00
continue ;
}
2019-03-20 00:09:29 +11:00
// TODO implement cycle cursor up.
// actorId = CheckButtonMapPress_CycleUp(0);
// if (((actorId & 0xffff) != 0) && isInputEnabled()) {
// _cursor->_sequenceID = _cursor->_sequenceID + 1;
2020-02-07 15:25:30 +01:00
// if (_cursor->_iniItemInHand == 0) {
2019-03-20 00:09:29 +11:00
// bVar1 = _cursor->_sequenceID < 5;
// }
// else {
// bVar1 = _cursor->_sequenceID < 6;
// }
// if (!bVar1) {
// _cursor->_sequenceID = 0;
// }
// if ((_cursor->_sequenceID == 0) && ((_inventory->getType() == 1 || (_inventory->getType() == 2)))) {
// _cursor->_sequenceID = 1;
// }
// if (_cursor->_sequenceID == 2) {
// if (_inventory->getType() == 1) {
// _cursor->_sequenceID = 4;
// }
// uVar6 = 3;
// if (_cursor->_sequenceID == 2) goto LAB_80026fb0;
// }
2020-02-11 10:21:09 +11:00
// _flickerIdleCounter = 0;
2019-03-20 00:09:29 +11:00
// actorId = uVar3;
// continue;
// }
2020-02-07 16:48:53 +01:00
if ( _bit_flags_8006fbd8 = = 3 ) {
_bit_flags_8006fbd8 = 0 ;
2019-03-20 00:09:29 +11:00
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
2020-02-08 14:25:17 +11:00
if ( flicker - > sceneId = = getCurrentSceneId ( ) & & flicker - > actor - > _direction ! = - 1 ) {
2020-02-14 23:02:47 +11:00
int16 iniId = _scriptOpcodes - > _scriptTargetINI ;
2019-03-19 20:49:34 +11:00
if ( _cursor - > _sequenceID ! = 5 ) {
2020-02-15 22:49:14 +11:00
iniId = _cursor - > _performActionTargetINI ;
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
if ( iniId > 0 ) {
2020-02-20 09:57:29 +11:00
flicker - > actor - > _direction = getINI ( iniId - 1 ) - > direction ;
2019-04-29 07:58:15 +10:00
}
2019-03-19 20:49:34 +11:00
}
2019-03-20 00:09:29 +11:00
2019-08-23 20:46:45 +10:00
performAction ( ) ;
2020-02-20 09:57:29 +11:00
if ( ( getCurrentSceneId ( ) = = 0x1d ) & & ( getINI ( 0x178 ) - > objectState ! = 0 ) ) { //cave of dilemma
2019-03-20 00:09:29 +11:00
clearFlags ( ENGINE_FLAG_8 ) ;
} else {
setFlags ( ENGINE_FLAG_8 ) ;
2019-03-19 20:49:34 +11:00
}
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-03-19 20:49:34 +11:00
continue ;
}
2020-02-14 23:02:47 +11:00
if ( _inventory - > getState ( ) ! = InventoryOpen ) {
if ( _inventory - > getState ( ) = = Closed ) {
if ( ( checkForInventoryButtonRelease ( ) & & isInputEnabled ( ) ) & &
( ( _bit_flags_8006fbd8 & 3 ) ! = 1 ) ) {
sequenceId = _dragonVAR - > getVar ( 7 ) ;
InventoryState uVar7 = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( _inventory - > _previousState ) ;
if ( sequenceId = = 1 ) {
_inventory - > _previousState = uVar7 ;
_inventory - > inventoryMissing ( ) ;
} else {
_flickerIdleCounter = 0 ;
_inventory - > setState ( InventoryOpen ) ;
_inventory - > openInventory ( ) ;
if ( _cursor - > _iniItemInHand = = 0 ) {
_cursor - > _sequenceID = 1 ;
2020-02-07 17:26:38 +01:00
} else {
2020-02-14 23:02:47 +11:00
_cursor - > _sequenceID = 5 ;
2019-03-19 20:49:34 +11:00
}
}
2020-02-14 23:02:47 +11:00
continue ;
}
InventoryState uVar6 = _inventory - > getState ( ) ;
if ( checkForActionButtonRelease ( ) & & isFlagSet ( ENGINE_FLAG_8 ) ) {
_flickerIdleCounter = 0 ;
if ( ( _cursor - > _iniUnderCursor & 0x8000 ) ! = 0 ) {
if ( _cursor - > _iniUnderCursor = = 0x8002 ) {
LAB_80027294 :
if ( _cursor - > _iniItemInHand = = 0 ) {
if ( ( _bit_flags_8006fbd8 & 3 ) ! = 1 ) {
sequenceId = _dragonVAR - > getVar ( 7 ) ;
InventoryState uVar7 = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( _inventory - > _previousState ) ;
if ( sequenceId = = 1 ) {
_inventory - > _previousState = uVar7 ;
_inventory - > inventoryMissing ( ) ;
} else {
_flickerIdleCounter = 0 ;
_inventory - > setState ( InventoryOpen ) ;
_inventory - > openInventory ( ) ;
if ( _cursor - > _iniItemInHand = = 0 ) {
_cursor - > _sequenceID = 1 ;
2020-02-13 22:07:01 +11:00
} else {
2020-02-14 23:02:47 +11:00
_cursor - > _sequenceID = 5 ;
2020-02-13 22:07:01 +11:00
}
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
continue ;
2019-03-19 20:49:34 +11:00
}
2020-02-07 17:26:38 +01:00
} else {
2020-02-14 23:02:47 +11:00
if ( _inventory - > addItem ( _cursor - > _iniItemInHand ) ) {
_cursor - > _sequenceID = 1 ;
waitForFrames ( 1 ) ;
_cursor - > _iniItemInHand = 0 ;
_cursor - > _iniUnderCursor = 0 ;
2020-02-13 22:07:01 +11:00
continue ;
}
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
} else {
if ( _cursor - > _iniUnderCursor ! = 0x8001 ) {
_flickerIdleCounter = 0 ;
2020-02-15 22:49:14 +11:00
_cursor - > _performActionTargetINI = _cursor - > _iniUnderCursor ;
2020-02-17 20:10:23 +11:00
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
if ( _cursor - > _sequenceID > = 5 ) {
2020-02-15 22:49:14 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _performActionTargetINI ;
_cursor - > _performActionTargetINI = _cursor - > _iniItemInHand ;
2020-02-14 23:02:47 +11:00
}
runINIScripts ( ) ;
2019-05-13 08:21:48 +10:00
continue ;
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
if ( _inventory - > getSequenceId ( ) = = 0 ) {
goto LAB_80027294 ;
2019-03-19 20:49:34 +11:00
}
}
2020-02-14 23:02:47 +11:00
if ( ( _cursor - > _iniUnderCursor = = 0x8001 ) & & ( _inventory - > getSequenceId ( ) = = 1 ) ) {
_inventory - > setState ( InventionBookOpen ) ;
_inventory - > _previousState = uVar6 ;
_inventory - > openInventionBook ( ) ;
2020-02-13 22:07:01 +11:00
continue ;
}
2020-02-14 23:02:47 +11:00
}
_flickerIdleCounter = 0 ;
2020-02-15 22:49:14 +11:00
_cursor - > _performActionTargetINI = _cursor - > _iniUnderCursor ;
2020-02-17 20:10:23 +11:00
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
if ( _cursor - > _sequenceID > = 5 ) {
2020-02-15 22:49:14 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _performActionTargetINI ;
_cursor - > _performActionTargetINI = _cursor - > _iniItemInHand ;
2020-02-14 23:02:47 +11:00
}
}
}
if ( _inventory - > getState ( ) = = InventionBookOpen ) {
uVar6 = _inventory - > getState ( ) ;
if ( checkForInventoryButtonRelease ( ) & & isInputEnabled ( ) ) {
uVar7 = _inventory - > _previousState ;
if ( _dragonVAR - > getVar ( 7 ) = = 1 ) {
_inventory - > _previousState = uVar7 ;
_inventory - > inventoryMissing ( ) ;
2020-02-13 22:07:01 +11:00
continue ;
}
2020-02-14 23:02:47 +11:00
_flickerIdleCounter = 0 ;
_inventory - > setState ( InventoryOpen ) ;
_inventory - > _previousState = uVar6 ;
_inventory - > openInventory ( ) ;
if ( _cursor - > _iniItemInHand = = 0 ) {
_cursor - > _sequenceID = 1 ;
} else {
_cursor - > _sequenceID = 5 ;
}
continue ;
}
if ( checkForActionButtonRelease ( ) & & isFlagSet ( ENGINE_FLAG_8 ) ) {
_flickerIdleCounter = 0 ;
2020-02-15 22:49:14 +11:00
_cursor - > _performActionTargetINI = _cursor - > _iniUnderCursor ;
2020-02-17 20:10:23 +11:00
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
if ( _cursor - > _sequenceID > = 5 ) {
2020-02-15 22:49:14 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _performActionTargetINI ;
_cursor - > _performActionTargetINI = _cursor - > _iniItemInHand ;
2019-03-19 20:49:34 +11:00
}
}
}
2019-03-20 00:09:29 +11:00
runINIScripts ( ) ;
2019-05-13 08:21:48 +10:00
continue ;
2019-03-19 20:49:34 +11:00
}
2019-03-20 00:09:29 +11:00
if ( checkForInventoryButtonRelease ( ) ) {
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-05-02 22:12:04 +10:00
_inventory - > closeInventory ( ) ;
2020-02-15 22:49:14 +11:00
_inventory - > setPreviousState ( ) ;
2019-05-13 08:21:48 +10:00
continue ;
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
uVar6 = _inventory - > getState ( ) ;
2019-03-20 00:09:29 +11:00
if ( checkForActionButtonRelease ( ) & & isFlagSet ( ENGINE_FLAG_8 ) ) {
2020-02-11 10:21:09 +11:00
_flickerIdleCounter = 0 ;
2019-03-19 20:49:34 +11:00
if ( ( _cursor - > _iniUnderCursor & 0x8000 ) ! = 0 ) {
if ( _cursor - > _iniUnderCursor = = 0x8001 ) {
2019-05-02 22:12:04 +10:00
_inventory - > closeInventory ( ) ;
2020-02-14 23:02:47 +11:00
_inventory - > setState ( Closed ) ;
if ( _inventory - > _previousState = = InventionBookOpen ) {
2020-02-13 22:07:01 +11:00
_inventory - > closeInventionBook ( ) ;
2019-03-19 20:49:34 +11:00
}
2020-02-07 17:26:38 +01:00
} else {
2020-02-13 22:32:03 +11:00
if ( _cursor - > _iniUnderCursor ! = 0x8002 ) {
if ( ( _cursor - > _iniItemInHand = = 0 ) | |
( ( ( uint16 ) ( _cursor - > _x - 10U ) < 300 & & ( ( uint16 ) ( _cursor - > _y - 10U ) < 0xb4 ) ) ) ) {
runINIScripts ( ) ;
} else {
_cursor - > _sequenceID = 5 ;
waitForFrames ( 2 ) ;
_inventory - > closeInventory ( ) ;
2020-02-15 22:49:14 +11:00
_inventory - > setPreviousState ( ) ;
2020-02-13 22:32:03 +11:00
}
continue ;
}
2019-05-02 22:12:04 +10:00
_inventory - > closeInventory ( ) ;
2020-02-14 23:02:47 +11:00
_inventory - > setState ( InventionBookOpen ) ;
if ( _inventory - > _previousState ! = InventionBookOpen ) {
2020-02-13 22:07:01 +11:00
_inventory - > openInventionBook ( ) ;
2019-03-19 20:49:34 +11:00
}
}
2020-02-14 23:02:47 +11:00
_inventory - > _previousState = uVar6 ;
2019-05-13 08:21:48 +10:00
continue ;
2019-03-19 20:49:34 +11:00
}
if ( _cursor - > _iniUnderCursor ! = 0 ) {
if ( ( _cursor - > _sequenceID ! = 4 ) & & ( _cursor - > _sequenceID ! = 2 ) ) {
2020-02-07 15:25:30 +01:00
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
2020-02-15 22:49:14 +11:00
_cursor - > _performActionTargetINI = _cursor - > _iniUnderCursor ;
2020-02-13 22:07:01 +11:00
if ( _cursor - > _sequenceID > = 4 ) {
2020-02-15 22:49:14 +11:00
_cursor - > _performActionTargetINI = _cursor - > _iniItemInHand ;
2019-11-07 13:25:27 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _iniUnderCursor ;
2019-03-19 20:49:34 +11:00
}
2019-03-20 00:09:29 +11:00
clearFlags ( ENGINE_FLAG_8 ) ;
2019-04-18 09:00:32 +10:00
walkFlickerToObject ( ) ;
2020-02-13 22:32:03 +11:00
if ( ( _cursor - > _iniItemInHand = = 0 ) | |
( ( ( uint16 ) ( _cursor - > _x - 10U ) < 300 & & ( ( uint16 ) ( _cursor - > _y - 10U ) < 0xb4 ) ) ) ) {
runINIScripts ( ) ;
} else {
_cursor - > _sequenceID = 5 ;
waitForFrames ( 2 ) ;
_inventory - > closeInventory ( ) ;
2020-02-15 22:49:14 +11:00
_inventory - > setPreviousState ( ) ;
2020-02-13 22:32:03 +11:00
}
continue ;
2019-03-19 20:49:34 +11:00
}
2019-08-02 23:04:30 +10:00
Actor * actor = _inventory - > getInventoryItemActor ( _cursor - > _iniUnderCursor ) ;
2020-02-07 15:25:30 +01:00
uint16 tmpId = _cursor - > _iniItemInHand ;
_inventory - > replaceItem ( _cursor - > _iniUnderCursor , _cursor - > _iniItemInHand ) ;
2020-02-19 17:47:09 +11:00
_cursor - > _objectInHandSequenceID = actor - > _sequenceID ;
2019-03-20 00:09:29 +11:00
actor - > clearFlag ( ACTOR_FLAG_40 ) ;
2020-02-07 15:25:30 +01:00
_cursor - > _iniItemInHand = _cursor - > _iniUnderCursor ;
2019-03-19 20:49:34 +11:00
_cursor - > _sequenceID = 5 ;
2019-08-02 23:04:30 +10:00
if ( tmpId ! = 0 ) {
2020-02-05 23:16:21 +11:00
actor - > _flags = 0 ;
2020-02-07 14:31:14 +01:00
actor - > _priorityLayer = 0 ;
actor - > _scale = DRAGONS_ENGINE_SPRITE_100_PERCENT_SCALE ;
2020-02-20 09:57:29 +11:00
actor - > updateSequence ( getINI ( tmpId - 1 ) - > inventorySequenceId * 2 + 10 ) ;
2019-03-20 00:09:29 +11:00
actor - > setFlag ( ACTOR_FLAG_40 ) ;
actor - > setFlag ( ACTOR_FLAG_80 ) ;
actor - > setFlag ( ACTOR_FLAG_100 ) ;
actor - > setFlag ( ACTOR_FLAG_200 ) ;
2020-02-07 14:31:14 +01:00
actor - > _priorityLayer = 6 ;
2019-03-19 20:49:34 +11:00
}
2019-05-13 08:21:48 +10:00
continue ;
2019-03-19 20:49:34 +11:00
}
2020-02-11 22:03:06 +11:00
if ( _cursor - > _iniItemInHand = = 0 ) {
runINIScripts ( ) ;
continue ;
}
2019-05-08 07:29:52 +10:00
//drop item back into inventory
2020-02-07 15:25:30 +01:00
if ( _inventory - > addItemIfPositionIsEmpty ( _cursor - > _iniItemInHand , _cursor - > _x , _cursor - > _y ) ) {
Actor * invActor = _inventory - > getInventoryItemActor ( _cursor - > _iniItemInHand ) ;
2020-02-05 23:16:21 +11:00
invActor - > _flags = 0 ;
2020-02-07 14:31:14 +01:00
invActor - > _priorityLayer = 0 ;
invActor - > _scale = DRAGONS_ENGINE_SPRITE_100_PERCENT_SCALE ;
2020-02-20 09:57:29 +11:00
invActor - > updateSequence ( getINI ( _cursor - > _iniItemInHand - 1 ) - > inventorySequenceId * 2 + 10 ) ;
2020-02-07 15:25:30 +01:00
_cursor - > _iniItemInHand = 0 ;
2019-08-02 23:04:30 +10:00
invActor - > setFlag ( ACTOR_FLAG_40 ) ;
invActor - > setFlag ( ACTOR_FLAG_80 ) ;
invActor - > setFlag ( ACTOR_FLAG_100 ) ;
invActor - > setFlag ( ACTOR_FLAG_200 ) ;
2020-02-07 14:31:14 +01:00
invActor - > _priorityLayer = 6 ;
2019-08-02 23:04:30 +10:00
if ( _cursor - > _sequenceID = = 5 ) {
2019-03-19 20:49:34 +11:00
_cursor - > _sequenceID = 4 ;
}
}
}
2020-02-07 15:25:30 +01:00
if ( ( _cursor - > _iniItemInHand = = 0 ) | |
2020-02-11 22:03:06 +11:00
( ( ( uint16 ) ( _cursor - > _x - 10U ) < 300 & & ( ( uint16 ) ( _cursor - > _y - 10U ) < 0xb4 ) ) ) ) {
runINIScripts ( ) ;
2020-02-13 22:32:03 +11:00
} else {
_cursor - > _sequenceID = 5 ;
waitForFrames ( 2 ) ;
_inventory - > closeInventory ( ) ;
2020-02-15 22:49:14 +11:00
_inventory - > setPreviousState ( ) ;
2020-02-11 22:03:06 +11:00
}
2019-03-19 20:49:34 +11:00
}
}
2018-12-13 22:30:30 +11:00
void DragonsEngine : : updateHandler ( ) {
2020-02-07 15:25:30 +01:00
_videoFlags | = 0x40 ;
2019-02-24 23:18:30 +11:00
//TODO logic here
2018-12-18 10:28:15 +11:00
updateActorSequences ( ) ;
2019-01-05 13:26:55 +11:00
2020-02-15 22:49:14 +11:00
updateCamera ( ) ;
2019-03-05 21:39:44 +11:00
_cursor - > updateVisibility ( ) ;
_inventory - > updateVisibility ( ) ;
2019-07-27 21:49:01 +10:00
_actorManager - > updateActorDisplayOrder ( ) ;
2019-06-17 19:41:54 +10:00
// 0x8001b200
if ( isFlagSet ( ENGINE_FLAG_8000 ) & & ! _sound - > isSpeechPlaying ( ) ) {
clearFlags ( ENGINE_FLAG_8000 ) ;
}
2019-01-05 13:26:55 +11:00
//TODO logic here
for ( uint16 i = 0 ; i < 0x17 ; i + + ) {
Actor * actor = _actorManager - > getActor ( i ) ;
2020-02-07 14:39:59 +01:00
if ( actor - > _flags & ACTOR_FLAG_40 ) {
if ( ! ( actor - > _flags & ACTOR_FLAG_100 ) ) {
2020-02-07 14:31:14 +01:00
int16 priority = _scene - > getPriorityAtPosition ( Common : : Point ( actor - > _x_pos , actor - > _y_pos ) ) ;
2019-01-05 13:26:55 +11:00
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
if ( flicker & & _scene - > contains ( flicker ) & & flicker - > actor - > _actorID = = i ) {
if ( priority < 8 | | priority = = 0x10 ) {
2020-02-07 14:31:14 +01:00
actor - > _priorityLayer = priority ;
2019-01-05 13:26:55 +11:00
}
} else {
if ( priority ! = - 1 ) {
2020-02-07 14:31:14 +01:00
actor - > _priorityLayer = priority ;
2019-01-05 13:26:55 +11:00
}
}
2020-02-07 14:31:14 +01:00
if ( actor - > _priorityLayer > = 0x11 ) {
actor - > _priorityLayer = 0 ;
2019-01-05 13:26:55 +11:00
}
2020-02-07 14:31:14 +01:00
if ( actor - > _priorityLayer > = 9 ) {
actor - > _priorityLayer - = 8 ;
2019-01-05 13:26:55 +11:00
}
}
2020-02-07 14:31:14 +01:00
if ( actor - > _sequenceTimer ! = 0 ) {
actor - > _sequenceTimer - - ;
2019-01-05 13:26:55 +11:00
}
}
}
2020-02-07 14:39:59 +01:00
if ( _flags & ENGINE_FLAG_80 ) {
2019-01-05 13:26:55 +11:00
for ( uint16 i = 0x17 ; i < DRAGONS_ENGINE_NUM_ACTORS ; i + + ) {
Actor * actor = _actorManager - > getActor ( i ) ;
2020-02-07 14:31:14 +01:00
if ( actor - > _sequenceTimer ! = 0 ) {
actor - > _sequenceTimer - - ;
2019-01-05 13:26:55 +11:00
}
}
}
2019-02-02 23:42:01 +11:00
2019-02-24 23:18:30 +11:00
if ( isFlagSet ( ENGINE_FLAG_4 ) ) {
updatePathfindingActors ( ) ;
}
// TODO 0x8001bed0
2020-02-04 22:23:55 +11:00
updatePaletteCycling ( ) ;
2019-02-24 23:18:30 +11:00
// 0x8001c294
if ( ! ( _unkFlags1 & ENGINE_UNK1_FLAG_8 ) ) {
//TODO ReadPad();
}
if ( isFlagSet ( ENGINE_FLAG_20 ) ) {
2019-02-02 23:42:01 +11:00
engineFlag0x20UpdateFunction ( ) ;
}
2019-02-23 23:51:03 +11:00
2019-11-29 09:29:02 +11:00
runVsyncUpdaterFunction ( ) ;
2019-02-24 23:18:30 +11:00
// TODO data_8006a3a0 logic. @ 0x8001c2f4
2019-03-03 22:25:00 +11:00
2020-02-07 15:25:30 +01:00
_videoFlags & = ~ 0x40 ;
2018-12-13 22:30:30 +11:00
}
uint32 DragonsEngine : : calulateTimeLeft ( ) {
uint32 now ;
now = _system - > getMillis ( ) ;
2019-02-02 23:42:01 +11:00
if ( _nextUpdatetime < = now ) {
2018-12-13 22:30:30 +11:00
_nextUpdatetime = now + DRAGONS_TICK_INTERVAL ;
2019-02-02 23:42:01 +11:00
return ( 0 ) ;
2018-12-13 22:30:30 +11:00
}
uint32 delay = _nextUpdatetime - now ;
_nextUpdatetime + = DRAGONS_TICK_INTERVAL ;
2019-02-02 23:42:01 +11:00
return ( delay ) ;
2018-12-13 22:30:30 +11:00
}
void DragonsEngine : : wait ( ) {
_system - > delayMillis ( calulateTimeLeft ( ) ) ;
}
2018-12-18 10:28:15 +11:00
void DragonsEngine : : updateActorSequences ( ) {
2020-02-07 14:39:59 +01:00
if ( ! ( _flags & ENGINE_FLAG_4 ) ) {
2019-01-28 21:20:54 +11:00
return ;
2018-12-18 10:28:15 +11:00
}
//TODO ResetRCnt(0xf2000001);
2020-02-07 14:39:59 +01:00
int16 actorId = _flags & ENGINE_FLAG_80 ? ( int16 ) 64 : ( int16 ) 23 ;
2018-12-18 10:28:15 +11:00
2019-01-05 13:26:55 +11:00
while ( actorId > 0 ) {
2018-12-18 10:28:15 +11:00
actorId - - ;
2019-02-02 23:42:01 +11:00
Actor * actor = _actorManager - > getActor ( ( uint16 ) actorId ) ;
2020-02-07 14:39:59 +01:00
if ( actorId < 2 & & _flags & ENGINE_FLAG_40 ) {
2018-12-18 10:28:15 +11:00
continue ;
}
2020-02-07 14:39:59 +01:00
if ( actor - > _flags & ACTOR_FLAG_40 & &
2020-02-07 17:26:38 +01:00
! ( actor - > _flags & ACTOR_FLAG_4 ) & &
! ( actor - > _flags & ACTOR_FLAG_400 ) & &
( actor - > _sequenceTimer = = 0 | | actor - > _flags & ACTOR_FLAG_1 ) ) {
2019-05-28 07:58:50 +10:00
debug ( 5 , " Actor[%d] execute sequenceOp " , actorId ) ;
2018-12-18 22:52:18 +11:00
2020-02-07 14:39:59 +01:00
if ( actor - > _flags & ACTOR_FLAG_1 ) {
2018-12-18 22:52:18 +11:00
actor - > resetSequenceIP ( ) ;
2019-05-08 07:29:52 +10:00
//clear flag mask 0xeff6;
actor - > clearFlag ( ACTOR_FLAG_1 ) ;
actor - > clearFlag ( ACTOR_FLAG_8 ) ;
actor - > clearFlag ( ACTOR_FLAG_1000 ) ;
2020-02-07 14:31:14 +01:00
actor - > _field_7a = 0 ;
2018-12-18 22:52:18 +11:00
}
OpCall opCall ;
2019-01-05 13:26:55 +11:00
opCall . _result = 1 ;
while ( opCall . _result = = 1 ) {
opCall . _op = ( byte ) READ_LE_UINT16 ( actor - > _seqCodeIp ) ;
opCall . _code = actor - > _seqCodeIp + 2 ;
_sequenceOpcodes - > execOpcode ( actor , opCall ) ;
actor - > _seqCodeIp + = opCall . _deltaOfs ;
}
2018-12-18 10:28:15 +11:00
}
}
}
2019-01-05 13:26:55 +11:00
void DragonsEngine : : setFlags ( uint32 flags ) {
_flags | = flags ;
}
void DragonsEngine : : clearFlags ( uint32 flags ) {
_flags & = ~ flags ;
}
2019-08-30 13:21:21 +10:00
uint32 DragonsEngine : : getMultipleFlags ( uint32 flags ) {
return _flags & flags ;
}
2019-09-18 10:54:28 +10:00
uint32 DragonsEngine : : getAllFlags ( ) {
return _flags ;
}
void DragonsEngine : : setAllFlags ( uint32 flags ) {
_flags = flags ;
}
2019-01-05 13:26:55 +11:00
void DragonsEngine : : setUnkFlags ( uint32 flags ) {
_unkFlags1 | = flags ;
}
void DragonsEngine : : clearUnkFlags ( uint32 flags ) {
_unkFlags1 & = ~ flags ;
}
2019-01-15 07:19:54 +11:00
byte * DragonsEngine : : getBackgroundPalette ( ) {
assert ( _scene ) ;
return _scene - > getPalette ( ) ;
}
2019-01-22 22:11:00 +11:00
bool DragonsEngine : : isFlagSet ( uint32 flag ) {
2019-02-02 23:42:01 +11:00
return ( bool ) ( _flags & flag ) ;
2019-01-22 22:11:00 +11:00
}
2019-03-03 22:25:00 +11:00
bool DragonsEngine : : isUnkFlagSet ( uint32 flag ) {
return ( bool ) ( _unkFlags1 & flag ) ;
}
2019-01-26 22:36:45 +11:00
DragonINI * DragonsEngine : : getINI ( uint32 index ) {
return _dragonINIResource - > getRecord ( index ) ;
}
uint16 DragonsEngine : : getVar ( uint16 offset ) {
return _dragonVAR - > getVar ( offset ) ;
}
2019-12-11 20:23:56 +00:00
uint16 DragonsEngine : : getCurrentSceneId ( ) const {
2019-01-26 22:36:45 +11:00
return _scene - > getSceneId ( ) ;
}
void DragonsEngine : : setVar ( uint16 offset , uint16 value ) {
return _dragonVAR - > setVar ( offset , value ) ;
}
2019-01-29 22:44:53 +11:00
uint16 DragonsEngine : : getIniFromImg ( ) {
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
2020-02-07 14:31:14 +01:00
int16 x = flicker - > actor - > _x_pos / 32 ;
int16 y = flicker - > actor - > _y_pos / 8 ;
2019-01-29 22:44:53 +11:00
uint16 currentSceneId = _scene - > getSceneId ( ) ;
2019-02-02 23:42:01 +11:00
for ( uint16 i = 0 ; i < _dragonINIResource - > totalRecords ( ) ; i + + ) {
2019-01-29 22:44:53 +11:00
DragonINI * ini = getINI ( i ) ;
2020-02-20 09:57:29 +11:00
if ( ini - > sceneId = = currentSceneId & & ini - > flags = = 0 ) {
Img * img = _dragonImg - > getImg ( ini - > imgId ) ;
2019-03-03 22:25:00 +11:00
if ( x > = img - > x & &
img - > x + img - > w > = x & &
y > = img - > y & &
img - > h + img - > y > = y ) {
2019-01-29 22:44:53 +11:00
return i + 1 ;
}
}
}
return 0 ;
}
2019-02-02 23:42:01 +11:00
void DragonsEngine : : runINIScripts ( ) {
2019-11-23 08:49:33 +11:00
bool isFlag8Set = isFlagSet ( ENGINE_FLAG_8 ) ;
2019-02-02 23:42:01 +11:00
for ( uint16 i = 0 ; i < _dragonINIResource - > totalRecords ( ) ; i + + ) {
DragonINI * ini = getINI ( i ) ;
2020-02-20 09:57:29 +11:00
if ( ini - > flags & INI_FLAG_10 ) {
ini - > flags & = ~ INI_FLAG_10 ;
2019-02-02 23:42:01 +11:00
byte * data = _dragonOBD - > getFromOpt ( i ) ;
2019-11-18 20:31:17 +11:00
ScriptOpCall scriptOpCall ( data + 8 , READ_LE_UINT32 ( data ) ) ;
2020-02-07 14:39:59 +01:00
clearFlags ( ENGINE_FLAG_8 ) ;
2019-02-02 23:42:01 +11:00
_scriptOpcodes - > runScript3 ( scriptOpCall ) ;
}
}
2019-11-23 08:49:33 +11:00
if ( isFlag8Set ) {
setFlags ( ENGINE_FLAG_8 ) ;
}
2019-02-02 23:42:01 +11:00
}
2020-02-15 22:49:14 +11:00
2019-04-26 22:25:40 +10:00
void DragonsEngine : : engineFlag0x20UpdateFunction ( ) {
2020-02-15 22:49:14 +11:00
if ( ! isFlagSet ( ENGINE_FLAG_20 ) ) {
_run_func_ptr_unk_countdown_timer = 1 ;
return ;
}
2019-04-26 22:25:40 +10:00
2020-02-29 12:35:37 +11:00
if ( isFlagSet ( ENGINE_FLAG_8 ) & & ! isFlagSet ( ENGINE_FLAG_8000000 ) ) {
2020-02-15 22:49:14 +11:00
_cursor - > update ( ) ;
}
2019-04-26 22:25:40 +10:00
2020-02-15 22:49:14 +11:00
uint16 currentSceneId = _scene - > getSceneId ( ) ;
DragonINI * flickerINI = _dragonINIResource - > getFlickerRecord ( ) ;
DragonINI * ini1 = getINI ( 1 ) ;
2019-04-26 22:25:40 +10:00
2020-03-12 10:22:44 +11:00
if ( flickerINI ! = nullptr ) {
2019-04-26 22:25:40 +10:00
if ( flickerINI - > sceneId = = currentSceneId ) {
2020-03-12 10:22:44 +11:00
if ( flickerINI - > actor = = nullptr | | flickerINI - > actor - > isFlagSet ( ACTOR_FLAG_10 ) ) {
if ( ini1 - > actor ! = nullptr ) {
2020-02-15 22:49:14 +11:00
ini1 - > actor - > updateSequence ( 8 ) ;
ini1 - > actor - > _priorityLayer = 0 ;
2019-04-26 22:25:40 +10:00
}
} else {
2020-02-15 22:49:14 +11:00
if ( ( _bit_flags_8006fbd8 & 2u ) = = 0 ) {
_bit_flags_8006fbd8 | = 2u ;
2019-04-26 22:25:40 +10:00
}
2020-02-15 22:49:14 +11:00
if ( flickerINI - > actor - > isFlagClear ( ACTOR_FLAG_2000 )
& & flickerINI - > actor - > isFlagSet ( ACTOR_FLAG_4 )
& & flickerINI - > actor - > _direction ! = - 1
& & flickerINI - > actor - > _direction ! = flickerINI - > actor - > _sequenceID ) {
flickerINI - > actor - > updateSequence ( flickerINI - > actor - > _direction ) ;
}
2020-03-12 10:22:44 +11:00
if ( ini1 - > actor ! = nullptr ) {
2020-02-15 22:49:14 +11:00
ini1 - > actor - > _priorityLayer = 0 ;
2019-04-26 22:25:40 +10:00
}
}
}
2020-02-15 22:49:14 +11:00
}
2019-04-26 22:25:40 +10:00
2020-02-15 22:49:14 +11:00
// 0x80027db8
if ( ! _inventory - > isOpen ( ) ) {
for ( uint16 i = 0 ; i < _dragonINIResource - > totalRecords ( ) ; i + + ) {
DragonINI * ini = getINI ( i ) ;
2020-02-20 09:57:29 +11:00
if ( ini - > counter > = 0 & & ini - > sceneId = = currentSceneId ) {
ini - > counter - - ;
if ( ini - > counter < 0 ) {
ini - > flags | = INI_FLAG_10 ;
2019-02-02 23:42:01 +11:00
}
}
}
2020-02-15 22:49:14 +11:00
}
2019-03-07 21:24:10 +11:00
2020-02-15 22:49:14 +11:00
if ( _run_func_ptr_unk_countdown_timer ! = 0 ) {
_run_func_ptr_unk_countdown_timer - - ;
2019-02-02 23:42:01 +11:00
}
}
void DragonsEngine : : waitForFrames ( uint16 numFrames ) {
for ( uint16 i = 0 ; i < numFrames ; i + + ) {
wait ( ) ;
updateHandler ( ) ;
_scene - > draw ( ) ;
_screen - > updateScreen ( ) ;
2019-07-19 07:44:41 +10:00
runSceneUpdaterFunction ( ) ;
2019-02-23 23:51:03 +11:00
updateEvents ( ) ;
2019-02-02 23:42:01 +11:00
}
}
2019-07-24 22:08:44 +10:00
void DragonsEngine : : waitForFramesAllowSkip ( uint16 numFrames ) {
for ( int i = 0 ; i < numFrames ; i + + ) {
waitForFrames ( 1 ) ;
if ( checkForActionButtonRelease ( ) ) { // TODO should this be any input?
return ;
}
}
}
2019-12-11 20:23:56 +00:00
void DragonsEngine : : playOrStopSound ( uint16 soundId ) {
debug ( " play sound 0x%x " , soundId ) ;
2019-12-16 10:21:02 +11:00
this - > _sound - > playOrStopSound ( soundId ) ;
2019-02-03 15:23:41 +11:00
}
2019-02-23 23:51:03 +11:00
void DragonsEngine : : updatePathfindingActors ( ) {
for ( uint16 i = 0 ; i < 0x17 ; i + + ) {
Actor * actor = _actorManager - > getActor ( i ) ;
actor - > walkPath ( ) ;
}
}
2020-03-23 22:56:09 +11:00
void DragonsEngine : : fadeFromBlack ( uint32 flags ) {
2019-03-05 23:17:40 +11:00
if ( ! isFlagSet ( ENGINE_FLAG_40 ) ) {
return ;
}
2020-03-23 22:56:09 +11:00
bool isUnkFlag2Set = isUnkFlagSet ( ENGINE_UNK1_FLAG_2 ) ;
2019-03-05 23:17:40 +11:00
setUnkFlags ( ENGINE_UNK1_FLAG_2 ) ;
clearFlags ( ENGINE_FLAG_40 ) ;
2020-03-23 22:56:09 +11:00
//TODO 0x80015a1c implement fading logic here.
if ( ! isUnkFlag2Set ) {
clearUnkFlags ( ENGINE_UNK1_FLAG_2 ) ;
}
}
void DragonsEngine : : fadeFromBlack ( ) {
fadeFromBlack ( 0x1f ) ;
}
void DragonsEngine : : fadeFromBlackExcludingFont ( ) {
fadeFromBlack ( 0x1e ) ;
}
void DragonsEngine : : fadeToBlack ( ) {
fadeToBlack ( 0x1f ) ;
}
void DragonsEngine : : fadeToBlackExcludingFont ( ) {
fadeToBlack ( 0x1e ) ;
2019-03-05 23:17:40 +11:00
}
2020-03-23 22:56:09 +11:00
void DragonsEngine : : fadeToBlack ( uint32 flags ) {
bool isFlag2Set = isUnkFlagSet ( ENGINE_UNK1_FLAG_2 ) ;
//TODO
// do {
// SetShadeTex(poly_ft4_tbl + uVar2,0);
// uVar5 = uVar5 + 1;
// uVar2 = (uint)uVar5;
// } while (uVar5 < 0x40);
// uVar5 = 0;
// uVar2 = 0;
// do {
// SetShadeTex(poly_f4_tbl + uVar2,0);
// uVar1 = unkFlags1;
// uVar5 = uVar5 + 1;
// uVar2 = (uint)uVar5;
// } while (uVar5 < 0xf);
if ( ! isFlagSet ( ENGINE_FLAG_40 ) ) {
setUnkFlags ( ENGINE_UNK1_FLAG_2 ) ;
//TODO fade out here.
setFlags ( ENGINE_FLAG_40 ) ;
if ( ! isFlag2Set ) {
clearUnkFlags ( ENGINE_UNK1_FLAG_2 ) ;
}
}
2019-03-05 23:17:40 +11:00
}
2019-08-23 20:46:45 +10:00
void DragonsEngine : : performAction ( ) {
2019-03-25 07:31:56 +11:00
uint uVar1 ;
2020-02-06 21:51:42 +11:00
uint16 uVar2 ;
2019-03-25 07:31:56 +11:00
uint uVar4 ;
uint uVar5 ;
uint uVar6 ;
byte * pvVar7 ;
byte * pvVar8 ;
2019-11-18 20:31:17 +11:00
byte * local_58_code ;
byte * local_58_codeEnd ;
bool load_58_result = false ;
2019-03-25 07:31:56 +11:00
2019-11-07 13:25:27 +11:00
uVar2 = _scriptOpcodes - > _scriptTargetINI ;
2019-03-25 07:31:56 +11:00
uVar1 = _flags ;
2020-03-12 10:22:44 +11:00
local_58_code = nullptr ;
local_58_codeEnd = nullptr ;
2019-03-25 07:31:56 +11:00
uVar6 = 0 ;
2020-02-19 17:47:09 +11:00
_scriptOpcodes - > _numDialogStackFramesToPop = 0 ;
2019-03-25 07:31:56 +11:00
2020-02-15 22:49:14 +11:00
assert ( _cursor - > _performActionTargetINI > 0 ) ;
byte * obd = _dragonOBD - > getFromOpt ( _cursor - > _performActionTargetINI - 1 ) ;
2019-03-25 07:31:56 +11:00
2019-11-18 20:31:17 +11:00
ScriptOpCall local_48 ( obd + 8 , READ_LE_UINT32 ( obd ) ) ;
pvVar7 = local_48 . _code ;
pvVar8 = local_48 . _codeEnd ;
2019-03-25 07:31:56 +11:00
uVar4 = _cursor - > executeScript ( local_48 , 1 ) ;
2020-02-07 15:25:30 +01:00
if ( _cursor - > _data_800728b0_cursor_seqID > 4 ) {
2020-02-19 17:47:09 +11:00
_scriptOpcodes - > _numDialogStackFramesToPop = 0 ;
2019-03-25 07:31:56 +11:00
2019-11-07 13:25:27 +11:00
obd = _dragonOBD - > getFromOpt ( _scriptOpcodes - > _scriptTargetINI - 1 ) ;
2020-02-15 22:49:14 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _performActionTargetINI ;
2019-03-25 07:31:56 +11:00
2019-11-18 20:31:17 +11:00
ScriptOpCall local_38 ( obd + 8 , READ_LE_UINT32 ( obd ) ) ;
2019-03-25 07:31:56 +11:00
uVar6 = _cursor - > executeScript ( local_38 , 1 ) ;
2019-11-07 13:25:27 +11:00
_scriptOpcodes - > _scriptTargetINI = uVar2 ;
2019-11-18 20:31:17 +11:00
if ( ( uVar6 & 0xffff ) ! = 0 ) {
local_58_code = local_38 . _code + 8 ;
local_58_codeEnd = local_58_code + READ_LE_UINT16 ( local_38 . _code + 6 ) ;
}
2019-03-25 07:31:56 +11:00
}
if ( ( ( uVar4 & 0xffff ) ! = 0 ) & & ( ( ( ( uVar4 & 2 ) = = 0 | | ( ( uVar6 & 2 ) ! = 0 ) ) | | ( ( uVar6 & 0xffff ) = = 0 ) ) ) ) {
2019-11-18 20:31:17 +11:00
local_58_code = local_48 . _code + 8 ;
local_58_codeEnd = local_58_code + READ_LE_UINT16 ( local_48 . _code + 6 ) ;
2019-03-25 07:31:56 +11:00
}
uVar4 = uVar4 & 0xfffd ;
2020-03-12 10:22:44 +11:00
if ( local_58_code ! = nullptr & & local_58_codeEnd ! = nullptr ) {
2019-03-25 07:31:56 +11:00
clearFlags ( ENGINE_FLAG_8 ) ;
2019-11-18 20:31:17 +11:00
ScriptOpCall local_58 ( local_58_code , local_58_codeEnd - local_58_code ) ;
2019-03-25 07:31:56 +11:00
_scriptOpcodes - > runScript ( local_58 ) ;
2019-11-18 20:31:17 +11:00
load_58_result = local_58 . _result ;
2019-03-25 07:31:56 +11:00
}
2019-11-18 20:31:17 +11:00
if ( ! load_58_result ) {
2020-02-07 15:25:30 +01:00
if ( _cursor - > _data_800728b0_cursor_seqID = = 3 ) {
2019-11-18 20:31:17 +11:00
ScriptOpCall local_58 ( pvVar7 , pvVar8 - pvVar7 ) ;
2019-07-14 11:55:46 +10:00
uVar5 = _talk - > talkToActor ( local_58 ) ;
2019-03-25 07:31:56 +11:00
uVar4 = uVar4 | uVar5 ;
}
if ( ( ( uVar4 & 0xffff ) = = 0 ) & & ( ( uVar6 & 0xfffd ) = = 0 ) ) {
2019-08-01 09:39:19 +10:00
_talk - > flickerRandomDefaultResponse ( ) ;
2019-03-25 07:31:56 +11:00
}
2020-02-07 17:26:38 +01:00
} else {
2020-02-19 17:47:09 +11:00
_scriptOpcodes - > _numDialogStackFramesToPop - - ;
2019-03-25 07:31:56 +11:00
}
_flags | = uVar1 & ENGINE_FLAG_8 ;
return ;
2019-03-20 00:09:29 +11:00
}
bool DragonsEngine : : checkForInventoryButtonRelease ( ) {
return _iKeyUp ;
}
bool DragonsEngine : : isInputEnabled ( ) {
return ! isFlagSet ( ENGINE_FLAG_20000000 ) & & ! isFlagSet ( ENGINE_FLAG_400 ) ;
}
2019-08-30 13:21:21 +10:00
bool DragonsEngine : : isActionButtonPressed ( ) {
2019-09-05 22:40:07 +10:00
return _leftMouseButtonDown ;
2019-08-30 13:21:21 +10:00
}
bool DragonsEngine : : isLeftKeyPressed ( ) {
2019-09-05 22:40:07 +10:00
return _leftKeyDown ;
2019-08-30 13:21:21 +10:00
}
bool DragonsEngine : : isRightKeyPressed ( ) {
2019-09-05 22:40:07 +10:00
return _rightKeyDown ;
2019-08-30 13:21:21 +10:00
}
2019-10-04 08:41:09 +10:00
bool DragonsEngine : : isUpKeyPressed ( ) {
return false ; // TODO
}
bool DragonsEngine : : isDownKeyPressed ( ) {
return false ; // TODO
}
2019-03-20 00:09:29 +11:00
bool DragonsEngine : : checkForActionButtonRelease ( ) {
2019-08-17 10:38:43 +10:00
return _leftMouseButtonUp | | _enterKeyUp ;
2019-03-20 00:09:29 +11:00
}
2020-02-07 17:26:38 +01:00
void DragonsEngine : : walkFlickerToObject ( ) {
2020-02-06 21:51:42 +11:00
uint16 targetX ;
uint16 targetY ;
2019-03-21 23:15:52 +11:00
uint uVar7 ;
uint uVar8 ;
DragonINI * targetINI ;
DragonINI * flickerINI ;
flickerINI = _dragonINIResource - > getFlickerRecord ( ) ;
if ( flickerINI - > sceneId = = getCurrentSceneId ( ) ) {
2020-02-15 22:49:14 +11:00
if ( _cursor - > _performActionTargetINI ! = 0 ) {
2019-03-21 23:15:52 +11:00
2020-02-15 22:49:14 +11:00
if ( ! ( READ_LE_UINT16 ( _dragonOBD - > getFromOpt ( _cursor - > _performActionTargetINI - 1 ) + 4 ) & 8 )
2020-02-14 23:02:47 +11:00
& & ( _inventory - > getState ( ) = = Closed ) & & ! isFlagSet ( ENGINE_FLAG_200000 ) ) {
2020-02-15 22:49:14 +11:00
targetINI = getINI ( _cursor - > _performActionTargetINI - 1 ) ;
2020-02-20 09:57:29 +11:00
if ( ( targetINI - > flags & 1 ) = = 0 ) {
2019-03-21 23:15:52 +11:00
if ( targetINI - > actorResourceId = = - 1 ) {
return ;
}
2020-02-20 09:57:29 +11:00
Img * img = _dragonImg - > getImg ( targetINI - > imgId ) ;
2019-03-21 23:15:52 +11:00
targetX = img - > field_a ;
targetY = img - > field_c ;
2020-02-07 17:26:38 +01:00
} else {
2020-02-07 14:31:14 +01:00
targetX = targetINI - > actor - > _x_pos ;
targetY = targetINI - > actor - > _y_pos ;
2019-03-21 23:15:52 +11:00
}
2020-01-21 23:02:22 +11:00
flickerINI - > actor - > _walkSpeed = 0x10000 ;
2020-02-20 09:57:29 +11:00
if ( flickerINI - > direction2 = = - 1 ) {
2019-03-21 23:15:52 +11:00
flickerINI - > actor - > setFlag ( ACTOR_FLAG_800 ) ;
}
2020-02-20 09:57:29 +11:00
flickerINI - > actor - > startWalk ( ( int ) ( ( ( uint ) targetX + ( uint ) targetINI - > baseXOffset ) * 0x10000 ) > > 0x10 ,
( int ) ( ( ( uint ) targetY + ( uint ) targetINI - > baseYOffset ) * 0x10000 ) > > 0x10 , 0 ) ;
2020-02-15 22:49:14 +11:00
_bit_flags_8006fbd8 = 1 ; //walk to perform an action.
2019-03-21 23:15:52 +11:00
return ;
}
if ( isFlagSet ( ENGINE_FLAG_200000 ) ) {
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 3 ;
2019-03-21 23:15:52 +11:00
return ;
}
flickerINI = _dragonINIResource - > getFlickerRecord ( ) ;
2020-03-12 10:22:44 +11:00
if ( flickerINI ! = nullptr & & flickerINI - > actor ! = nullptr ) {
2019-03-21 23:15:52 +11:00
flickerINI - > actor - > clearFlag ( ACTOR_FLAG_10 ) ;
flickerINI - > actor - > setFlag ( ACTOR_FLAG_4 ) ;
2020-02-15 22:49:14 +11:00
targetINI = getINI ( _cursor - > _performActionTargetINI - 1 ) ;
2020-02-20 09:57:29 +11:00
flickerINI - > direction2 = targetINI - > direction ;
flickerINI - > actor - > _direction = targetINI - > direction ;
2019-03-21 23:15:52 +11:00
}
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 3 ;
2019-03-21 23:15:52 +11:00
return ;
}
2020-02-14 23:02:47 +11:00
if ( _inventory - > getState ( ) = = Closed & & ! isFlagSet ( ENGINE_FLAG_200000 ) ) {
2020-02-06 21:51:42 +11:00
uVar7 = ( uint ) ( uint16 ) _cursor - > _x ;
uVar8 = ( uint ) ( uint16 ) _cursor - > _y ;
2020-01-21 23:02:22 +11:00
flickerINI - > actor - > _walkSpeed = 0x10000 ;
flickerINI - > actor - > startWalk (
2019-03-21 23:15:52 +11:00
( int ) ( ( uVar7 + ( uint ) _scene - > _camera . x ) * 0x10000 ) > > 0x10 ,
2020-02-07 18:06:57 +01:00
( int ) ( ( uVar8 + ( uint ) _scene - > _camera . y ) * 0x10000 ) > > 0x10 , 0 ) ;
2019-03-21 23:15:52 +11:00
}
2020-02-07 17:26:38 +01:00
} else {
2020-02-15 22:49:14 +11:00
if ( _cursor - > _performActionTargetINI ! = 0 ) {
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 3 ;
2019-03-21 23:15:52 +11:00
return ;
}
}
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 0 ;
2019-03-21 23:15:52 +11:00
return ;
2019-03-20 00:09:29 +11:00
}
2019-03-28 21:54:17 +11:00
void DragonsEngine : : reset_screen_maybe ( ) {
2020-02-07 15:25:30 +01:00
_videoFlags & = ~ 0x10 ;
2019-03-28 21:54:17 +11:00
//TODO
}
2019-05-13 08:21:48 +10:00
bool DragonsEngine : : canLoadGameStateCurrently ( ) {
return isInputEnabled ( ) ;
}
bool DragonsEngine : : canSaveGameStateCurrently ( ) {
2020-02-14 23:02:47 +11:00
return isInputEnabled ( ) & & ! _inventory - > isOpen ( ) ;
2019-05-13 08:21:48 +10:00
}
bool DragonsEngine : : hasFeature ( Engine : : EngineFeature f ) const {
return
// TODO (f == kSupportsRTL) ||
( f = = kSupportsLoadingDuringRuntime ) | |
( f = = kSupportsSavingDuringRuntime ) ;
}
2020-03-07 23:05:11 +11:00
void DragonsEngine : : init ( ) {
2019-05-19 20:30:58 +10:00
_flags = 0x1046 ;
_flags & = 0x1c07040 ;
_flags | = 0x26 ;
_unkFlags1 = 0 ;
2020-02-29 15:23:56 +11:00
initSubtitleFlag ( ) ;
2019-08-17 10:38:43 +10:00
2019-11-07 13:25:27 +11:00
_scriptOpcodes - > _scriptTargetINI = 0 ; //TODO this should be reset in scriptopcode.
2019-05-19 20:30:58 +10:00
_cursor - > init ( _actorManager , _dragonINIResource ) ;
_inventory - > init ( _actorManager , _backgroundResourceLoader , new Bag ( _bigfileArchive , _screen ) , _dragonINIResource ) ;
2019-05-28 07:58:50 +10:00
_talk - > init ( ) ;
2019-05-19 20:30:58 +10:00
2019-10-25 18:42:16 +11:00
_screen - > loadPalette ( 1 , _cursor - > getPalette ( ) ) ;
setupPalette1 ( ) ;
_screen - > loadPalette ( 2 , _cursor - > getPalette ( ) ) ;
2020-02-23 21:41:09 +11:00
_screen - > updatePaletteTransparency ( 2 , 1 , 5 , true ) ;
_screen - > updatePaletteTransparency ( 2 , 0xc1 , 0xc3 , true ) ;
2019-10-25 18:42:16 +11:00
_screen - > loadPalette ( 4 , _cursor - > getPalette ( ) ) ;
_screen - > updatePaletteTransparency ( 4 , 1 , 0xff , true ) ;
2020-03-07 23:05:11 +11:00
}
2019-10-25 18:42:16 +11:00
2020-03-07 23:05:11 +11:00
void DragonsEngine : : loadScene ( uint16 sceneId ) {
2020-02-07 17:26:38 +01:00
// TODO fun_80017010_update_actor_texture_maybe();
2019-05-19 20:30:58 +10:00
if ( sceneId > 2 ) {
_dragonVAR - > setVar ( 1 , 1 ) ;
}
2019-07-22 07:49:13 +10:00
//if (sceneId > 2) { //TODO remove this restriction to enable intro sequence.
2019-05-19 20:30:58 +10:00
_scene - > setSceneId ( 2 ) ;
byte * obd = _dragonOBD - > getFromSpt ( 3 ) ;
2019-11-18 20:31:17 +11:00
ScriptOpCall scriptOpCall ( obd + 4 , READ_LE_UINT32 ( obd ) ) ;
2019-05-19 20:30:58 +10:00
_scriptOpcodes - > runScript ( scriptOpCall ) ;
2019-07-22 07:49:13 +10:00
//} else {
// sceneId = 0x12; // HACK the first scene. TODO remove this
// }
2019-05-19 20:30:58 +10:00
2019-05-28 07:58:50 +10:00
_inventory - > loadInventoryItemsFromSave ( ) ;
2020-02-07 08:34:58 +11:00
if ( getINI ( 0 ) - > sceneId = = 0 ) {
2019-05-19 20:30:58 +10:00
getINI ( 0 ) - > sceneId = sceneId ; //TODO
} else {
_scene - > setSceneId ( getINI ( 0 ) - > sceneId ) ;
}
_sceneId1 = sceneId ;
2019-07-22 07:49:13 +10:00
_scene - > loadScene ( sceneId ? sceneId : 0x12 , 0x1e ) ;
2019-05-19 20:30:58 +10:00
}
void DragonsEngine : : reset ( ) {
2019-08-01 09:39:19 +10:00
seedRandom ( 0x1dd ) ; //TODO should we randomise this better? I got this value from a couple of runs in the emulator
2019-05-19 20:30:58 +10:00
_nextUpdatetime = 0 ;
_flags = 0 ;
_unkFlags1 = 0 ;
2020-02-07 15:25:30 +01:00
_run_func_ptr_unk_countdown_timer = 0 ;
_videoFlags = 0 ;
2020-02-19 17:47:09 +11:00
_flickerInitialSceneDirection = 0 ;
2019-05-19 20:30:58 +10:00
2020-02-07 08:34:58 +11:00
for ( int i = 0 ; i < 8 ; i + + ) {
2020-02-04 22:23:55 +11:00
_paletteCyclingTbl [ i ] . paletteType = 0 ;
_paletteCyclingTbl [ i ] . startOffset = 0 ;
_paletteCyclingTbl [ i ] . endOffset = 0 ;
_paletteCyclingTbl [ i ] . updateInterval = 0 ;
_paletteCyclingTbl [ i ] . updateCounter = 0 ;
2019-05-19 20:30:58 +10:00
}
2020-03-12 10:22:44 +11:00
clearSceneUpdateFunction ( ) ;
2019-05-19 20:30:58 +10:00
}
2019-07-19 07:44:41 +10:00
void DragonsEngine : : runSceneUpdaterFunction ( ) {
2020-02-07 15:25:30 +01:00
if ( ( isFlagSet ( ENGINE_FLAG_20 ) & & ( _run_func_ptr_unk_countdown_timer = = 0 ) ) & &
2020-03-12 10:22:44 +11:00
( _run_func_ptr_unk_countdown_timer = 1 , _sceneUpdateFunction ! = nullptr ) ) {
2019-07-19 07:44:41 +10:00
_sceneUpdateFunction ( ) ;
}
}
void DragonsEngine : : setSceneUpdateFunction ( void ( * newUpdateFunction ) ( ) ) {
_sceneUpdateFunction = newUpdateFunction ;
}
2020-03-12 10:22:44 +11:00
void DragonsEngine : : clearSceneUpdateFunction ( ) {
setSceneUpdateFunction ( nullptr ) ;
}
2019-11-29 09:29:02 +11:00
void DragonsEngine : : setVsyncUpdateFunction ( void ( * newUpdateFunction ) ( ) ) {
_vsyncUpdateFunction = newUpdateFunction ;
}
2019-08-01 09:39:19 +10:00
void DragonsEngine : : seedRandom ( int32 seed ) {
2020-02-07 17:26:38 +01:00
_randomState = seed * - 0x2b0e2b0f ;
2019-08-01 09:39:19 +10:00
}
2020-02-07 17:26:38 +01:00
uint32 DragonsEngine : : shuffleRandState ( ) {
2019-08-01 09:39:19 +10:00
uint32 returnBit ;
returnBit = _randomState & 1 ;
_randomState = _randomState > > 1 |
2019-10-25 18:42:16 +11:00
( ( _randomState < < 0x1e ^ _randomState ^ _randomState < < 0x1d ^ _randomState < < 0x1b ^
_randomState < < 0x19 ) & 0x80000000 ) ;
2019-08-01 09:39:19 +10:00
return returnBit ;
}
uint16 DragonsEngine : : getRand ( uint16 max ) {
uint16 rand = 0 ;
for ( int i = 0 ; i < 0x10 ; i + + ) {
2019-11-29 21:52:02 +11:00
rand | = shuffleRandState ( ) < < i ;
2019-08-01 09:39:19 +10:00
}
return rand % max ;
}
2019-08-17 10:38:43 +10:00
bool DragonsEngine : : checkForDownKeyRelease ( ) {
return _downKeyUp ;
}
bool DragonsEngine : : checkForUpKeyRelease ( ) {
return _upKeyUp ;
}
2019-09-19 07:28:17 +10:00
bool DragonsEngine : : isSquareButtonPressed ( ) {
return _aKeyDown ;
}
bool DragonsEngine : : isTriangleButtonPressed ( ) {
return _wKeyDown ;
}
bool DragonsEngine : : isCircleButtonPressed ( ) {
return _dKeyDown ;
}
bool DragonsEngine : : isCrossButtonPressed ( ) {
return _sKeyDown ;
}
bool DragonsEngine : : isL1ButtonPressed ( ) {
return _oKeyDown ;
}
bool DragonsEngine : : isR1ButtonPressed ( ) {
return _pKeyDown ;
}
2019-10-25 18:42:16 +11:00
void DragonsEngine : : setupPalette1 ( ) {
byte palette [ 512 ] ;
memcpy ( palette , _cursor - > getPalette ( ) , 0x100 ) ;
memcpy ( palette + 0x100 , _cursor - > getPalette ( ) , 0x100 ) ;
_screen - > loadPalette ( 1 , palette ) ;
2020-02-07 18:06:57 +01:00
_screen - > updatePaletteTransparency ( 1 , 0x40 , 0x7f , true ) ;
2019-10-25 18:42:16 +11:00
}
bool DragonsEngine : : isDebugMode ( ) {
return _debugMode ;
}
2019-11-29 09:29:02 +11:00
bool DragonsEngine : : isVsyncUpdaterFunctionRunning ( ) {
2020-03-12 10:22:44 +11:00
return _vsyncUpdateFunction ! = nullptr ;
2019-11-29 09:29:02 +11:00
}
void DragonsEngine : : runVsyncUpdaterFunction ( ) {
if ( isVsyncUpdaterFunctionRunning ( ) ) {
_vsyncUpdateFunction ( ) ;
}
}
2019-12-11 20:23:56 +00:00
void DragonsEngine : : loadCurrentSceneMsf ( ) {
2019-12-16 10:21:02 +11:00
_sound - > loadMsf ( getCurrentSceneId ( ) ) ;
2019-12-11 20:23:56 +00:00
}
2020-02-04 22:23:55 +11:00
void DragonsEngine : : updatePaletteCycling ( ) {
if ( ! _isGamePaused ) {
for ( int loopIndex = 0 ; loopIndex < 8 ; loopIndex + + ) {
if ( _paletteCyclingTbl [ loopIndex ] . updateInterval ! = 0 ) {
if ( _paletteCyclingTbl [ loopIndex ] . updateCounter = = 0 ) {
uint16 * palette = ( uint16 * ) _screen - > getPalette ( _paletteCyclingTbl [ loopIndex ] . paletteType ) ;
2020-02-06 21:51:42 +11:00
int16 uVar14 = ( uint ) ( uint16 ) _paletteCyclingTbl [ loopIndex ] . startOffset ;
int16 uVar8 = ( uint ) ( uint16 ) _paletteCyclingTbl [ loopIndex ] . endOffset ;
2020-02-04 22:23:55 +11:00
if ( uVar14 < uVar8 ) {
uint16 uVar11 = palette [ uVar8 ] ;
int uVar15 = uVar8 ;
if ( uVar14 < uVar8 ) {
do {
uVar8 - - ;
palette [ uVar15 ] = palette [ uVar15 - 1 ] ;
uVar15 = uVar8 & 0xffff ;
2020-02-06 21:51:42 +11:00
} while ( ( uint ) ( uint16 ) _paletteCyclingTbl [ loopIndex ] . startOffset < ( uVar8 & 0xffff ) ) ;
2020-02-04 22:23:55 +11:00
}
2020-02-06 21:51:42 +11:00
palette [ ( uint16 ) _paletteCyclingTbl [ loopIndex ] . startOffset ] = uVar11 ;
2020-02-04 22:23:55 +11:00
_paletteCyclingTbl [ loopIndex ] . updateCounter = _paletteCyclingTbl [ loopIndex ] . updateInterval ;
2020-02-07 17:26:38 +01:00
} else {
2020-02-04 22:23:55 +11:00
if ( uVar8 < uVar14 ) {
uint16 uVar11 = palette [ uVar14 ] ;
uint16 uVar15 = uVar8 ;
if ( uVar8 < uVar14 ) {
do {
uVar8 - - ;
palette [ uVar15 ] = palette [ uVar15 + 1 ] ;
uVar15 = uVar8 & 0xffff ;
2020-02-06 21:51:42 +11:00
} while ( ( uVar8 & 0xffff ) < ( uint ) ( uint16 ) _paletteCyclingTbl [ loopIndex ] . startOffset ) ;
2020-02-04 22:23:55 +11:00
}
2020-02-06 21:51:42 +11:00
palette [ ( uint16 ) _paletteCyclingTbl [ loopIndex ] . endOffset ] = uVar11 ;
2020-02-04 22:23:55 +11:00
_paletteCyclingTbl [ loopIndex ] . updateCounter =
_paletteCyclingTbl [ loopIndex ] . updateInterval ;
}
}
2020-02-07 17:26:38 +01:00
} else {
2020-02-04 22:23:55 +11:00
_paletteCyclingTbl [ loopIndex ] . updateCounter = _paletteCyclingTbl [ loopIndex ] . updateCounter + - 1 ;
}
}
}
}
}
2020-02-08 23:43:58 +11:00
uint32 DragonsEngine : : getFontOffsetFromDragonEXE ( ) {
switch ( _language ) {
case Common : : EN_USA : return 0x4a144 ;
2020-02-09 10:47:32 +11:00
case Common : : EN_GRB : return 0x4b4fc ;
2020-02-08 23:43:58 +11:00
case Common : : DE_DEU : return 0x4af5c ;
2020-02-09 10:47:32 +11:00
case Common : : FR_FRA : return 0x4b158 ;
2020-02-08 23:43:58 +11:00
default : error ( " Unable to get font offset from dragon.exe for %s " , getLanguageCode ( _language ) ) ;
}
}
uint32 DragonsEngine : : getSpeechTblOffsetFromDragonEXE ( ) {
switch ( _language ) {
case Common : : EN_USA : return 0x4e138 ;
2020-02-09 10:47:32 +11:00
case Common : : EN_GRB : return 0x4f4f4 ;
2020-02-08 23:43:58 +11:00
case Common : : DE_DEU : return 0x4f0a4 ;
2020-02-09 10:47:32 +11:00
case Common : : FR_FRA : return 0x4f2a0 ;
2020-02-08 23:43:58 +11:00
default : error ( " Unable to get speech table offset from dragon.exe for %s " , getLanguageCode ( _language ) ) ;
}
}
uint32 DragonsEngine : : getBigFileInfoTblFromDragonEXE ( ) {
switch ( _language ) {
case Common : : EN_USA : return 0x4a238 ;
case Common : : EN_GRB : return 0x4b5f4 ;
case Common : : DE_DEU : return 0x4b054 ;
2020-02-09 10:47:32 +11:00
case Common : : FR_FRA : return 0x4b250 ;
default :
error ( " Unable to get speech table offset from dragon.exe for %s " , getLanguageCode ( _language ) ) ;
}
}
uint32 DragonsEngine : : getCutscenePaletteOffsetFromDragonEXE ( ) {
switch ( _language ) {
case Common : : EN_USA : return 0x5336c ;
case Common : : EN_GRB : return 0x54628 ;
case Common : : DE_DEU : return 0x541d8 ;
case Common : : FR_FRA : return 0x543d4 ;
2020-02-08 23:43:58 +11:00
default :
error ( " Unable to get speech table offset from dragon.exe for %s " , getLanguageCode ( _language ) ) ;
}
}
2020-02-09 23:04:26 +11:00
uint32 DragonsEngine : : defaultResponseOffsetFromDragonEXE ( ) {
switch ( _language ) {
case Common : : EN_USA : return 0x541b0 ;
case Common : : EN_GRB : return 0x55470 ;
case Common : : DE_DEU : return 0x55020 ;
case Common : : FR_FRA : return 0x5521c ;
default :
error ( " Unable to get speech table offset from dragon.exe for %s " , getLanguageCode ( _language ) ) ;
}
}
2020-02-11 22:03:06 +11:00
void DragonsEngine : : updateFlickerIdleAnimation ( ) {
_flickerIdleCounter + + ;
if ( _flickerIdleCounter > = 0x4af ) {
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
if ( flicker - > actor - > _resourceID = = 0xe ) {
flicker - > actor - > _direction = 2 ;
2020-02-20 09:57:29 +11:00
flicker - > direction2 = 2 ;
2020-02-11 22:03:06 +11:00
if ( getINI ( 0xc2 ) - > sceneId = = 1 ) {
flicker - > actor - > updateSequence ( 0x30 ) ;
} else {
flicker - > actor - > updateSequence ( 2 ) ;
}
_flickerIdleCounter = 0 ;
setFlags ( ENGINE_FLAG_80000000 ) ;
}
}
if ( isFlagSet ( ENGINE_FLAG_80000000 )
& & _dragonINIResource - > getFlickerRecord ( ) - > actor - > isFlagSet ( ACTOR_FLAG_4 ) ) {
_flickerIdleCounter = 0 ;
clearFlags ( ENGINE_FLAG_80000000 ) ;
}
}
2020-02-15 22:49:14 +11:00
void DragonsEngine : : updateCamera ( ) {
if ( isFlagSet ( ENGINE_FLAG_40 ) & & ! isUnkFlagSet ( ENGINE_UNK1_FLAG_1 ) ) {
return ;
}
if ( isFlagSet ( ENGINE_FLAG_1 ) & & ! isUnkFlagSet ( ENGINE_UNK1_FLAG_2 ) ) { //TODO original doesn't seem to check for flag 2 here. adding to get cutscenes to work.
DragonINI * flicker = _dragonINIResource - > getFlickerRecord ( ) ;
if ( flicker & & flicker - > sceneId ! = 0 ) {
if ( ( flicker - > actor - > _x_pos - _scene - > _camera . x > = 0x4f ) ) {
if ( flicker - > actor - > _x_pos - _scene - > _camera . x > = 0xf0 ) {
_scene - > _camera . x = flicker - > actor - > _x_pos - 0xf0 ;
}
} else {
_scene - > _camera . x = flicker - > actor - > _x_pos - 0x50 ;
}
int16 sVar4 = flicker - > actor - > _y_pos + - 0x1e ;
if ( ( ( int ) flicker - > actor - > _y_pos - ( int ) _scene - > _camera . y < 0x1e ) | |
( sVar4 = flicker - > actor - > _y_pos + - 0xaa , 0xaa < ( int ) flicker - > actor - > _y_pos - ( int ) _scene - > _camera . y ) ) {
_scene - > _camera . y = sVar4 ;
}
}
if ( _scene - > _camera . x < 0 ) {
_scene - > _camera . x = 0 ;
}
if ( _scene - > getStageWidth ( ) < _scene - > _camera . x + 0x140 ) {
_scene - > _camera . x = _scene - > getStageWidth ( ) - 0x140 ;
}
if ( _scene - > _camera . y < 0 ) {
_scene - > _camera . y = 0 ;
}
if ( _scene - > getStageHeight ( ) < _scene - > _camera . y + 200 ) {
_scene - > _camera . y = _scene - > getStageHeight ( ) + - 200 ;
}
}
}
2020-02-29 15:23:56 +11:00
void DragonsEngine : : initSubtitleFlag ( ) {
bool showSubtitles = ConfMan . getBool ( " subtitles " ) ;
if ( showSubtitles ) {
clearFlags ( ENGINE_FLAG_1000_SUBTITLES_DISABLED ) ;
} else {
setFlags ( ENGINE_FLAG_1000_SUBTITLES_DISABLED ) ;
}
}
2020-03-07 23:05:11 +11:00
int centerText ( const char * text ) {
return 0x14 - ( strlen ( text ) / 2 + 1 ) ;
}
void DragonsEngine : : mainMenu ( ) {
_inMenu = true ;
//TODO need to support other languages.
const char copyright [ 6 ] [ 40 ] = {
" Crystal Dynamics is a trademark " ,
" of Crystal Dynamics. " ,
" Blazing Dragons is a trademark and " ,
" copyright of Terry Jones and is " ,
" used with permission. " ,
" Licensed by Nelvana Marketing Inc. "
} ;
const char menuItems [ 3 ] [ 40 ] = {
" Start " ,
" Options " ,
" Previews "
} ;
_screen - > clearScreen ( ) ;
Actor * actor = _actorManager - > loadActor ( 0xd9 , 0 , 0 , 0 , 3 ) ;
actor - > setFlag ( ACTOR_FLAG_8000 ) ;
actor - > setFlag ( ACTOR_FLAG_100 ) ;
actor - > setFlag ( ACTOR_FLAG_80 ) ;
//TODO fix palette for copyright image.
_screen - > loadPalette ( 0 , _cursor - > getPalette ( ) ) ; //actor->_actorResource->getPalette());
for ( int i = 0 ; i < 6 ; i + + ) {
_fontManager - > addAsciiText ( centerText ( & copyright [ i ] [ 0 ] ) * 8 , ( 0x12 + i ) * 8 , & copyright [ i ] [ 0 ] , strlen ( copyright [ i ] ) , 1 ) ;
}
waitForFramesAllowSkip ( 400 ) ;
_fontManager - > clearText ( ) ;
actor - > updateSequence ( 1 ) ;
2020-03-13 22:10:54 +11:00
bool startGame = false ;
2020-03-07 23:05:11 +11:00
do {
2020-03-13 22:10:54 +11:00
uint16 curMenuItem = 0 ;
do {
for ( int i = 0 ; i < 3 ; i + + ) {
_fontManager - > addAsciiText ( ( i = = 0 ? 17 : 16 ) * 8 , ( 0x12 + i ) * 8 , & menuItems [ i ] [ 0 ] ,
strlen ( menuItems [ i ] ) , i = = curMenuItem ? 0 : 1 ) ;
}
2020-03-15 14:01:54 +11:00
if ( checkForDownKeyRelease ( ) ) {
if ( curMenuItem < 2 ) {
curMenuItem + + ;
} else {
curMenuItem = 0 ;
}
2020-03-13 22:10:54 +11:00
playOrStopSound ( 0x8009 ) ;
}
2020-03-15 14:01:54 +11:00
if ( checkForUpKeyRelease ( ) ) {
if ( curMenuItem > 0 ) {
curMenuItem - - ;
} else {
curMenuItem = 2 ;
}
2020-03-13 22:10:54 +11:00
playOrStopSound ( 0x8009 ) ;
}
waitForFrames ( 1 ) ;
} while ( ! checkForActionButtonRelease ( ) & & ! shouldQuit ( ) ) ;
if ( curMenuItem = = 0 ) {
2020-03-15 14:01:54 +11:00
_screen - > clearScreen ( ) ;
loadingScreen ( ) ;
2020-03-13 22:10:54 +11:00
startGame = true ;
} else if ( curMenuItem = = 1 ) {
//TODO options menu
} else if ( curMenuItem = = 2 ) {
_strPlayer - > playVideo ( " previews.str " ) ;
}
} while ( ! shouldQuit ( ) & & ! startGame ) ;
2020-03-07 23:05:11 +11:00
_inMenu = false ;
}
bool DragonsEngine : : isInMenu ( ) {
return _inMenu ;
}
2020-03-15 14:01:54 +11:00
void loadingScreenUpdateFunction ( ) {
getEngine ( ) - > loadingScreenUpdate ( ) ;
}
void DragonsEngine : : loadingScreen ( ) {
const int flamesActorOffset [ 4 ] = { 2 , 0 , 3 , 1 } ;
_loadingScreenState = new LoadingScreenState ;
_fontManager - > clearText ( ) ;
_actorManager - > clearActorFlags ( 2 ) ;
_screen - > addFlatQuad ( 0 , 0 , 0x13f , 0 , 0x13f , 199 , 0 , 199 , 0x34a2 , 6 , 0 ) ;
Actor * actor = _actorManager - > loadActor ( 0 , 0x82 , 0 , 0 , 6 ) ;
actor - > setFlag ( ACTOR_FLAG_100 ) ;
actor - > setFlag ( ACTOR_FLAG_200 ) ;
actor - > setFlag ( ACTOR_FLAG_80 ) ;
actor = _actorManager - > loadActor ( 0 , 0x83 , 0 , 0 , 6 ) ;
actor - > setFlag ( ACTOR_FLAG_100 ) ;
actor - > setFlag ( ACTOR_FLAG_200 ) ;
actor - > setFlag ( ACTOR_FLAG_80 ) ;
for ( int i = 0 ; i < 10 ; i + + ) {
actor = _actorManager - > loadActor ( 0 , flamesActorOffset [ ( i % 4 ) ] + 0x7e , i * 0x20 + 0x10 , 0xbe , 6 ) ;
actor - > setFlag ( ACTOR_FLAG_100 ) ;
actor - > setFlag ( ACTOR_FLAG_200 ) ;
actor - > setFlag ( ACTOR_FLAG_80 ) ;
_loadingScreenState - > flames [ i ] = actor ;
_loadingScreenState - > baseYOffset = 0xbe ;
int x0 = i * 0x20 ;
_loadingScreenState - > quads [ i ] = _screen - > addFlatQuad ( x0 , 0 , x0 + 0x20 , 0 , x0 + 0x20 , 199 , x0 , 199 , 0 , 7 , 0 ) ;
}
setVsyncUpdateFunction ( loadingScreenUpdateFunction ) ;
waitForFramesAllowSkip ( 400 ) ;
_actorManager - > clearActorFlags ( 2 ) ;
_screen - > clearAllFlatQuads ( ) ;
setVsyncUpdateFunction ( nullptr ) ;
delete _loadingScreenState ;
_loadingScreenState = nullptr ;
}
void DragonsEngine : : loadingScreenUpdate ( ) {
const int16 flameOffsetTbl [ 26 ] = {
3 , 4 , 5 , 6 ,
7 , 5 , 4 , 3 ,
3 , 4 , 6 , 7 ,
6 , 5 , 5 , 6 ,
7 , 6 , 4 , 3 ,
2 , 3 , 4 , 5 ,
6 , 5
} ;
FlatQuad * quad ;
int16 flameYOffset ;
if ( _loadingScreenState - > loadingFlamesUpdateCounter = = 0 ) {
_loadingScreenState - > loadingFlamesUpdateCounter = 4 ;
for ( int i = 0 ; i < 10 ; i + + ) {
2020-03-19 23:29:07 +11:00
flameYOffset = _loadingScreenState - > baseYOffset - flameOffsetTbl [ ( i + _loadingScreenState - > flameOffsetIdx ) % 26 ] ;
2020-03-15 14:01:54 +11:00
if ( _loadingScreenState - > flames [ i ] - > _y_pos > = - 0xb ) {
_loadingScreenState - > flames [ i ] - > _y_pos = flameYOffset ;
}
quad = _screen - > getFlatQuad ( _loadingScreenState - > quads [ i ] ) ;
if ( quad - > points [ 0 ] . y > = - 1 ) {
quad - > points [ 0 ] . y = flameYOffset + 2 ;
quad - > points [ 1 ] . y = flameYOffset + 2 ;
}
}
2020-03-19 23:29:07 +11:00
_loadingScreenState - > flameOffsetIdx = ( _loadingScreenState - > flameOffsetIdx + 1 ) % 26 ;
2020-03-15 14:01:54 +11:00
} else {
_loadingScreenState - > loadingFlamesUpdateCounter - - ;
}
if ( _loadingScreenState - > loadingFlamesRiseCounter = = 0 ) {
_loadingScreenState - > loadingFlamesRiseCounter = 1 ;
_loadingScreenState - > baseYOffset - - ;
} else {
_loadingScreenState - > loadingFlamesRiseCounter - - ;
}
}
2019-07-22 07:49:13 +10:00
void ( * DragonsEngine : : getSceneUpdateFunction ( ) ) ( ) {
return _sceneUpdateFunction ;
}
2019-07-19 07:44:41 +10:00
2018-10-19 23:22:30 +11:00
} // End of namespace Dragons