mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-25 19:25:20 +00:00
1716 lines
48 KiB
C++
1716 lines
48 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
#include "common/config-manager.h"
|
|
#include "common/keyboard.h"
|
|
#include "common/language.h"
|
|
#include "engines/util.h"
|
|
#include "graphics/thumbnail.h"
|
|
#include "common/error.h"
|
|
#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"
|
|
#include "dragons/strplayer.h"
|
|
|
|
namespace Dragons {
|
|
|
|
#define DRAGONS_TICK_INTERVAL 17
|
|
|
|
static DragonsEngine *_engine = nullptr;
|
|
|
|
DragonsEngine *getEngine() {
|
|
return _engine;
|
|
}
|
|
|
|
DragonsEngine::DragonsEngine(OSystem *syst, const ADGameDescription *desc) : Engine(syst) {
|
|
_language = desc->language;
|
|
_bigfileArchive = nullptr;
|
|
_dragonRMS = nullptr;
|
|
_backgroundResourceLoader = nullptr;
|
|
_screen = nullptr;
|
|
_sequenceOpcodes = new SequenceOpcodes(this);
|
|
_scriptOpcodes = nullptr;
|
|
_engine = this;
|
|
_inventory = new Inventory(this);
|
|
_cursor = new Cursor(this);
|
|
_credits = nullptr;
|
|
_talk = nullptr;
|
|
_fontManager = nullptr;
|
|
_strPlayer = nullptr;
|
|
_sceneUpdateFunction = nullptr;
|
|
_vsyncUpdateFunction = nullptr;
|
|
|
|
_leftMouseButtonUp = false;
|
|
_leftMouseButtonDown = false;
|
|
_rightMouseButtonUp = false;
|
|
_iKeyUp = false;
|
|
_downKeyUp = false;
|
|
_upKeyUp = false;
|
|
_enterKeyUp = false;
|
|
_leftKeyDown = false;
|
|
_leftKeyUp = false;
|
|
_rightKeyDown = false;
|
|
_rightKeyUp = false;
|
|
_wKeyDown = false;
|
|
_aKeyDown = false;
|
|
_sKeyDown = false;
|
|
_dKeyDown = false;
|
|
_oKeyDown = false;
|
|
_pKeyDown = false;
|
|
|
|
_debugMode = false;
|
|
_isGamePaused = false;
|
|
_inMenu = false;
|
|
|
|
_bit_flags_8006fbd8 = 0;
|
|
|
|
reset();
|
|
}
|
|
|
|
DragonsEngine::~DragonsEngine() {
|
|
delete _sequenceOpcodes;
|
|
delete _scriptOpcodes;
|
|
}
|
|
|
|
void DragonsEngine::updateEvents() {
|
|
Common::Event event;
|
|
_leftMouseButtonUp = false;
|
|
_rightMouseButtonUp = false;
|
|
_iKeyUp = false;
|
|
_downKeyUp = false;
|
|
_upKeyUp = false;
|
|
_enterKeyUp = false;
|
|
_leftKeyUp = false;
|
|
_rightKeyUp = false;
|
|
while (_eventMan->pollEvent(event)) {
|
|
// _input->processEvent(event);
|
|
switch (event.type) {
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
Common::Error DragonsEngine::run() {
|
|
_screen = new Screen();
|
|
_bigfileArchive = new BigfileArchive(this, "bigfile.dat");
|
|
_talk = new Talk(this, _bigfileArchive);
|
|
_dragonFLG = new DragonFLG(_bigfileArchive);
|
|
_dragonImg = new DragonImg(_bigfileArchive);
|
|
_dragonOBD = new DragonOBD(_bigfileArchive);
|
|
_dragonRMS = new DragonRMS(_bigfileArchive, _dragonOBD);
|
|
_dragonVAR = new DragonVAR(_bigfileArchive);
|
|
_dragonINIResource = new DragonINIResource(_bigfileArchive);
|
|
_fontManager = new FontManager(this, _screen, _bigfileArchive);
|
|
_credits = new Credits(this, _fontManager, _bigfileArchive);
|
|
ActorResourceLoader *actorResourceLoader = new ActorResourceLoader(_bigfileArchive);
|
|
_actorManager = new ActorManager(actorResourceLoader);
|
|
_scriptOpcodes = new ScriptOpcodes(this, _dragonFLG);
|
|
_backgroundResourceLoader = new BackgroundResourceLoader(_bigfileArchive, _dragonRMS);
|
|
_scene = new Scene(this, _screen, _scriptOpcodes, _actorManager, _dragonRMS, _dragonINIResource, _backgroundResourceLoader);
|
|
|
|
_sound = new SoundManager(this, _bigfileArchive, _dragonRMS);
|
|
_strPlayer = new StrPlayer(this, _screen);
|
|
|
|
if (ConfMan.hasKey("save_slot")) {
|
|
loadGameState(ConfMan.getInt("save_slot"));
|
|
} else {
|
|
_strPlayer->playVideo("crystald.str");
|
|
_strPlayer->playVideo("illusion.str");
|
|
_strPlayer->playVideo("labintro.str");
|
|
|
|
init();
|
|
mainMenu();
|
|
loadScene(0);
|
|
}
|
|
|
|
_scene->draw();
|
|
_screen->updateScreen();
|
|
|
|
gameLoop();
|
|
|
|
delete _scene;
|
|
delete _actorManager;
|
|
delete _backgroundResourceLoader;
|
|
delete _dragonFLG;
|
|
delete _dragonImg;
|
|
delete _dragonRMS;
|
|
delete _dragonVAR;
|
|
delete _fontManager;
|
|
delete _bigfileArchive;
|
|
delete _screen;
|
|
delete _sound;
|
|
delete _strPlayer;
|
|
|
|
debug("Ok");
|
|
return Common::kNoError;
|
|
}
|
|
|
|
uint16 DragonsEngine::ipt_img_file_related() {
|
|
DragonINI *flicker = _dragonINIResource->getFlickerRecord();
|
|
assert(flicker);
|
|
|
|
int16 tileX = flicker->actor->_x_pos / 32;
|
|
int16 tileY = flicker->actor->_y_pos / 8;
|
|
|
|
for (int i = 0; i < _dragonINIResource->totalRecords(); i++) {
|
|
DragonINI *ini = getINI(i);
|
|
if ((ini->sceneId == getCurrentSceneId()) && (ini->flags == 0)) {
|
|
Img *img = _dragonImg->getImg(ini->imgId);
|
|
if ((img->x <= tileX) && (((tileX <= img->x + img->w && (img->y <= tileY)) && (tileY <= img->y + img->h)))) {
|
|
return i + 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void DragonsEngine::gameLoop() {
|
|
uint16 prevImgIniId = 0;
|
|
InventoryState uVar6;
|
|
InventoryState uVar7;
|
|
uint16 sequenceId;
|
|
|
|
_cursor->_cursorActivationSeqOffset = 0;
|
|
_bit_flags_8006fbd8 = 0;
|
|
_flickerIdleCounter = 0;
|
|
setFlags(ENGINE_FLAG_8);
|
|
|
|
while (!shouldQuit()) {
|
|
_scene->draw();
|
|
_screen->updateScreen();
|
|
wait();
|
|
updateHandler();
|
|
updateEvents();
|
|
runSceneUpdaterFunction(); //TODO is this the right place for this logic?
|
|
|
|
if (getCurrentSceneId() != 2) {
|
|
_sceneId1 = getCurrentSceneId();
|
|
}
|
|
|
|
updateFlickerIdleAnimation();
|
|
|
|
if (_bit_flags_8006fbd8 == 0) {
|
|
setFlags(ENGINE_FLAG_8);
|
|
}
|
|
if (_dragonINIResource->getFlickerRecord()->sceneId == getCurrentSceneId()) {
|
|
uint16 imgIniId = ipt_img_file_related();
|
|
if (imgIniId != 0 && imgIniId != (prevImgIniId & 0xffff)) {
|
|
byte *obd = _dragonOBD->getFromOpt(imgIniId - 1);
|
|
ScriptOpCall scriptOpCall(obd + 8, READ_LE_UINT32(obd));
|
|
|
|
if (_scriptOpcodes->runScript4(scriptOpCall)) {
|
|
scriptOpCall._codeEnd = scriptOpCall._code + 4 + READ_LE_UINT16(scriptOpCall._code + 2);
|
|
scriptOpCall._code += 4;
|
|
_scriptOpcodes->runScript(scriptOpCall);
|
|
_flickerIdleCounter = 0;
|
|
}
|
|
}
|
|
prevImgIniId = imgIniId;
|
|
} else {
|
|
prevImgIniId = 0;
|
|
}
|
|
|
|
if (_cursor->updateINIUnderCursor() == 0 ||
|
|
(!(_cursor->_iniUnderCursor & 0x8000) && (getINI(_cursor->_iniUnderCursor - 1)->flags & 0x4000) != 0)) { //TODO check this. This logic looks a bit strange.
|
|
_cursor->_cursorActivationSeqOffset = 0;
|
|
} else {
|
|
_cursor->_cursorActivationSeqOffset = 5;
|
|
}
|
|
|
|
if (_rightMouseButtonUp && isInputEnabled()) {
|
|
_cursor->selectPreviousCursor();
|
|
_flickerIdleCounter = 0;
|
|
continue;
|
|
}
|
|
// TODO implement cycle cursor up.
|
|
// actorId = CheckButtonMapPress_CycleUp(0);
|
|
// if (((actorId & 0xffff) != 0) && isInputEnabled()) {
|
|
// _cursor->_sequenceID = _cursor->_sequenceID + 1;
|
|
// if (_cursor->_iniItemInHand == 0) {
|
|
// 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;
|
|
// }
|
|
// _flickerIdleCounter = 0;
|
|
// actorId = uVar3;
|
|
// continue;
|
|
// }
|
|
|
|
if (_bit_flags_8006fbd8 == 3) {
|
|
_bit_flags_8006fbd8 = 0;
|
|
DragonINI *flicker = _dragonINIResource->getFlickerRecord();
|
|
if (flicker->sceneId == getCurrentSceneId() && flicker->actor->_direction != -1) {
|
|
int16 iniId = _scriptOpcodes->_scriptTargetINI;
|
|
if (_cursor->_sequenceID != 5) {
|
|
iniId = _cursor->_performActionTargetINI;
|
|
}
|
|
if (iniId > 0) {
|
|
flicker->actor->_direction = getINI(iniId - 1)->direction;
|
|
}
|
|
}
|
|
|
|
performAction();
|
|
if ((getCurrentSceneId() == 0x1d) && (getINI(0x178)->objectState != 0)) { //cave of dilemma
|
|
clearFlags(ENGINE_FLAG_8);
|
|
} else {
|
|
setFlags(ENGINE_FLAG_8);
|
|
}
|
|
_flickerIdleCounter = 0;
|
|
continue;
|
|
}
|
|
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;
|
|
} else {
|
|
_cursor->_sequenceID = 5;
|
|
}
|
|
}
|
|
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;
|
|
} else {
|
|
_cursor->_sequenceID = 5;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
} else {
|
|
if (_inventory->addItem(_cursor->_iniItemInHand)) {
|
|
_cursor->_sequenceID = 1;
|
|
waitForFrames(1);
|
|
_cursor->_iniItemInHand = 0;
|
|
_cursor->_iniUnderCursor = 0;
|
|
continue;
|
|
}
|
|
}
|
|
} else {
|
|
if (_cursor->_iniUnderCursor != 0x8001) {
|
|
_flickerIdleCounter = 0;
|
|
_cursor->_performActionTargetINI = _cursor->_iniUnderCursor;
|
|
_cursor->_data_800728b0_cursor_seqID = _cursor->_sequenceID;
|
|
walkFlickerToObject();
|
|
if (_bit_flags_8006fbd8 != 0) {
|
|
clearFlags(ENGINE_FLAG_8);
|
|
}
|
|
if (_cursor->_sequenceID >= 5) {
|
|
_scriptOpcodes->_scriptTargetINI = _cursor->_performActionTargetINI;
|
|
_cursor->_performActionTargetINI = _cursor->_iniItemInHand;
|
|
}
|
|
runINIScripts();
|
|
continue;
|
|
}
|
|
if (_inventory->getSequenceId() == 0) {
|
|
goto LAB_80027294;
|
|
}
|
|
}
|
|
if ((_cursor->_iniUnderCursor == 0x8001) && (_inventory->getSequenceId() == 1)) {
|
|
_inventory->setState(InventionBookOpen);
|
|
_inventory->_previousState = uVar6;
|
|
_inventory->openInventionBook();
|
|
continue;
|
|
}
|
|
}
|
|
_flickerIdleCounter = 0;
|
|
_cursor->_performActionTargetINI = _cursor->_iniUnderCursor;
|
|
_cursor->_data_800728b0_cursor_seqID = _cursor->_sequenceID;
|
|
walkFlickerToObject();
|
|
if (_bit_flags_8006fbd8 != 0) {
|
|
clearFlags(ENGINE_FLAG_8);
|
|
}
|
|
if (_cursor->_sequenceID >= 5) {
|
|
_scriptOpcodes->_scriptTargetINI = _cursor->_performActionTargetINI;
|
|
_cursor->_performActionTargetINI = _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();
|
|
continue;
|
|
}
|
|
_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->_performActionTargetINI = _cursor->_iniUnderCursor;
|
|
_cursor->_data_800728b0_cursor_seqID = _cursor->_sequenceID;
|
|
walkFlickerToObject();
|
|
if (_bit_flags_8006fbd8 != 0) {
|
|
clearFlags(ENGINE_FLAG_8);
|
|
}
|
|
if (_cursor->_sequenceID >= 5) {
|
|
_scriptOpcodes->_scriptTargetINI = _cursor->_performActionTargetINI;
|
|
_cursor->_performActionTargetINI = _cursor->_iniItemInHand;
|
|
}
|
|
}
|
|
}
|
|
runINIScripts();
|
|
continue;
|
|
}
|
|
if (checkForInventoryButtonRelease()) {
|
|
_flickerIdleCounter = 0;
|
|
_inventory->closeInventory();
|
|
_inventory->setPreviousState();
|
|
continue;
|
|
}
|
|
uVar6 = _inventory->getState();
|
|
if (checkForActionButtonRelease() && isFlagSet(ENGINE_FLAG_8)) {
|
|
_flickerIdleCounter = 0;
|
|
if ((_cursor->_iniUnderCursor & 0x8000) != 0) {
|
|
if (_cursor->_iniUnderCursor == 0x8001) {
|
|
_inventory->closeInventory();
|
|
_inventory->setState(Closed);
|
|
if (_inventory->_previousState == InventionBookOpen) {
|
|
_inventory->closeInventionBook();
|
|
}
|
|
} else {
|
|
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();
|
|
_inventory->setPreviousState();
|
|
}
|
|
continue;
|
|
}
|
|
_inventory->closeInventory();
|
|
_inventory->setState(InventionBookOpen);
|
|
if (_inventory->_previousState != InventionBookOpen) {
|
|
_inventory->openInventionBook();
|
|
}
|
|
}
|
|
_inventory->_previousState = uVar6;
|
|
continue;
|
|
}
|
|
if (_cursor->_iniUnderCursor != 0) {
|
|
if ((_cursor->_sequenceID != 4) && (_cursor->_sequenceID != 2)) {
|
|
_cursor->_data_800728b0_cursor_seqID = _cursor->_sequenceID;
|
|
_cursor->_performActionTargetINI = _cursor->_iniUnderCursor;
|
|
if (_cursor->_sequenceID >= 4) {
|
|
_cursor->_performActionTargetINI = _cursor->_iniItemInHand;
|
|
_scriptOpcodes->_scriptTargetINI = _cursor->_iniUnderCursor;
|
|
}
|
|
clearFlags(ENGINE_FLAG_8);
|
|
walkFlickerToObject();
|
|
if ((_cursor->_iniItemInHand == 0) ||
|
|
(((uint16)(_cursor->_x - 10U) < 300 && ((uint16)(_cursor->_y - 10U) < 0xb4)))) {
|
|
runINIScripts();
|
|
} else {
|
|
_cursor->_sequenceID = 5;
|
|
waitForFrames(2);
|
|
_inventory->closeInventory();
|
|
_inventory->setPreviousState();
|
|
}
|
|
continue;
|
|
}
|
|
Actor *actor = _inventory->getInventoryItemActor(_cursor->_iniUnderCursor);
|
|
uint16 tmpId = _cursor->_iniItemInHand;
|
|
_inventory->replaceItem(_cursor->_iniUnderCursor, _cursor->_iniItemInHand);
|
|
_cursor->_objectInHandSequenceID = actor->_sequenceID;
|
|
actor->clearFlag(ACTOR_FLAG_40);
|
|
_cursor->_iniItemInHand = _cursor->_iniUnderCursor;
|
|
_cursor->_sequenceID = 5;
|
|
if (tmpId != 0) {
|
|
actor->_flags = 0;
|
|
actor->_priorityLayer = 0;
|
|
actor->_scale = DRAGONS_ENGINE_SPRITE_100_PERCENT_SCALE;
|
|
actor->updateSequence(getINI(tmpId - 1)->inventorySequenceId * 2 + 10);
|
|
actor->setFlag(ACTOR_FLAG_40);
|
|
actor->setFlag(ACTOR_FLAG_80);
|
|
actor->setFlag(ACTOR_FLAG_100);
|
|
actor->setFlag(ACTOR_FLAG_200);
|
|
actor->_priorityLayer = 6;
|
|
}
|
|
continue;
|
|
}
|
|
if (_cursor->_iniItemInHand == 0) {
|
|
runINIScripts();
|
|
continue;
|
|
}
|
|
//drop item back into inventory
|
|
if (_inventory->addItemIfPositionIsEmpty(_cursor->_iniItemInHand, _cursor->_x, _cursor->_y)) {
|
|
Actor *invActor = _inventory->getInventoryItemActor(_cursor->_iniItemInHand);
|
|
invActor->_flags = 0;
|
|
invActor->_priorityLayer = 0;
|
|
invActor->_scale = DRAGONS_ENGINE_SPRITE_100_PERCENT_SCALE;
|
|
invActor->updateSequence(getINI(_cursor->_iniItemInHand - 1)->inventorySequenceId * 2 + 10);
|
|
_cursor->_iniItemInHand = 0;
|
|
invActor->setFlag(ACTOR_FLAG_40);
|
|
invActor->setFlag(ACTOR_FLAG_80);
|
|
invActor->setFlag(ACTOR_FLAG_100);
|
|
invActor->setFlag(ACTOR_FLAG_200);
|
|
invActor->_priorityLayer = 6;
|
|
if (_cursor->_sequenceID == 5) {
|
|
_cursor->_sequenceID = 4;
|
|
}
|
|
}
|
|
}
|
|
if ((_cursor->_iniItemInHand == 0) ||
|
|
(((uint16)(_cursor->_x - 10U) < 300 && ((uint16)(_cursor->_y - 10U) < 0xb4)))) {
|
|
runINIScripts();
|
|
} else {
|
|
_cursor->_sequenceID = 5;
|
|
waitForFrames(2);
|
|
_inventory->closeInventory();
|
|
_inventory->setPreviousState();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void DragonsEngine::updateHandler() {
|
|
_videoFlags |= 0x40;
|
|
//TODO logic here
|
|
|
|
updateActorSequences();
|
|
|
|
updateCamera();
|
|
|
|
_cursor->updateVisibility();
|
|
_inventory->updateVisibility();
|
|
|
|
_actorManager->updateActorDisplayOrder();
|
|
|
|
// 0x8001b200
|
|
if (isFlagSet(ENGINE_FLAG_8000) && !_sound->isSpeechPlaying()) {
|
|
clearFlags(ENGINE_FLAG_8000);
|
|
}
|
|
|
|
//TODO logic here
|
|
for (uint16 i = 0; i < 0x17; i++) {
|
|
Actor *actor = _actorManager->getActor(i);
|
|
if (actor->_flags & ACTOR_FLAG_40) {
|
|
if (!(actor->_flags & ACTOR_FLAG_100)) {
|
|
int16 priority = _scene->getPriorityAtPosition(Common::Point(actor->_x_pos, actor->_y_pos));
|
|
DragonINI *flicker = _dragonINIResource->getFlickerRecord();
|
|
if (flicker && _scene->contains(flicker) && flicker->actor->_actorID == i) {
|
|
if (priority < 8 || priority == 0x10) {
|
|
actor->_priorityLayer = priority;
|
|
}
|
|
} else {
|
|
if (priority != -1) {
|
|
actor->_priorityLayer = priority;
|
|
}
|
|
}
|
|
|
|
if (actor->_priorityLayer >= 0x11) {
|
|
actor->_priorityLayer = 0;
|
|
}
|
|
|
|
if (actor->_priorityLayer >= 9) {
|
|
actor->_priorityLayer -= 8;
|
|
}
|
|
}
|
|
|
|
if (actor->_sequenceTimer != 0) {
|
|
actor->_sequenceTimer--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_flags & ENGINE_FLAG_80) {
|
|
for (uint16 i = 0x17; i < DRAGONS_ENGINE_NUM_ACTORS; i++) {
|
|
Actor *actor = _actorManager->getActor(i);
|
|
if (actor->_sequenceTimer != 0) {
|
|
actor->_sequenceTimer--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isFlagSet(ENGINE_FLAG_4)) {
|
|
updatePathfindingActors();
|
|
}
|
|
|
|
// TODO 0x8001bed0
|
|
updatePaletteCycling();
|
|
|
|
// 0x8001c294
|
|
if (!(_unkFlags1 & ENGINE_UNK1_FLAG_8)) {
|
|
//TODO ReadPad();
|
|
}
|
|
|
|
if (isFlagSet(ENGINE_FLAG_20)) {
|
|
engineFlag0x20UpdateFunction();
|
|
}
|
|
|
|
runVsyncUpdaterFunction();
|
|
|
|
// TODO data_8006a3a0 logic. @ 0x8001c2f4
|
|
|
|
_videoFlags &= ~0x40;
|
|
}
|
|
|
|
uint32 DragonsEngine::calulateTimeLeft() {
|
|
uint32 now;
|
|
|
|
now = _system->getMillis();
|
|
|
|
if (_nextUpdatetime <= now) {
|
|
_nextUpdatetime = now + DRAGONS_TICK_INTERVAL;
|
|
return (0);
|
|
}
|
|
uint32 delay = _nextUpdatetime - now;
|
|
_nextUpdatetime += DRAGONS_TICK_INTERVAL;
|
|
return (delay);
|
|
}
|
|
|
|
void DragonsEngine::wait() {
|
|
_system->delayMillis(calulateTimeLeft());
|
|
}
|
|
|
|
void DragonsEngine::updateActorSequences() {
|
|
if (!(_flags & ENGINE_FLAG_4)) {
|
|
return;
|
|
}
|
|
|
|
//TODO ResetRCnt(0xf2000001);
|
|
|
|
int16 actorId = _flags & ENGINE_FLAG_80 ? (int16) 64 : (int16) 23;
|
|
|
|
while (actorId > 0) {
|
|
actorId--;
|
|
Actor *actor = _actorManager->getActor((uint16) actorId);
|
|
if (actorId < 2 && _flags & ENGINE_FLAG_40) {
|
|
continue;
|
|
}
|
|
|
|
if (actor->_flags & ACTOR_FLAG_40 &&
|
|
!(actor->_flags & ACTOR_FLAG_4) &&
|
|
!(actor->_flags & ACTOR_FLAG_400) &&
|
|
(actor->_sequenceTimer == 0 || actor->_flags & ACTOR_FLAG_1)) {
|
|
debug(5, "Actor[%d] execute sequenceOp", actorId);
|
|
|
|
if (actor->_flags & ACTOR_FLAG_1) {
|
|
actor->resetSequenceIP();
|
|
//clear flag mask 0xeff6;
|
|
actor->clearFlag(ACTOR_FLAG_1);
|
|
actor->clearFlag(ACTOR_FLAG_8);
|
|
actor->clearFlag(ACTOR_FLAG_1000);
|
|
actor->_field_7a = 0;
|
|
}
|
|
OpCall opCall;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::setFlags(uint32 flags) {
|
|
_flags |= flags;
|
|
}
|
|
|
|
void DragonsEngine::clearFlags(uint32 flags) {
|
|
_flags &= ~flags;
|
|
}
|
|
|
|
uint32 DragonsEngine::getMultipleFlags(uint32 flags) {
|
|
return _flags & flags;
|
|
}
|
|
|
|
uint32 DragonsEngine::getAllFlags() {
|
|
return _flags;
|
|
}
|
|
|
|
void DragonsEngine::setAllFlags(uint32 flags) {
|
|
_flags = flags;
|
|
}
|
|
|
|
void DragonsEngine::setUnkFlags(uint32 flags) {
|
|
_unkFlags1 |= flags;
|
|
}
|
|
|
|
void DragonsEngine::clearUnkFlags(uint32 flags) {
|
|
_unkFlags1 &= ~flags;
|
|
}
|
|
|
|
byte *DragonsEngine::getBackgroundPalette() {
|
|
assert(_scene);
|
|
return _scene->getPalette();
|
|
}
|
|
|
|
bool DragonsEngine::isFlagSet(uint32 flag) {
|
|
return (bool) (_flags & flag);
|
|
}
|
|
|
|
bool DragonsEngine::isUnkFlagSet(uint32 flag) {
|
|
return (bool) (_unkFlags1 & flag);
|
|
}
|
|
|
|
DragonINI *DragonsEngine::getINI(uint32 index) {
|
|
return _dragonINIResource->getRecord(index);
|
|
}
|
|
|
|
uint16 DragonsEngine::getVar(uint16 offset) {
|
|
return _dragonVAR->getVar(offset);
|
|
}
|
|
|
|
uint16 DragonsEngine::getCurrentSceneId() const {
|
|
return _scene->getSceneId();
|
|
}
|
|
|
|
void DragonsEngine::setVar(uint16 offset, uint16 value) {
|
|
return _dragonVAR->setVar(offset, value);
|
|
}
|
|
|
|
uint16 DragonsEngine::getIniFromImg() {
|
|
DragonINI *flicker = _dragonINIResource->getFlickerRecord();
|
|
|
|
int16 x = flicker->actor->_x_pos / 32;
|
|
int16 y = flicker->actor->_y_pos / 8;
|
|
|
|
uint16 currentSceneId = _scene->getSceneId();
|
|
|
|
for (uint16 i = 0; i < _dragonINIResource->totalRecords(); i++) {
|
|
DragonINI *ini = getINI(i);
|
|
if (ini->sceneId == currentSceneId && ini->flags == 0) {
|
|
Img *img = _dragonImg->getImg(ini->imgId);
|
|
if (x >= img->x &&
|
|
img->x + img->w >= x &&
|
|
y >= img->y &&
|
|
img->h + img->y >= y) {
|
|
return i + 1;
|
|
}
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void DragonsEngine::runINIScripts() {
|
|
bool isFlag8Set = isFlagSet(ENGINE_FLAG_8);
|
|
for (uint16 i = 0; i < _dragonINIResource->totalRecords(); i++) {
|
|
DragonINI *ini = getINI(i);
|
|
if (ini->flags & INI_FLAG_10) {
|
|
ini->flags &= ~INI_FLAG_10;
|
|
byte *data = _dragonOBD->getFromOpt(i);
|
|
ScriptOpCall scriptOpCall(data + 8, READ_LE_UINT32(data));
|
|
clearFlags(ENGINE_FLAG_8);
|
|
_scriptOpcodes->runScript3(scriptOpCall);
|
|
}
|
|
}
|
|
if (isFlag8Set) {
|
|
setFlags(ENGINE_FLAG_8);
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::engineFlag0x20UpdateFunction() {
|
|
if (!isFlagSet(ENGINE_FLAG_20)) {
|
|
_run_func_ptr_unk_countdown_timer = 1;
|
|
return;
|
|
}
|
|
|
|
if (isFlagSet(ENGINE_FLAG_8) && !isFlagSet(ENGINE_FLAG_8000000)) {
|
|
_cursor->update();
|
|
}
|
|
|
|
uint16 currentSceneId = _scene->getSceneId();
|
|
DragonINI *flickerINI = _dragonINIResource->getFlickerRecord();
|
|
DragonINI *ini1 = getINI(1);
|
|
|
|
if (flickerINI != nullptr) {
|
|
if (flickerINI->sceneId == currentSceneId) {
|
|
if (flickerINI->actor == nullptr || flickerINI->actor->isFlagSet(ACTOR_FLAG_10)) {
|
|
if (ini1->actor != nullptr) {
|
|
ini1->actor->updateSequence(8);
|
|
ini1->actor->_priorityLayer = 0;
|
|
}
|
|
} else {
|
|
if ((_bit_flags_8006fbd8 & 2u) == 0) {
|
|
_bit_flags_8006fbd8 |= 2u;
|
|
}
|
|
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);
|
|
}
|
|
if (ini1->actor != nullptr) {
|
|
ini1->actor->_priorityLayer = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 0x80027db8
|
|
if (!_inventory->isOpen()) {
|
|
for (uint16 i = 0; i < _dragonINIResource->totalRecords(); i++) {
|
|
DragonINI *ini = getINI(i);
|
|
if (ini->counter >= 0 && ini->sceneId == currentSceneId) {
|
|
ini->counter--;
|
|
if (ini->counter < 0) {
|
|
ini->flags |= INI_FLAG_10;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_run_func_ptr_unk_countdown_timer != 0) {
|
|
_run_func_ptr_unk_countdown_timer--;
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::waitForFrames(uint16 numFrames) {
|
|
for (uint16 i = 0; i < numFrames; i++) {
|
|
wait();
|
|
updateHandler();
|
|
|
|
_scene->draw();
|
|
_screen->updateScreen();
|
|
runSceneUpdaterFunction();
|
|
updateEvents();
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::waitForFramesAllowSkip(uint16 numFrames) {
|
|
for (int i = 0; i < numFrames; i++) {
|
|
waitForFrames(1);
|
|
if (checkForActionButtonRelease()) { // TODO should this be any input?
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::playOrStopSound(uint16 soundId) {
|
|
debug("play sound 0x%x", soundId);
|
|
|
|
this->_sound->playOrStopSound(soundId);
|
|
}
|
|
|
|
void DragonsEngine::updatePathfindingActors() {
|
|
for (uint16 i = 0; i < 0x17; i++) {
|
|
Actor *actor = _actorManager->getActor(i);
|
|
actor->walkPath();
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::fadeFromBlack(uint32 flags) {
|
|
if (!isFlagSet(ENGINE_FLAG_40)) {
|
|
return;
|
|
}
|
|
bool isUnkFlag2Set = isUnkFlagSet(ENGINE_UNK1_FLAG_2);
|
|
|
|
setUnkFlags(ENGINE_UNK1_FLAG_2);
|
|
clearFlags(ENGINE_FLAG_40);
|
|
|
|
//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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::performAction() {
|
|
uint uVar1;
|
|
uint16 uVar2;
|
|
uint uVar4;
|
|
uint uVar5;
|
|
uint uVar6;
|
|
byte * pvVar7;
|
|
byte * pvVar8;
|
|
byte *local_58_code;
|
|
byte *local_58_codeEnd;
|
|
bool load_58_result = false;
|
|
|
|
uVar2 = _scriptOpcodes->_scriptTargetINI;
|
|
uVar1 = _flags;
|
|
local_58_code = nullptr;
|
|
local_58_codeEnd = nullptr;
|
|
|
|
uVar6 = 0;
|
|
_scriptOpcodes->_numDialogStackFramesToPop = 0;
|
|
|
|
assert(_cursor->_performActionTargetINI > 0);
|
|
byte *obd = _dragonOBD->getFromOpt(_cursor->_performActionTargetINI - 1);
|
|
|
|
|
|
ScriptOpCall local_48(obd + 8, READ_LE_UINT32(obd));
|
|
pvVar7 = local_48._code;
|
|
pvVar8 = local_48._codeEnd;
|
|
|
|
uVar4 = _cursor->executeScript(local_48, 1);
|
|
if (_cursor->_data_800728b0_cursor_seqID > 4) {
|
|
_scriptOpcodes->_numDialogStackFramesToPop = 0;
|
|
|
|
obd = _dragonOBD->getFromOpt(_scriptOpcodes->_scriptTargetINI - 1);
|
|
_scriptOpcodes->_scriptTargetINI = _cursor->_performActionTargetINI;
|
|
|
|
ScriptOpCall local_38(obd + 8, READ_LE_UINT32(obd));
|
|
|
|
uVar6 = _cursor->executeScript(local_38, 1);
|
|
_scriptOpcodes->_scriptTargetINI = uVar2;
|
|
|
|
if ((uVar6 & 0xffff) != 0) {
|
|
local_58_code = local_38._code + 8;
|
|
local_58_codeEnd = local_58_code + READ_LE_UINT16(local_38._code + 6);
|
|
}
|
|
}
|
|
if (((uVar4 & 0xffff) != 0) && ((((uVar4 & 2) == 0 || ((uVar6 & 2) != 0)) || ((uVar6 & 0xffff) == 0)))) {
|
|
local_58_code = local_48._code + 8;
|
|
local_58_codeEnd = local_58_code + READ_LE_UINT16(local_48._code + 6);
|
|
}
|
|
uVar4 = uVar4 & 0xfffd;
|
|
if (local_58_code != nullptr && local_58_codeEnd != nullptr) {
|
|
clearFlags(ENGINE_FLAG_8);
|
|
ScriptOpCall local_58(local_58_code, local_58_codeEnd - local_58_code);
|
|
_scriptOpcodes->runScript(local_58);
|
|
load_58_result = local_58._result;
|
|
}
|
|
if (!load_58_result) {
|
|
if (_cursor->_data_800728b0_cursor_seqID == 3) {
|
|
ScriptOpCall local_58(pvVar7, pvVar8 - pvVar7);
|
|
uVar5 = _talk->talkToActor(local_58);
|
|
uVar4 = uVar4 | uVar5;
|
|
}
|
|
if (((uVar4 & 0xffff) == 0) && ((uVar6 & 0xfffd) == 0)) {
|
|
_talk->flickerRandomDefaultResponse();
|
|
}
|
|
} else {
|
|
_scriptOpcodes->_numDialogStackFramesToPop--;
|
|
}
|
|
_flags |= uVar1 & ENGINE_FLAG_8;
|
|
return;
|
|
}
|
|
|
|
bool DragonsEngine::checkForInventoryButtonRelease() {
|
|
return _iKeyUp;
|
|
}
|
|
|
|
bool DragonsEngine::isInputEnabled() {
|
|
return !isFlagSet(ENGINE_FLAG_20000000) && !isFlagSet(ENGINE_FLAG_400);
|
|
}
|
|
|
|
bool DragonsEngine::isActionButtonPressed() {
|
|
return _leftMouseButtonDown;
|
|
}
|
|
|
|
bool DragonsEngine::isLeftKeyPressed() {
|
|
return _leftKeyDown;
|
|
}
|
|
|
|
bool DragonsEngine::isRightKeyPressed() {
|
|
return _rightKeyDown;
|
|
}
|
|
|
|
bool DragonsEngine::isUpKeyPressed() {
|
|
return false; // TODO
|
|
}
|
|
|
|
bool DragonsEngine::isDownKeyPressed() {
|
|
return false; // TODO
|
|
}
|
|
|
|
bool DragonsEngine::checkForActionButtonRelease() {
|
|
return _leftMouseButtonUp || _enterKeyUp;
|
|
}
|
|
|
|
void DragonsEngine::walkFlickerToObject() {
|
|
uint16 targetX;
|
|
uint16 targetY;
|
|
uint uVar7;
|
|
uint uVar8;
|
|
DragonINI *targetINI;
|
|
DragonINI *flickerINI;
|
|
|
|
flickerINI = _dragonINIResource->getFlickerRecord();
|
|
if (flickerINI->sceneId == getCurrentSceneId()) {
|
|
if (_cursor->_performActionTargetINI != 0) {
|
|
|
|
if (!(READ_LE_UINT16(_dragonOBD->getFromOpt(_cursor->_performActionTargetINI - 1) + 4) & 8)
|
|
&& (_inventory->getState() == Closed) && !isFlagSet(ENGINE_FLAG_200000)) {
|
|
targetINI = getINI(_cursor->_performActionTargetINI - 1);
|
|
if ((targetINI->flags & 1) == 0) {
|
|
if (targetINI->actorResourceId == -1) {
|
|
return;
|
|
}
|
|
Img *img = _dragonImg->getImg(targetINI->imgId);
|
|
targetX = img->field_a;
|
|
targetY = img->field_c;
|
|
} else {
|
|
targetX = targetINI->actor->_x_pos;
|
|
targetY = targetINI->actor->_y_pos;
|
|
}
|
|
flickerINI->actor->_walkSpeed = 0x10000;
|
|
if (flickerINI->direction2 == -1) {
|
|
flickerINI->actor->setFlag(ACTOR_FLAG_800);
|
|
}
|
|
flickerINI->actor->startWalk((int)(((uint)targetX + (uint)targetINI->baseXOffset) * 0x10000) >> 0x10,
|
|
(int)(((uint)targetY + (uint)targetINI->baseYOffset) * 0x10000) >> 0x10, 0);
|
|
_bit_flags_8006fbd8 = 1; //walk to perform an action.
|
|
return;
|
|
}
|
|
if (isFlagSet(ENGINE_FLAG_200000)) {
|
|
_bit_flags_8006fbd8 = 3;
|
|
return;
|
|
}
|
|
flickerINI = _dragonINIResource->getFlickerRecord();
|
|
if (flickerINI != nullptr && flickerINI->actor != nullptr) {
|
|
flickerINI->actor->clearFlag(ACTOR_FLAG_10);
|
|
flickerINI->actor->setFlag(ACTOR_FLAG_4);
|
|
targetINI = getINI(_cursor->_performActionTargetINI - 1);
|
|
flickerINI->direction2 = targetINI->direction;
|
|
flickerINI->actor->_direction = targetINI->direction;
|
|
}
|
|
_bit_flags_8006fbd8 = 3;
|
|
return;
|
|
}
|
|
if (_inventory->getState() == Closed && !isFlagSet(ENGINE_FLAG_200000)) {
|
|
uVar7 = (uint)(uint16)_cursor->_x;
|
|
uVar8 = (uint)(uint16)_cursor->_y;
|
|
flickerINI->actor->_walkSpeed = 0x10000;
|
|
flickerINI->actor->startWalk(
|
|
(int)((uVar7 + (uint)_scene->_camera.x) * 0x10000) >> 0x10,
|
|
(int)((uVar8 + (uint)_scene->_camera.y) * 0x10000) >> 0x10, 0);
|
|
}
|
|
} else {
|
|
if (_cursor->_performActionTargetINI != 0) {
|
|
_bit_flags_8006fbd8 = 3;
|
|
return;
|
|
}
|
|
}
|
|
_bit_flags_8006fbd8 = 0;
|
|
return;
|
|
}
|
|
|
|
void DragonsEngine::reset_screen_maybe() {
|
|
_videoFlags &= ~0x10;
|
|
//TODO
|
|
}
|
|
|
|
bool DragonsEngine::canLoadGameStateCurrently() {
|
|
return isInputEnabled();
|
|
}
|
|
|
|
bool DragonsEngine::canSaveGameStateCurrently() {
|
|
return isInputEnabled() && !_inventory->isOpen();
|
|
}
|
|
|
|
bool DragonsEngine::hasFeature(Engine::EngineFeature f) const {
|
|
return
|
|
// TODO (f == kSupportsRTL) ||
|
|
(f == kSupportsLoadingDuringRuntime) ||
|
|
(f == kSupportsSavingDuringRuntime);
|
|
}
|
|
|
|
void DragonsEngine::init() {
|
|
_flags = 0x1046;
|
|
_flags &= 0x1c07040;
|
|
_flags |= 0x26;
|
|
_unkFlags1 = 0;
|
|
|
|
initSubtitleFlag();
|
|
|
|
_scriptOpcodes->_scriptTargetINI = 0; //TODO this should be reset in scriptopcode.
|
|
_cursor->init(_actorManager, _dragonINIResource);
|
|
_inventory->init(_actorManager, _backgroundResourceLoader, new Bag(_bigfileArchive, _screen), _dragonINIResource);
|
|
_talk->init();
|
|
|
|
_screen->loadPalette(1, _cursor->getPalette());
|
|
setupPalette1();
|
|
|
|
_screen->loadPalette(2, _cursor->getPalette());
|
|
_screen->updatePaletteTransparency(2, 1, 5, true);
|
|
_screen->updatePaletteTransparency(2, 0xc1, 0xc3, true);
|
|
|
|
_screen->loadPalette(4, _cursor->getPalette());
|
|
_screen->updatePaletteTransparency(4, 1, 0xff, true);
|
|
}
|
|
|
|
void DragonsEngine::loadScene(uint16 sceneId) {
|
|
// TODO fun_80017010_update_actor_texture_maybe();
|
|
if (sceneId > 2) {
|
|
_dragonVAR->setVar(1, 1);
|
|
}
|
|
|
|
//if (sceneId > 2) { //TODO remove this restriction to enable intro sequence.
|
|
_scene->setSceneId(2);
|
|
byte *obd = _dragonOBD->getFromSpt(3);
|
|
ScriptOpCall scriptOpCall(obd + 4, READ_LE_UINT32(obd));
|
|
_scriptOpcodes->runScript(scriptOpCall);
|
|
//} else {
|
|
// sceneId = 0x12; // HACK the first scene. TODO remove this
|
|
// }
|
|
|
|
_inventory->loadInventoryItemsFromSave();
|
|
|
|
if (getINI(0)->sceneId == 0) {
|
|
getINI(0)->sceneId = sceneId; //TODO
|
|
} else {
|
|
_scene->setSceneId(getINI(0)->sceneId);
|
|
}
|
|
_sceneId1 = sceneId;
|
|
_scene->loadScene(sceneId ? sceneId : 0x12, 0x1e);
|
|
}
|
|
|
|
void DragonsEngine::reset() {
|
|
seedRandom(0x1dd); //TODO should we randomise this better? I got this value from a couple of runs in the emulator
|
|
_nextUpdatetime = 0;
|
|
_flags = 0;
|
|
_unkFlags1 = 0;
|
|
_run_func_ptr_unk_countdown_timer = 0;
|
|
_videoFlags = 0;
|
|
_flickerInitialSceneDirection = 0;
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
_paletteCyclingTbl[i].paletteType = 0;
|
|
_paletteCyclingTbl[i].startOffset = 0;
|
|
_paletteCyclingTbl[i].endOffset = 0;
|
|
_paletteCyclingTbl[i].updateInterval = 0;
|
|
_paletteCyclingTbl[i].updateCounter = 0;
|
|
}
|
|
|
|
clearSceneUpdateFunction();
|
|
}
|
|
|
|
void DragonsEngine::runSceneUpdaterFunction() {
|
|
if ((isFlagSet(ENGINE_FLAG_20) && (_run_func_ptr_unk_countdown_timer == 0)) &&
|
|
(_run_func_ptr_unk_countdown_timer = 1, _sceneUpdateFunction != nullptr)) {
|
|
_sceneUpdateFunction();
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::setSceneUpdateFunction(void (*newUpdateFunction)()) {
|
|
_sceneUpdateFunction = newUpdateFunction;
|
|
}
|
|
|
|
void DragonsEngine::clearSceneUpdateFunction() {
|
|
setSceneUpdateFunction(nullptr);
|
|
}
|
|
|
|
void DragonsEngine::setVsyncUpdateFunction(void (*newUpdateFunction)()) {
|
|
_vsyncUpdateFunction = newUpdateFunction;
|
|
}
|
|
|
|
void DragonsEngine::seedRandom(int32 seed) {
|
|
_randomState = seed * -0x2b0e2b0f;
|
|
}
|
|
|
|
uint32 DragonsEngine::shuffleRandState() {
|
|
uint32 returnBit;
|
|
|
|
returnBit = _randomState & 1;
|
|
_randomState = _randomState >> 1 |
|
|
((_randomState << 0x1e ^ _randomState ^ _randomState << 0x1d ^ _randomState << 0x1b ^
|
|
_randomState << 0x19) & 0x80000000);
|
|
return returnBit;
|
|
}
|
|
|
|
uint16 DragonsEngine::getRand(uint16 max) {
|
|
uint16 rand = 0;
|
|
|
|
for (int i = 0; i < 0x10; i++) {
|
|
rand |= shuffleRandState() << i;
|
|
}
|
|
return rand % max;
|
|
}
|
|
|
|
bool DragonsEngine::checkForDownKeyRelease() {
|
|
return _downKeyUp;
|
|
}
|
|
|
|
bool DragonsEngine::checkForUpKeyRelease() {
|
|
return _upKeyUp;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void DragonsEngine::setupPalette1() {
|
|
byte palette[512];
|
|
memcpy(palette, _cursor->getPalette(), 0x100);
|
|
memcpy(palette + 0x100, _cursor->getPalette(), 0x100);
|
|
_screen->loadPalette(1, palette);
|
|
_screen->updatePaletteTransparency(1, 0x40, 0x7f, true);
|
|
}
|
|
|
|
bool DragonsEngine::isDebugMode() {
|
|
return _debugMode;
|
|
}
|
|
|
|
bool DragonsEngine::isVsyncUpdaterFunctionRunning() {
|
|
return _vsyncUpdateFunction != nullptr;
|
|
}
|
|
|
|
void DragonsEngine::runVsyncUpdaterFunction() {
|
|
if (isVsyncUpdaterFunctionRunning()) {
|
|
_vsyncUpdateFunction();
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::loadCurrentSceneMsf() {
|
|
_sound->loadMsf(getCurrentSceneId());
|
|
}
|
|
|
|
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);
|
|
int16 uVar14 = (uint)(uint16)_paletteCyclingTbl[loopIndex].startOffset;
|
|
int16 uVar8 = (uint)(uint16)_paletteCyclingTbl[loopIndex].endOffset;
|
|
if (uVar14 < uVar8) {
|
|
uint16 uVar11 = palette[uVar8];
|
|
int uVar15 = uVar8;
|
|
if (uVar14 < uVar8) {
|
|
do {
|
|
uVar8--;
|
|
palette[uVar15] = palette[uVar15 - 1];
|
|
uVar15 = uVar8 & 0xffff;
|
|
} while ((uint)(uint16)_paletteCyclingTbl[loopIndex].startOffset < (uVar8 & 0xffff));
|
|
}
|
|
palette[(uint16)_paletteCyclingTbl[loopIndex].startOffset] = uVar11;
|
|
_paletteCyclingTbl[loopIndex].updateCounter = _paletteCyclingTbl[loopIndex].updateInterval;
|
|
} else {
|
|
if (uVar8 < uVar14) {
|
|
uint16 uVar11 = palette[uVar14];
|
|
uint16 uVar15 = uVar8;
|
|
if (uVar8 < uVar14) {
|
|
do {
|
|
uVar8--;
|
|
palette[uVar15] = palette[uVar15 + 1];
|
|
uVar15 = uVar8 & 0xffff;
|
|
} while ((uVar8 & 0xffff) < (uint)(uint16)_paletteCyclingTbl[loopIndex].startOffset);
|
|
}
|
|
palette[(uint16)_paletteCyclingTbl[loopIndex].endOffset] = uVar11;
|
|
_paletteCyclingTbl[loopIndex].updateCounter =
|
|
_paletteCyclingTbl[loopIndex].updateInterval;
|
|
}
|
|
}
|
|
} else {
|
|
_paletteCyclingTbl[loopIndex].updateCounter = _paletteCyclingTbl[loopIndex].updateCounter + -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32 DragonsEngine::getFontOffsetFromDragonEXE() {
|
|
switch (_language) {
|
|
case Common::EN_USA : return 0x4a144;
|
|
case Common::EN_GRB : return 0x4b4fc;
|
|
case Common::DE_DEU : return 0x4af5c;
|
|
case Common::FR_FRA : return 0x4b158;
|
|
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;
|
|
case Common::EN_GRB : return 0x4f4f4;
|
|
case Common::DE_DEU : return 0x4f0a4;
|
|
case Common::FR_FRA : return 0x4f2a0;
|
|
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;
|
|
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;
|
|
default :
|
|
error("Unable to get speech table offset from dragon.exe for %s", getLanguageCode(_language));
|
|
}
|
|
}
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::updateFlickerIdleAnimation() {
|
|
_flickerIdleCounter++;
|
|
if (_flickerIdleCounter >= 0x4af) {
|
|
DragonINI *flicker = _dragonINIResource->getFlickerRecord();
|
|
if (flicker->actor->_resourceID == 0xe) {
|
|
flicker->actor->_direction = 2;
|
|
flicker->direction2 = 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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DragonsEngine::initSubtitleFlag() {
|
|
bool showSubtitles = ConfMan.getBool("subtitles");
|
|
if (showSubtitles) {
|
|
clearFlags(ENGINE_FLAG_1000_SUBTITLES_DISABLED);
|
|
} else {
|
|
setFlags(ENGINE_FLAG_1000_SUBTITLES_DISABLED);
|
|
}
|
|
}
|
|
|
|
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(©right[i][0]) * 8, (0x12 + i) * 8, ©right[i][0], strlen(copyright[i]), 1);
|
|
}
|
|
|
|
waitForFramesAllowSkip(400);
|
|
_fontManager->clearText();
|
|
actor->updateSequence(1);
|
|
|
|
bool startGame = false;
|
|
do {
|
|
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);
|
|
}
|
|
if (checkForDownKeyRelease()) {
|
|
if (curMenuItem < 2) {
|
|
curMenuItem++;
|
|
} else {
|
|
curMenuItem = 0;
|
|
}
|
|
playOrStopSound(0x8009);
|
|
}
|
|
|
|
if (checkForUpKeyRelease()) {
|
|
if (curMenuItem > 0) {
|
|
curMenuItem--;
|
|
} else {
|
|
curMenuItem = 2;
|
|
}
|
|
playOrStopSound(0x8009);
|
|
}
|
|
waitForFrames(1);
|
|
} while (!checkForActionButtonRelease() && !shouldQuit());
|
|
|
|
if (curMenuItem == 0) {
|
|
_screen->clearScreen();
|
|
loadingScreen();
|
|
startGame = true;
|
|
} else if (curMenuItem == 1) {
|
|
//TODO options menu
|
|
} else if (curMenuItem == 2) {
|
|
_strPlayer->playVideo("previews.str");
|
|
}
|
|
} while (!shouldQuit() && !startGame);
|
|
|
|
_inMenu = false;
|
|
}
|
|
|
|
bool DragonsEngine::isInMenu() {
|
|
return _inMenu;
|
|
}
|
|
|
|
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++) {
|
|
flameYOffset = _loadingScreenState->baseYOffset - flameOffsetTbl[(i + _loadingScreenState->flameOffsetIdx) % 26];
|
|
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;
|
|
}
|
|
}
|
|
_loadingScreenState->flameOffsetIdx = (_loadingScreenState->flameOffsetIdx + 1) % 26;
|
|
} else {
|
|
_loadingScreenState->loadingFlamesUpdateCounter--;
|
|
}
|
|
|
|
if (_loadingScreenState->loadingFlamesRiseCounter == 0) {
|
|
_loadingScreenState->loadingFlamesRiseCounter = 1;
|
|
_loadingScreenState->baseYOffset--;
|
|
} else {
|
|
_loadingScreenState->loadingFlamesRiseCounter--;
|
|
}
|
|
}
|
|
|
|
void (*DragonsEngine::getSceneUpdateFunction())() {
|
|
return _sceneUpdateFunction;
|
|
}
|
|
|
|
} // End of namespace Dragons
|