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"
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 ;
2018-11-07 22:27:05 +11:00
_bigfileArchive = NULL ;
_dragonRMS = NULL ;
_backgroundResourceLoader = NULL ;
_screen = NULL ;
2018-12-18 22:52:18 +11:00
_sequenceOpcodes = new SequenceOpcodes ( this ) ;
2019-01-26 22:36:45 +11:00
_scriptOpcodes = NULL ;
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 ) ;
2019-12-10 22:38:53 +11:00
_credits = NULL ;
2019-05-28 07:58:50 +10:00
_talk = NULL ;
2019-07-05 20:31:52 +10:00
_fontManager = NULL ;
2019-07-19 07:44:41 +10:00
_sceneUpdateFunction = NULL ;
2019-11-29 09:29:02 +11:00
_vsyncUpdateFunction = NULL ;
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 ;
2019-10-25 18:42:16 +11:00
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 ) ;
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 {
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 ;
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 ) ;
2019-03-20 00:09:29 +11:00
if ( ( ini - > sceneId = = getCurrentSceneId ( ) ) & & ( ini - > field_1a_flags_maybe = = 0 ) ) {
2020-02-07 15:25:30 +01:00
Img * img = _dragonImg - > getImg ( ini - > field_2 ) ;
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 | |
2019-03-21 23:15:52 +11:00
( ! ( _cursor - > _iniUnderCursor & 0x8000 ) & & ( getINI ( _cursor - > _iniUnderCursor - 1 ) - > field_1a_flags_maybe & 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-14 23:02:47 +11:00
iniId = _cursor - > _data_80072890 ;
2019-03-19 20:49:34 +11:00
}
2020-02-14 23:02:47 +11:00
if ( iniId > 0 ) {
flicker - > actor - > _direction = getINI ( iniId - 1 ) - > field_e ;
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-07 17:26:38 +01:00
if ( ( getCurrentSceneId ( ) = = 0x1d ) & & ( getINI ( 0x178 ) - > field_12 ! = 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 ;
_cursor - > _data_80072890 = _cursor - > _iniUnderCursor ;
if ( _cursor - > _sequenceID < 5 ) {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
} else {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
_scriptOpcodes - > _scriptTargetINI = _cursor - > _data_80072890 ;
_cursor - > _data_80072890 = _cursor - > _iniItemInHand ;
}
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 ;
_cursor - > _data_80072890 = _cursor - > _iniUnderCursor ;
if ( _cursor - > _sequenceID < 5 ) {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
} else {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
2020-02-13 22:07:01 +11:00
}
2020-02-14 23:02:47 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _data_80072890 ;
_cursor - > _data_80072890 = _cursor - > _iniItemInHand ;
}
}
}
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 ;
_cursor - > _data_80072890 = _cursor - > _iniUnderCursor ;
if ( _cursor - > _sequenceID < 5 ) {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
}
} else {
_cursor - > _data_800728b0_cursor_seqID = _cursor - > _sequenceID ;
walkFlickerToObject ( ) ;
if ( _bit_flags_8006fbd8 ! = 0 ) {
clearFlags ( ENGINE_FLAG_8 ) ;
2020-02-13 22:07:01 +11:00
}
2020-02-14 23:02:47 +11:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _data_80072890 ;
_cursor - > _data_80072890 = _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-14 23:02:47 +11:00
InventoryState prevInventoryMode = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( prevInventoryMode ) ;
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-14 23:02:47 +11:00
InventoryState prevInventoryMode = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( prevInventoryMode ) ;
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 ;
_cursor - > _data_80072890 = _cursor - > _iniUnderCursor ;
2020-02-13 22:07:01 +11:00
if ( _cursor - > _sequenceID > = 4 ) {
2020-02-07 15:25:30 +01:00
_cursor - > _data_80072890 = _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-14 23:02:47 +11:00
uVar6 = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( uVar6 ) ;
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 ) ;
2019-03-20 00:09:29 +11:00
_cursor - > data_8007283c = actor - > _sequenceID ;
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 ;
2019-08-02 23:04:30 +10:00
actor - > updateSequence ( getINI ( tmpId - 1 ) - > field_8 * 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-07 17:26:38 +01:00
invActor - > updateSequence ( getINI ( _cursor - > _iniItemInHand - 1 ) - > field_8 * 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-14 23:02:47 +11:00
InventoryState prevInventoryMode = _inventory - > _previousState ;
_inventory - > _previousState = _inventory - > getState ( ) ;
_inventory - > setState ( prevInventoryMode ) ;
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
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 ) ;
if ( ini - > sceneId = = currentSceneId & & ini - > field_1a_flags_maybe = = 0 ) {
2020-02-07 15:25:30 +01:00
Img * img = _dragonImg - > getImg ( ini - > field_2 ) ;
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-07 14:39:59 +01:00
if ( ini - > field_1a_flags_maybe & INI_FLAG_10 ) {
ini - > field_1a_flags_maybe & = ~ 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
}
2019-04-26 22:25:40 +10:00
/*
void DragonsEngine : : engineFlag0x20UpdateFunction ( ) {
{
2020-02-06 21:51:42 +11:00
uint16 uVar1 ;
2020-02-06 22:35:51 +11:00
uint16 uVar2 ;
2019-04-26 22:25:40 +10:00
DragonINI * pDVar3 ;
DragonINI * pDVar4 ;
2020-02-06 21:51:42 +11:00
uint16 uVar5 ;
2019-04-26 22:25:40 +10:00
uint actorId ;
DragonINI * flickerINI = _dragonINIResource - > getFlickerRecord ( ) ;
uint16 currentSceneId = _scene - > getSceneId ( ) ;
// uVar1 = flickerINI->actorId;
// actorId = (uint)uVar1;
// uVar5 = dragon_ini_pointer[dragon_ini_const__2 + -1].field_0x1c;
if ( flickerINI = = NULL ) {
//LAB_80027d40:
// if ((flickerINI->sceneId == currentSceneId)
// && (uVar5 != 0xffff)) {
2020-02-07 16:48:53 +01:00
// actors[(uint)uVar5]._sequenceID = 8;
// actors[(uint)uVar5]._priorityLayer_maybe = 0;
2019-04-26 22:25:40 +10:00
// }
2020-02-07 17:26:38 +01:00
} else {
2019-04-26 22:25:40 +10:00
if ( flickerINI - > sceneId = = currentSceneId ) {
if ( ( flickerINI = = NULL ) | | flickerINI - > actor - > isFlagSet ( ACTOR_FLAG_10 ) ) {
if ( ( flickerINI - > sceneId = = currentSceneId )
& & ( uVar5 ! = 0xffff ) ) {
2020-02-07 16:48:53 +01:00
// actors[(uint)uVar5]._sequenceID = 8;
// actors[(uint)uVar5]._priorityLayer_maybe = 0;
2019-04-26 22:25:40 +10:00
}
} else {
2020-02-07 16:48:53 +01:00
if ( ( _bit_flags_8006fbd8 & 2 ) = = 0 ) {
_bit_flags_8006fbd8 = _bit_flags_8006fbd8 | 2 ;
2019-04-26 22:25:40 +10:00
}
2020-02-05 23:16:21 +11:00
// if (((((actors[actorId]._flags & 0x2000) == 0) && ((actors[actorId]._flags & 4) != 0)) &&
2020-02-08 14:25:17 +11:00
// (actors[actorId]._direction != actors[actorId]._sequenceID)) &&
// (actors[actorId]._direction != -1)) {
// actor_update_sequenceID(actorId, actors[actorId]._direction);
2019-04-26 22:25:40 +10:00
// }
}
} else {
2020-02-07 16:48:53 +01:00
//actors[(uint)uVar5]._priorityLayer_maybe = 0;
2019-04-26 22:25:40 +10:00
}
}
LAB_80027db4 :
uVar1 = num_ini_records_maybe ;
pDVar3 = dragon_ini_pointer ;
uVar2 = currentSceneId ;
if ( ( inventoryType = = 0 ) & & ( uVar5 = 0 , num_ini_records_maybe ! = 0 ) ) {
actorId = 0 ;
do {
pDVar4 = pDVar3 + actorId ;
if ( ( ( - 1 < ( int ) ( ( uint ) pDVar4 - > field_0x10 < < 0x10 ) ) & & ( pDVar4 - > sceneId_maybe = = uVar2 ) ) & &
( pDVar4 - > field_0x10 = pDVar4 - > field_0x10 - 1 , ( int ) ( ( uint ) pDVar4 - > field_0x10 < < 0x10 ) < 0 ) )
{
pDVar4 - > field_1a_flags_maybe = pDVar4 - > field_1a_flags_maybe | 0x10 ;
}
uVar5 = uVar5 + 1 ;
actorId = ( uint ) uVar5 ;
} while ( uVar5 < uVar1 ) ;
}
2020-02-07 15:25:30 +01:00
if ( _run_func_ptr_unk_countdown_timer ! = 0 ) {
_run_func_ptr_unk_countdown_timer = _run_func_ptr_unk_countdown_timer - 1 ;
2019-04-26 22:25:40 +10:00
}
2020-02-07 15:25:30 +01:00
return ( uint ) _run_func_ptr_unk_countdown_timer ;
2019-04-26 22:25:40 +10:00
} */
2019-02-02 23:42:01 +11:00
2019-11-23 08:49:33 +11:00
//TODO the logic in this function doesn't match the original. It should be redone.
2019-02-02 23:42:01 +11:00
void DragonsEngine : : engineFlag0x20UpdateFunction ( ) {
2020-02-11 22:03:06 +11:00
if ( isFlagSet ( ENGINE_FLAG_20 ) ) {
if ( isFlagSet ( ENGINE_FLAG_8 ) & & ! isFlagSet ( ENGINE_FLAG_80000000 ) ) {
2019-03-05 21:39:44 +11:00
_cursor - > update ( ) ;
2019-02-02 23:42:01 +11:00
}
2019-03-07 21:24:10 +11:00
//TODO 0x80027be4
2019-02-02 23:42:01 +11:00
uint16 currentSceneId = _scene - > getSceneId ( ) ;
2019-04-26 22:25:40 +10:00
DragonINI * flickerINI = _dragonINIResource - > getFlickerRecord ( ) ;
// uVar1 = flickerINI->actorId;
// actorId = (uint)uVar1;
// uVar5 = dragon_ini_pointer[dragon_ini_const__2 + -1].field_0x1c;
if ( flickerINI = = NULL ) {
//LAB_80027d40:
2019-05-01 13:25:51 +10:00
//error("LAB_80027d40"); //TODO is this logic required?
2019-04-26 22:25:40 +10:00
// if ((flickerINI->sceneId == currentSceneId)
// && (uVar5 != 0xffff)) {
2020-02-07 16:48:53 +01:00
// actors[(uint)uVar5]._sequenceID = 8;
// actors[(uint)uVar5]._priorityLayer_maybe = 0;
2019-04-26 22:25:40 +10:00
// }
2020-02-07 17:26:38 +01:00
} else {
2019-04-26 22:25:40 +10:00
if ( flickerINI - > sceneId = = currentSceneId ) {
2019-05-01 13:25:51 +10:00
if ( flickerINI - > actor - > isFlagSet ( ACTOR_FLAG_10 ) ) {
if ( _inventory - > isActorSet ( ) ) {
_inventory - > setActorSequenceId ( 8 ) ;
_inventory - > setPriority ( 0 ) ;
2019-04-26 22:25:40 +10:00
}
} else {
2020-02-11 22:03:06 +11:00
if ( ( _bit_flags_8006fbd8 & 2u ) = = 0 ) {
_bit_flags_8006fbd8 | = 2u ;
2019-04-26 22:25:40 +10:00
}
2019-04-29 07:58:15 +10:00
if ( flickerINI - > actor - > isFlagClear ( ACTOR_FLAG_2000 )
2020-02-07 17:26:38 +01:00
& & flickerINI - > actor - > isFlagSet ( ACTOR_FLAG_4 )
2020-02-08 14:25:17 +11:00
& & flickerINI - > actor - > _direction ! = - 1
& & flickerINI - > actor - > _direction ! = flickerINI - > actor - > _sequenceID ) {
flickerINI - > actor - > updateSequence ( flickerINI - > actor - > _direction ) ;
2019-04-29 07:58:15 +10:00
}
2019-04-26 22:25:40 +10:00
}
} else {
2019-05-01 13:25:51 +10:00
_inventory - > setPriority ( 0 ) ; //TODO I don't think this is quite right.
2019-04-26 22:25:40 +10:00
}
}
2019-03-07 21:24:10 +11:00
// 0x80027db8
2020-02-14 23:02:47 +11:00
if ( ! _inventory - > isOpen ( ) ) {
2019-02-02 23:42:01 +11:00
for ( uint16 i = 0 ; i < _dragonINIResource - > totalRecords ( ) ; i + + ) {
DragonINI * ini = getINI ( i ) ;
if ( ini - > field_10 > = 0 & & ini - > sceneId = = currentSceneId ) {
ini - > field_10 - - ;
if ( ini - > field_10 < 0 ) {
2020-02-07 14:39:59 +01:00
ini - > field_1a_flags_maybe | = INI_FLAG_10 ;
2019-02-02 23:42:01 +11:00
}
}
}
}
2019-03-07 21:24:10 +11:00
2020-02-07 15:25:30 +01:00
if ( _run_func_ptr_unk_countdown_timer ! = 0 ) {
_run_func_ptr_unk_countdown_timer - - ;
2019-03-07 21:24:10 +11:00
}
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 ( ) ;
}
}
2019-03-05 23:17:40 +11:00
void DragonsEngine : : fade_related ( uint32 flags ) {
if ( ! isFlagSet ( ENGINE_FLAG_40 ) ) {
return ;
}
setUnkFlags ( ENGINE_UNK1_FLAG_2 ) ;
clearFlags ( ENGINE_FLAG_40 ) ;
//TODO 0x80015a1c
}
void DragonsEngine : : call_fade_related_1f ( ) {
fade_related ( 0x1f ) ;
}
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 ;
2019-11-18 20:31:17 +11:00
local_58_code = NULL ;
local_58_codeEnd = NULL ;
2019-03-25 07:31:56 +11:00
uVar6 = 0 ;
_scriptOpcodes - > _data_80071f5c = 0 ;
2020-02-07 15:25:30 +01:00
assert ( _cursor - > _data_80072890 > 0 ) ;
byte * obd = _dragonOBD - > getFromOpt ( _cursor - > _data_80072890 - 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 ) {
2019-03-25 07:31:56 +11:00
_scriptOpcodes - > _data_80071f5c = 0 ;
2019-11-07 13:25:27 +11:00
obd = _dragonOBD - > getFromOpt ( _scriptOpcodes - > _scriptTargetINI - 1 ) ;
2020-02-07 15:25:30 +01:00
_scriptOpcodes - > _scriptTargetINI = _cursor - > _data_80072890 ;
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 ;
2019-11-18 20:31:17 +11:00
if ( local_58_code ! = NULL & & local_58_codeEnd ! = NULL ) {
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 {
2019-03-25 07:31:56 +11:00
_scriptOpcodes - > _data_80071f5c - - ;
}
_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-07 15:25:30 +01:00
if ( _cursor - > _data_80072890 ! = 0 ) {
2019-03-21 23:15:52 +11:00
2020-02-07 15:25:30 +01:00
if ( ! ( READ_LE_UINT16 ( _dragonOBD - > getFromOpt ( _cursor - > _data_80072890 - 1 ) + 4 ) & 8 )
2020-02-14 23:02:47 +11:00
& & ( _inventory - > getState ( ) = = Closed ) & & ! isFlagSet ( ENGINE_FLAG_200000 ) ) {
2020-02-07 15:25:30 +01:00
targetINI = getINI ( _cursor - > _data_80072890 - 1 ) ;
2019-03-21 23:15:52 +11:00
if ( ( targetINI - > field_1a_flags_maybe & 1 ) = = 0 ) {
if ( targetINI - > actorResourceId = = - 1 ) {
return ;
}
2020-02-07 15:25:30 +01:00
Img * img = _dragonImg - > getImg ( targetINI - > field_2 ) ;
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 ;
2019-03-21 23:15:52 +11:00
if ( flickerINI - > field_20_actor_field_14 = = - 1 ) {
flickerINI - > actor - > setFlag ( ACTOR_FLAG_800 ) ;
}
2020-01-21 23:02:22 +11:00
flickerINI - > actor - > startWalk ( ( int ) ( ( ( uint ) targetX + ( uint ) targetINI - > field_1c ) * 0x10000 ) > > 0x10 ,
2020-02-07 18:06:57 +01:00
( int ) ( ( ( uint ) targetY + ( uint ) targetINI - > field_1e ) * 0x10000 ) > > 0x10 , 0 ) ;
2020-02-07 16:48:53 +01:00
_bit_flags_8006fbd8 = 1 ;
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 ( ) ;
if ( flickerINI ! = NULL & & flickerINI - > actor ! = NULL ) {
flickerINI - > actor - > clearFlag ( ACTOR_FLAG_10 ) ;
flickerINI - > actor - > setFlag ( ACTOR_FLAG_4 ) ;
2020-02-07 15:25:30 +01:00
targetINI = getINI ( _cursor - > _data_80072890 - 1 ) ;
2019-03-21 23:15:52 +11:00
flickerINI - > field_20_actor_field_14 = targetINI - > field_e ;
2020-02-08 14:25:17 +11:00
flickerINI - > actor - > _direction = targetINI - > field_e ;
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-07 15:25:30 +01:00
if ( _cursor - > _data_80072890 ! = 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 ) ;
}
2019-05-19 20:30:58 +10:00
void DragonsEngine : : loadScene ( uint16 sceneId ) {
_flags = 0x1046 ;
_flags & = 0x1c07040 ;
_flags | = 0x26 ;
_unkFlags1 = 0 ;
2019-08-17 10:38:43 +10:00
clearFlags ( ENGINE_FLAG_1000_TEXT_ENABLED ) ; //TODO wire this up to subtitle config.
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 ( ) ) ;
_screen - > loadPalette ( 4 , _cursor - > getPalette ( ) ) ;
_screen - > updatePaletteTransparency ( 4 , 1 , 0xff , true ) ;
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 ;
_data_800633fa = 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
}
2019-08-01 09:39:19 +10:00
setSceneUpdateFunction ( NULL ) ;
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-02-07 17:26:38 +01:00
( _run_func_ptr_unk_countdown_timer = 1 , _sceneUpdateFunction ! = NULL ) ) {
2019-07-19 07:44:41 +10:00
_sceneUpdateFunction ( ) ;
}
}
void DragonsEngine : : setSceneUpdateFunction ( void ( * newUpdateFunction ) ( ) ) {
_sceneUpdateFunction = newUpdateFunction ;
}
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 ( ) {
return _vsyncUpdateFunction ! = NULL ;
}
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 ;
flicker - > field_20_actor_field_14 = 2 ;
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 ) ;
}
}
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