TWINE: cleanup input code and replaced magic numbers

This commit is contained in:
Martin Gerhardy 2020-10-26 00:24:41 +01:00
parent 934a250cfd
commit b307011170
9 changed files with 28 additions and 75 deletions

View file

@ -42,7 +42,7 @@ Actor::Actor(TwinEEngine *engine) : _engine(engine) {
} }
void Actor::restartHeroScene() { void Actor::restartHeroScene() {
_engine->_scene->sceneHero->controlMode = 1; _engine->_scene->sceneHero->controlMode = ControlMode::kManual;
memset(&_engine->_scene->sceneHero->dynamicFlags, 0, sizeof(_engine->_scene->sceneHero->dynamicFlags)); memset(&_engine->_scene->sceneHero->dynamicFlags, 0, sizeof(_engine->_scene->sceneHero->dynamicFlags));
memset(&_engine->_scene->sceneHero->staticFlags, 0, sizeof(_engine->_scene->sceneHero->staticFlags)); memset(&_engine->_scene->sceneHero->staticFlags, 0, sizeof(_engine->_scene->sceneHero->staticFlags));
@ -387,7 +387,7 @@ void Actor::resetActor(int16 actorIdx) {
actor->angle = 0; actor->angle = 0;
actor->speed = 40; actor->speed = 40;
actor->controlMode = 0; actor->controlMode = ControlMode::kNoMove;
actor->info0 = 0; actor->info0 = 0;
actor->info1 = 0; actor->info1 = 0;

View file

@ -147,6 +147,18 @@ struct DynamicFlagsStruct {
uint16 bUnk8000 : 1; // 0x8000 unused uint16 bUnk8000 : 1; // 0x8000 unused
}; };
/** Control mode types */
enum ControlMode {
kNoMove = 0,
kManual = 1,
kFollow = 2,
kTrack = 3,
kFollow2 = 4,
kTrackAttack = 5,
kSameXZ = 6,
kRandom = 7
};
/** Actors structure */ /** Actors structure */
struct ActorStruct { struct ActorStruct {
StaticFlagsStruct staticFlags; StaticFlagsStruct staticFlags;
@ -170,7 +182,7 @@ struct ActorStruct {
int32 bonusParameter = 0; // field_10 int32 bonusParameter = 0; // field_10
int32 angle = 0; int32 angle = 0;
int32 speed = 0; int32 speed = 0;
int32 controlMode = 0; ControlMode controlMode = ControlMode::kNoMove;
int32 info0 = 0; // cropLeft int32 info0 = 0; // cropLeft
int32 info1 = 0; // cropTop int32 info1 = 0; // cropTop
int32 info2 = 0; // cropRight int32 info2 = 0; // cropRight

View file

@ -73,14 +73,6 @@ static const struct KeyProperties {
{0x00, false, 0x00}}; {0x00, false, 0x00}};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map"); static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
ScopedKeyMapperDisable::ScopedKeyMapperDisable() {
g_system->getEventManager()->getKeymapper()->setEnabled(false);
}
ScopedKeyMapperDisable::~ScopedKeyMapperDisable() {
g_system->getEventManager()->getKeymapper()->setEnabled(true);
}
ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) { ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) {
_prevKeyMap = _engine->_input->currentKeyMap(); _prevKeyMap = _engine->_input->currentKeyMap();
_engine->_input->enableKeyMap(cutsceneKeyMapId); _engine->_input->enableKeyMap(cutsceneKeyMapId);
@ -92,13 +84,6 @@ ScopedKeyMap::~ScopedKeyMap() {
Input::Input(TwinEEngine *engine) : _engine(engine) {} Input::Input(TwinEEngine *engine) : _engine(engine) {}
bool Input::isPressed(Common::KeyCode keycode, bool onlyFirstTime) const {
if (onlyFirstTime) {
return _pressed[keycode] == 1;
}
return _pressed[keycode] > 0;
}
bool Input::isActionActive(TwinEActionType actionType, bool onlyFirstTime) const { bool Input::isActionActive(TwinEActionType actionType, bool onlyFirstTime) const {
if (onlyFirstTime) { if (onlyFirstTime) {
return actionStates[actionType] == 1; return actionStates[actionType] == 1;
@ -127,9 +112,6 @@ void Input::enableKeyMap(const char *id) {
return; return;
} }
// switching the keymap must also disable all other action keys
memset(_pressed, 0, sizeof(_pressed));
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper(); Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
const Common::KeymapArray &keymaps = keymapper->getKeymaps(); const Common::KeymapArray &keymaps = keymapper->getKeymaps();
for (Common::Keymap *keymap : keymaps) { for (Common::Keymap *keymap : keymaps) {
@ -183,12 +165,6 @@ void Input::readKeys() {
case Common::EVENT_LBUTTONDOWN: case Common::EVENT_LBUTTONDOWN:
leftMouse = 1; leftMouse = 1;
break; break;
case Common::EVENT_KEYDOWN:
_pressed[event.kbd.keycode] = 1 + event.kbdRepeat;
break;
case Common::EVENT_KEYUP:
_pressed[event.kbd.keycode] = 0;
break;
case Common::EVENT_RBUTTONDOWN: case Common::EVENT_RBUTTONDOWN:
rightMouse = 1; rightMouse = 1;
break; break;

View file

@ -134,15 +134,6 @@ struct MouseStatusStruct {
int32 y = 0; int32 y = 0;
}; };
/**
* @brief Whenever text input is needed (like the playername)
* you have to disable the keymaps
*/
struct ScopedKeyMapperDisable {
ScopedKeyMapperDisable();
~ScopedKeyMapperDisable();
};
/** /**
* @brief Activates the given key map id that is registered in the meta engine * @brief Activates the given key map id that is registered in the meta engine
*/ */
@ -158,7 +149,6 @@ public:
class Input { class Input {
private: private:
TwinEEngine *_engine; TwinEEngine *_engine;
uint8 _pressed[Common::KEYCODE_LAST]{0};
Common::String _currentKeyMap; Common::String _currentKeyMap;
uint8 actionStates[TwinEActionType::Max]{false}; uint8 actionStates[TwinEActionType::Max]{false};
@ -197,20 +187,6 @@ public:
bool toggleAbortAction(); bool toggleAbortAction();
/**
* @param onlyFirstTime If this is set to @c true, repeating key press events are not taken into account here
* This means, that even if the key is held down, this will return @c false. @c false as value for this parameter
* will return @c true also for repeating key presses.
*
* @note You won't receive any pressed events if you have that key bound to a @c TwinEActionType value.
* @sa isActionActive()
*/
bool isPressed(Common::KeyCode keycode, bool onlyFirstTime = true) const;
inline bool isPressedEnter(bool onlyFirstTime = true) const {
return isPressed(Common::KEYCODE_RETURN, onlyFirstTime) || isPressed(Common::KEYCODE_KP_ENTER, onlyFirstTime);
}
bool isQuickBehaviourActionActive() const; bool isQuickBehaviourActionActive() const;
/** /**

View file

@ -281,7 +281,7 @@ void Movements::processActorMovements(int32 actorIdx) {
heroPressedKey = _engine->_input->key; heroPressedKey = _engine->_input->key;
} else { } else {
if (!actor->staticFlags.bIsSpriteActor) { if (!actor->staticFlags.bIsSpriteActor) {
if (actor->controlMode != kManual) { if (actor->controlMode != ControlMode::kManual) {
actor->angle = getRealAngle(&actor->move); actor->angle = getRealAngle(&actor->move);
} }
} }

View file

@ -28,18 +28,6 @@
namespace TwinE { namespace TwinE {
/** Control mode types */
enum ControlMode {
kNoMove = 0,
kManual = 1,
kFollow = 2,
kTrack = 3,
kFollow2 = 4,
kTrackAttack = 5,
kSameXZ = 6,
kRandom = 7
};
class TwinEEngine; class TwinEEngine;
class Movements { class Movements {

View file

@ -170,7 +170,7 @@ bool Scene::loadSceneLBA1() {
act->bonusParameter &= 0xFE; act->bonusParameter &= 0xFE;
act->angle = stream.readUint16LE(); act->angle = stream.readUint16LE();
act->speed = stream.readUint16LE(); act->speed = stream.readUint16LE();
act->controlMode = stream.readUint16LE(); act->controlMode = (ControlMode)stream.readUint16LE();
act->info0 = stream.readUint16LE(); act->info0 = stream.readUint16LE();
act->info1 = stream.readUint16LE(); act->info1 = stream.readUint16LE();
act->info2 = stream.readUint16LE(); act->info2 = stream.readUint16LE();
@ -266,7 +266,7 @@ void Scene::changeScene() {
resetScene(); resetScene();
_engine->_actor->loadHeroEntities(); _engine->_actor->loadHeroEntities();
sceneHero->controlMode = 1; sceneHero->controlMode = ControlMode::kManual;
sceneHero->zone = -1; sceneHero->zone = -1;
sceneHero->positionInLifeScript = 0; sceneHero->positionInLifeScript = 0;
sceneHero->positionInMoveScript = -1; sceneHero->positionInMoveScript = -1;

View file

@ -589,8 +589,8 @@ static int32 lFALLABLE(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor)
static int32 lSET_DIRMODE(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) { static int32 lSET_DIRMODE(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
int32 controlMode = *(scriptPtr++); int32 controlMode = *(scriptPtr++);
actor->controlMode = controlMode; actor->controlMode = (ControlMode)controlMode;
if (controlMode == kFollow) { if (actor->controlMode == ControlMode::kFollow) {
actor->followedActor = *(scriptPtr++); actor->followedActor = *(scriptPtr++);
} }
@ -602,9 +602,10 @@ static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, int32 actorIdx, ActorStruct *
int32 otherActorIdx = *(scriptPtr++); int32 otherActorIdx = *(scriptPtr++);
int32 controlMode = *(scriptPtr++); int32 controlMode = *(scriptPtr++);
engine->_scene->getActor(otherActorIdx)->controlMode = controlMode; ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
if (controlMode == kFollow) { otherActor->controlMode = (ControlMode)controlMode;
engine->_scene->getActor(otherActorIdx)->followedActor = *(scriptPtr++); if (otherActor->controlMode == ControlMode::kFollow) {
otherActor->followedActor = *(scriptPtr++);
} }
return 0; return 0;

View file

@ -419,7 +419,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
// inventory menu // inventory menu
loopInventoryItem = -1; loopInventoryItem = -1;
if (_input->isActionActive(TwinEActionType::InventoryMenu) && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) { if (_input->isActionActive(TwinEActionType::InventoryMenu) && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == ControlMode::kManual) {
freezeTime(); freezeTime();
_menu->processInventoryMenu(); _menu->processInventoryMenu();
@ -535,7 +535,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false) || _input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false) ||
_input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false) || _input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false) ||
_input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) && _input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) &&
_scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) { _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == ControlMode::kManual) {
if (_input->isActionActive(TwinEActionType::QuickBehaviourNormal, false)) { if (_input->isActionActive(TwinEActionType::QuickBehaviourNormal, false)) {
_actor->heroBehaviour = HeroBehaviourType::kNormal; _actor->heroBehaviour = HeroBehaviourType::kNormal;
} else if (_input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false)) { } else if (_input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false)) {
@ -627,7 +627,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (actor->life == 0) { if (actor->life == 0) {
if (a == 0) { // if its hero who died if (a == 0) { // if its hero who died
_animations->initAnim(kLandDeath, 4, 0, 0); _animations->initAnim(kLandDeath, 4, 0, 0);
actor->controlMode = 0; actor->controlMode = ControlMode::kNoMove;
} else { } else {
_sound->playSample(37, getRandomNumber(2000) + 3096, 1, actor->x, actor->y, actor->z, a); _sound->playSample(37, getRandomNumber(2000) + 3096, 1, actor->x, actor->y, actor->z, a);
@ -691,7 +691,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_actor->cropBottomScreen = _renderer->projPosY; _actor->cropBottomScreen = _renderer->projPosY;
} }
_renderer->projectPositionOnScreen(actor->x - _grid->cameraX, actor->y - _grid->cameraY, actor->z - _grid->cameraZ); _renderer->projectPositionOnScreen(actor->x - _grid->cameraX, actor->y - _grid->cameraY, actor->z - _grid->cameraZ);
actor->controlMode = 0; actor->controlMode = ControlMode::kNoMove;
actor->life = -1; actor->life = -1;
_actor->cropBottomScreen = _renderer->projPosY; _actor->cropBottomScreen = _renderer->projPosY;
actor->staticFlags.bCanDrown |= 0x10; actor->staticFlags.bCanDrown |= 0x10;