TWINE: started to split keymaps for ui, game and cutscenes

This commit is contained in:
Martin Gerhardy 2020-10-23 20:09:33 +02:00 committed by Eugene Sandulenko
parent c59fd6a32e
commit d417478b8c
11 changed files with 432 additions and 249 deletions

View file

@ -409,7 +409,7 @@ int32 Debug::debugProcessButton(int32 X, int32 Y) {
void Debug::debugPlasmaWindow(const char *text, int32 color) { void Debug::debugPlasmaWindow(const char *text, int32 color) {
int32 textSize; int32 textSize;
_engine->_menu->processPlasmaEffect(5, color); _engine->_menu->processPlasmaEffect(0, 5, SCREEN_WIDTH, color);
if (!(_engine->getRandomNumber() % 5)) { if (!(_engine->getRandomNumber() % 5)) {
_engine->_menu->plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255; _engine->_menu->plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255;
} }

View file

@ -274,7 +274,13 @@ void FlaMovies::playFlaMovie(const char *flaName) {
if (!strcmp((const char *)flaHeaderData.version, "V1.3")) { if (!strcmp((const char *)flaHeaderData.version, "V1.3")) {
int32 currentFrame = 0; int32 currentFrame = 0;
ScopedKeyMap scopedKeyMap(_engine, cutsceneKeyMapId);
do { do {
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
if (currentFrame == flaHeaderData.numOfFrames) { if (currentFrame == flaHeaderData.numOfFrames) {
break; break;
} }
@ -303,17 +309,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
currentFrame++; currentFrame++;
_engine->_system->delayMillis(1000 / flaHeaderData.speed + 1); _engine->_system->delayMillis(1000 / flaHeaderData.speed + 1);
} while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
if (_engine->_input->isAnyKeyPressed()) {
break;
}
} while (true);
} }
if (_engine->cfgfile.CrossFade) { if (_engine->cfgfile.CrossFade) {

View file

@ -21,11 +21,19 @@
*/ */
#include "twine/input.h" #include "twine/input.h"
#include "backends/keymapper/keymapper.h"
#include "common/events.h"
#include "common/keyboard.h"
#include "common/system.h" #include "common/system.h"
#include "twine/actor.h"
#include "twine/twine.h" #include "twine/twine.h"
namespace TwinE { namespace TwinE {
const char *mainKeyMapId = "mainKeyMap";
const char *uiKeyMapId = "uiKeyMap";
const char *cutsceneKeyMapId = "cutsceneKeyMap";
/** Pressed key char map - scanCodeTab2 */ /** Pressed key char map - scanCodeTab2 */
static const struct KeyProperties { static const struct KeyProperties {
uint8 high; uint8 high;
@ -65,22 +73,62 @@ 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");
Input::Input(TwinEEngine *engine) : _engine(engine) {} ScopedKeyMapperDisable::ScopedKeyMapperDisable() {
g_system->getEventManager()->getKeymapper()->setEnabled(false);
bool Input::isAnyKeyPressed() const {
return internalKeyCode != 0;
} }
bool Input::isPressed(Common::KeyCode keycode) const { ScopedKeyMapperDisable::~ScopedKeyMapperDisable() {
return false; // TODO: g_system->getEventManager()->getKeymapper()->setEnabled(true);
}
ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) {
_prevKeyMap = _engine->_input->currentKeyMap();
_engine->_input->enabledKeyMap(cutsceneKeyMapId);
}
ScopedKeyMap::~ScopedKeyMap() {
_engine->_input->enabledKeyMap(_prevKeyMap.c_str());
}
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 {
if (onlyFirstTime) {
return actionStates[actionType] == 1;
}
return actionStates[actionType] > 0;
}
bool Input::toggleActionIfActive(TwinEActionType actionType) {
if (actionStates[actionType] > 0) {
actionStates[actionType] = 0;
return true;
}
return false;
}
bool Input::isQuickBehaviourActionActive() const {
return isActionActive(TwinEActionType::QuickBehaviourNormal) || isActionActive(TwinEActionType::QuickBehaviourAthletic) || isActionActive(TwinEActionType::QuickBehaviourAggressive) || isActionActive(TwinEActionType::QuickBehaviourDiscreet);
}
void Input::enabledKeyMap(const char *id) {
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
const Common::KeymapArray &keymaps = keymapper->getKeymaps();
for (Common::Keymap *keymap : keymaps) {
keymap->setEnabled(keymap->getId() == id);
}
_currentKeyMap = id;
} }
void Input::readKeys() { void Input::readKeys() {
if (_engine->shouldQuit()) { ++_tickCounter;
internalKeyCode = 1;
skippedKey = 1;
return;
}
skippedKey = 0; skippedKey = 0;
internalKeyCode = 0; internalKeyCode = 0;
@ -89,7 +137,7 @@ void Input::readKeys() {
uint8 localKey = 0; uint8 localKey = 0;
switch (event.type) { switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_END: case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
actionStates[event.customType] = false; actionStates[event.customType] = 0;
localKey = twineactions[event.customType].localKey; localKey = twineactions[event.customType].localKey;
break; break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START: case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
@ -103,29 +151,25 @@ void Input::readKeys() {
break; break;
default: default:
localKey = twineactions[event.customType].localKey; localKey = twineactions[event.customType].localKey;
actionStates[event.customType] = true; debug("repeat: %i", event.kbdRepeat);
actionStates[event.customType] = 1 + event.kbdRepeat;
break; break;
} }
} else { } else {
localKey = twineactions[event.customType].localKey; localKey = twineactions[event.customType].localKey;
actionStates[event.customType] = true; debug("repeat: %i", event.kbdRepeat);
actionStates[event.customType] = 1 + event.kbdRepeat;
} }
break; break;
case Common::EVENT_LBUTTONDOWN: case Common::EVENT_LBUTTONDOWN:
leftMouse = 1; leftMouse = 1;
break; break;
case Common::EVENT_KEYDOWN: { case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) { _pressed[event.kbd.keycode] = 1 + event.kbdRepeat;
_hitEnter = true;
}
break; break;
} case Common::EVENT_KEYUP:
case Common::EVENT_KEYUP: { _pressed[event.kbd.keycode] = 0;
if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) {
_hitEnter = false;
}
break; break;
}
case Common::EVENT_RBUTTONDOWN: case Common::EVENT_RBUTTONDOWN:
rightMouse = 1; rightMouse = 1;
break; break;

View file

@ -29,6 +29,12 @@
namespace TwinE { namespace TwinE {
class TwinEEngine;
extern const char *mainKeyMapId;
extern const char *uiKeyMapId;
extern const char *cutsceneKeyMapId;
enum TwinEActionType { enum TwinEActionType {
Pause, Pause,
NextRoom, NextRoom,
@ -61,9 +67,19 @@ enum TwinEActionType {
Escape, Escape,
PageUp, PageUp,
UIEnter,
UIAbort,
UILeft,
UIRight,
UIUp,
UIDown,
CutsceneAbort,
Max Max
}; };
// TODO: get rid of this table
static constexpr const struct ActionMapping { static constexpr const struct ActionMapping {
TwinEActionType action; TwinEActionType action;
uint8 localKey; uint8 localKey;
@ -97,8 +113,14 @@ static constexpr const struct ActionMapping {
{InventoryMenu, 0x36}, {InventoryMenu, 0x36},
{SpecialAction, 0x11}, {SpecialAction, 0x11},
{Escape, 0x01}, {Escape, 0x01},
{PageUp, 0x49} // TODO: used for what? {PageUp, 0x49}, // TODO: used for what?
}; {UIEnter, 0x00},
{UIAbort, 0x00},
{UILeft, 0x00},
{UIRight, 0x00},
{UIUp, 0x00},
{UIDown, 0x00},
{CutsceneAbort, 0x00}};
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size"); static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
@ -109,17 +131,31 @@ struct MouseStatusStruct {
int32 y = 0; int32 y = 0;
}; };
class TwinEEngine; struct ScopedKeyMapperDisable {
ScopedKeyMapperDisable();
~ScopedKeyMapperDisable();
};
class ScopedKeyMap {
private:
TwinEEngine* _engine;
Common::String _prevKeyMap;
public:
ScopedKeyMap(TwinEEngine* engine, const char *id);
~ScopedKeyMap();
};
class Input { class Input {
private: private:
TwinEEngine *_engine; TwinEEngine *_engine;
bool _hitEnter = false; int _tickCounter = 0;
uint8 _pressed[Common::KEYCODE_LAST]{0};
Common::String _currentKeyMap;
public: public:
Input(TwinEEngine *engine); Input(TwinEEngine *engine);
bool actionStates[TwinEActionType::Max]{false}; uint8 actionStates[TwinEActionType::Max]{false};
int16 skippedKey = 0; int16 skippedKey = 0;
int16 pressedKey = 0; int16 pressedKey = 0;
int16 internalKeyCode = 0; int16 internalKeyCode = 0;
@ -130,14 +166,45 @@ public:
int16 leftMouse = 0; int16 leftMouse = 0;
int16 rightMouse = 0; int16 rightMouse = 0;
bool isAnyKeyPressed() const; /**
* @brief Dependent on the context we are currently in the game, we might want to disable certain keymaps.
* Like disabling ui keymaps when we are in-game - or vice versa.
*/
void enabledKeyMap(const char *id);
bool isPressed(Common::KeyCode keycode) const; const Common::String currentKeyMap() const;
inline bool isPressedEnter() const { /**
return isPressed(Common::KEYCODE_RETURN) || isPressed(Common::KEYCODE_KP_ENTER); * @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.
*
* @sa isPressed()
*/
bool isActionActive(TwinEActionType actionType, bool onlyFirstTime = true) const;
/**
* @brief If the action is active, the internal state is reset and a following call of this method won't return
* @c true anymore
*/
bool toggleActionIfActive(TwinEActionType actionType);
/**
* @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;
/** /**
* Gets mouse positions * Gets mouse positions
* @param mouseData structure that contains mouse position info * @param mouseData structure that contains mouse position info
@ -147,6 +214,10 @@ public:
void readKeys(); void readKeys();
}; };
inline const Common::String Input::currentKeyMap() const {
return _currentKeyMap;
}
} // namespace TwinE } // namespace TwinE
#endif #endif

View file

@ -34,8 +34,8 @@
#include "twine/gamestate.h" #include "twine/gamestate.h"
#include "twine/grid.h" #include "twine/grid.h"
#include "twine/hqrdepack.h" #include "twine/hqrdepack.h"
#include "twine/interface.h"
#include "twine/input.h" #include "twine/input.h"
#include "twine/interface.h"
#include "twine/menuoptions.h" #include "twine/menuoptions.h"
#include "twine/movements.h" #include "twine/movements.h"
#include "twine/music.h" #include "twine/music.h"
@ -281,13 +281,13 @@ void Menu::plasmaEffectRenderFrame() {
*(dest++) = *(src++); *(dest++) = *(src++);
} }
void Menu::processPlasmaEffect(int32 top, int32 color) { void Menu::processPlasmaEffect(int32 left, int32 top, int32 right, int32 color) {
const int32 max_value = color + 15; const int32 max_value = color + 15;
plasmaEffectRenderFrame(); plasmaEffectRenderFrame();
const uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH; const uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top]; uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
for (int32 i = 0; i < 25; i++) { for (int32 i = 0; i < 25; i++) {
for (int32 j = 0; j < kMainMenuButtonWidth; j++) { for (int32 j = 0; j < kMainMenuButtonWidth; j++) {
@ -348,13 +348,13 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
} }
}; };
processPlasmaEffect(top, 80); processPlasmaEffect(left, top, right, 80);
if (!(_engine->getRandomNumber() % 5)) { if (!(_engine->getRandomNumber() % 5)) {
plasmaEffectPtr[_engine->getRandomNumber() % 140 * 10 + 1900] = 255; plasmaEffectPtr[_engine->getRandomNumber() % 140 * 10 + 1900] = 255;
} }
_engine->_interface->drawSplittedBox(newWidth, top, right, bottom, 68); _engine->_interface->drawSplittedBox(newWidth, top, right, bottom, 68);
} else { } else {
processPlasmaEffect(top, 64); processPlasmaEffect(left, top, right, 64);
if (!(_engine->getRandomNumber() % 5)) { if (!(_engine->getRandomNumber() % 5)) {
plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255; plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255;
} }
@ -431,21 +431,20 @@ int32 Menu::processMenu(int16 *menuSettings) {
const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons]; const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
int32 maxButton = numEntry - 1; int32 maxButton = numEntry - 1;
_engine->_input->enabledKeyMap(uiKeyMapId);
_engine->_screens->loadMenuImage(false);
do { do {
_engine->readKeys(); _engine->readKeys();
_engine->_input->key = _engine->_input->pressedKey; _engine->_input->key = _engine->_input->pressedKey;
if (_engine->_input->isPressed(Common::KeyCode::KEYCODE_DOWN)) { // on arrow key down if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
debug("pressed down");
currentButton++; currentButton++;
if (currentButton == numEntry) { // if current button is the last, than next button is the first if (currentButton == numEntry) { // if current button is the last, than next button is the first
currentButton = 0; currentButton = 0;
} }
buttonsNeedRedraw = true; buttonsNeedRedraw = true;
} } else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
if (((uint8)_engine->_input->key & 1)) { // on arrow key up
debug("pressed up");
currentButton--; currentButton--;
if (currentButton < 0) { // if current button is the first, than previous button is the last if (currentButton < 0) { // if current button is the first, than previous button is the last
currentButton = maxButton; currentButton = maxButton;
@ -461,10 +460,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
switch (id) { switch (id) {
case kMusicVolume: { case kMusicVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType); int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
if (((uint8)_engine->_input->key & 4)) { // on arrow key left if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4; volume -= 4;
} }
if (((uint8)_engine->_input->key & 8)) { // on arrow key right if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4; volume += 4;
} }
_engine->_music->musicVolume(volume); _engine->_music->musicVolume(volume);
@ -472,10 +471,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
} }
case kSoundVolume: { case kSoundVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
if (((uint8)_engine->_input->key & 4)) { // on arrow key left if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4; volume -= 4;
} }
if (((uint8)_engine->_input->key & 8)) { // on arrow key right if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4; volume += 4;
} }
mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume); mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
@ -483,10 +482,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
} }
case kCDVolume: { case kCDVolume: {
AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus(); AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
if (((uint8)_engine->_input->key & 4)) { // on arrow key left if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
status.volume -= 4; status.volume -= 4;
} }
if (((uint8)_engine->_input->key & 8)) { // on arrow key right if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
status.volume += 4; status.volume += 4;
} }
_engine->_system->getAudioCDManager()->setVolume(status.volume); _engine->_system->getAudioCDManager()->setVolume(status.volume);
@ -494,10 +493,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
} }
case kLineVolume: { case kLineVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType); int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
if (((uint8)_engine->_input->key & 4)) { // on arrow key left if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4; volume -= 4;
} }
if (((uint8)_engine->_input->key & 8)) { // on arrow key right if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4; volume += 4;
} }
mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume); mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
@ -505,10 +504,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
} }
case kMasterVolume: { case kMasterVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType); int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
if (((uint8)_engine->_input->key & 4)) { // on arrow key left if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4; volume -= 4;
} }
if (((uint8)_engine->_input->key & 8)) { // on arrow key right if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4; volume += 4;
} }
mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume); mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
@ -532,7 +531,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (musicChanged) { if (musicChanged) {
// TODO: update volume settings // TODO: update volume settings
} }
} while (!(_engine->_input->skippedKey & 2) && !(_engine->_input->skippedKey & 1)); } while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
@ -872,20 +871,18 @@ void Menu::processBehaviourMenu() {
_engine->_animations->setAnimAtKeyframe(behaviourAnimState[_engine->_actor->heroBehaviour], _engine->_animations->animTable[_engine->_actor->heroAnimIdx[_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[_engine->_actor->heroBehaviour]); _engine->_animations->setAnimAtKeyframe(behaviourAnimState[_engine->_actor->heroBehaviour], _engine->_animations->animTable[_engine->_actor->heroAnimIdx[_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[_engine->_actor->heroBehaviour]);
_engine->readKeys();
int32 tmpTime = _engine->lbaTime; int32 tmpTime = _engine->lbaTime;
while (_engine->_input->skippedKey & 4 || (_engine->_input->internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_input->internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) { while (_engine->_input->isActionActive(TwinEActionType::BehaviourMenu) || _engine->_input->isQuickBehaviourActionActive()) {
_engine->readKeys(); _engine->readKeys();
_engine->_input->key = _engine->_input->pressedKey; _engine->_input->key = _engine->_input->pressedKey;
int heroBehaviour = (int)_engine->_actor->heroBehaviour; int heroBehaviour = (int)_engine->_actor->heroBehaviour;
if (_engine->_input->key & 8) { if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
heroBehaviour++; heroBehaviour++;
} }
if (_engine->_input->key & 4) { if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
heroBehaviour--; heroBehaviour--;
} }
@ -965,14 +962,12 @@ void Menu::drawItem(int32 item) {
} }
void Menu::drawInventoryItems() { void Menu::drawInventoryItems() {
int32 item;
_engine->_interface->drawTransparentBox(17, 10, 622, 320, 4); _engine->_interface->drawTransparentBox(17, 10, 622, 320, 4);
drawBox(17, 10, 622, 320); drawBox(17, 10, 622, 320);
drawMagicItemsBox(110, 18, 188, 311, 75); drawMagicItemsBox(110, 18, 188, 311, 75);
_engine->copyBlockPhys(17, 10, 622, 320); _engine->copyBlockPhys(17, 10, 622, 320);
for (item = 0; item < NUM_INVENTORY_ITEMS; item++) { for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
drawItem(item); drawItem(item);
} }
} }
@ -1002,7 +997,7 @@ void Menu::processInventoryMenu() {
_engine->_text->setFontCrossColor(4); _engine->_text->setFontCrossColor(4);
_engine->_text->initDialogueBox(); _engine->_text->initDialogueBox();
while (_engine->_input->internalKeyCode != 1) { while (_engine->_input->isActionActive(TwinEActionType::InventoryMenu)) {
_engine->readKeys(); _engine->readKeys();
int32 prevSelectedItem = inventorySelectedItem; int32 prevSelectedItem = inventorySelectedItem;
@ -1026,7 +1021,7 @@ void Menu::processInventoryMenu() {
if (_engine->loopCurrentKey == 1 || _engine->loopPressedKey & 0x20) if (_engine->loopCurrentKey == 1 || _engine->loopPressedKey & 0x20)
break; break;
if (_engine->_input->key & 2) { // down if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
inventorySelectedItem++; inventorySelectedItem++;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) { if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem = 0; inventorySelectedItem = 0;
@ -1035,7 +1030,7 @@ void Menu::processInventoryMenu() {
bx = 3; bx = 3;
} }
if (_engine->_input->key & 1) { // up if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
inventorySelectedItem--; inventorySelectedItem--;
if (inventorySelectedItem < 0) { if (inventorySelectedItem < 0) {
inventorySelectedItem = NUM_INVENTORY_ITEMS - 1; inventorySelectedItem = NUM_INVENTORY_ITEMS - 1;
@ -1044,7 +1039,7 @@ void Menu::processInventoryMenu() {
bx = 3; bx = 3;
} }
if (_engine->_input->key & 4) { // left if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
inventorySelectedItem -= 4; inventorySelectedItem -= 4;
if (inventorySelectedItem < 0) { if (inventorySelectedItem < 0) {
inventorySelectedItem += NUM_INVENTORY_ITEMS; inventorySelectedItem += NUM_INVENTORY_ITEMS;
@ -1053,7 +1048,7 @@ void Menu::processInventoryMenu() {
bx = 3; bx = 3;
} }
if (_engine->_input->key & 8) { // right if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
inventorySelectedItem += 4; inventorySelectedItem += 4;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) { if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem -= NUM_INVENTORY_ITEMS; inventorySelectedItem -= NUM_INVENTORY_ITEMS;

View file

@ -115,7 +115,7 @@ public:
* @param top top height where the effect will be draw in the front buffer * @param top top height where the effect will be draw in the front buffer
* @param color plasma effect start color * @param color plasma effect start color
*/ */
void processPlasmaEffect(int32 top, int32 color); void processPlasmaEffect(int32 left, int32 top, int32 right, int32 color);
/** /**
* Draw the entire button box * Draw the entire button box

View file

@ -21,11 +21,11 @@
*/ */
#include "twine/menuoptions.h" #include "twine/menuoptions.h"
#include "common/keyboard.h" #include "common/system.h"
#include "twine/flamovies.h" #include "twine/flamovies.h"
#include "twine/gamestate.h" #include "twine/gamestate.h"
#include "twine/interface.h"
#include "twine/input.h" #include "twine/input.h"
#include "twine/interface.h"
#include "twine/menu.h" #include "twine/menu.h"
#include "twine/music.h" #include "twine/music.h"
#include "twine/resources.h" #include "twine/resources.h"
@ -138,7 +138,7 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
if (arg != 0) { if (arg != 0) {
_engine->_interface->drawSplittedBox(left, top, right, bottom, 91); _engine->_interface->drawSplittedBox(left, top, right, bottom, 91);
} else { } else {
_engine->_interface->blitBox(left, top, right, bottom, (const int8*)_engine->workVideoBuffer.getPixels(), left, top, (int8*)_engine->frontVideoBuffer.getPixels()); _engine->_interface->blitBox(left, top, right, bottom, (const int8 *)_engine->workVideoBuffer.getPixels(), left, top, (int8 *)_engine->frontVideoBuffer.getPixels());
right2 = right; right2 = right;
_engine->_interface->drawTransparentBox(left, top, right2, bottom, 4); _engine->_interface->drawTransparentBox(left, top, right2, bottom, 4);
} }
@ -162,19 +162,20 @@ void MenuOptions::drawSelectableCharacters() {
// 0001F18C // 0001F18C
void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) { void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
if (type == 1) {
_engine->_menu->processPlasmaEffect(top, 1);
}
const int left = _engine->_text->dialTextBoxLeft; const int left = _engine->_text->dialTextBoxLeft;
const int right = _engine->_text->dialTextBoxRight; const int right = _engine->_text->dialTextBoxRight;
if (type == 1) {
_engine->_menu->processPlasmaEffect(left, top, right, 1);
}
const int bottom = _engine->_text->dialTextBoxBottom; const int bottom = _engine->_text->dialTextBoxBottom;
_engine->_menu->drawBox(left, top, right, bottom); _engine->_menu->drawBox(left, top, right, bottom);
_engine->_interface->drawTransparentBox(left + 1, top + 1, right - 1, bottom - 1, 3); _engine->_interface->drawTransparentBox(left + 1, top + 1, right - 1, bottom - 1, 3);
_engine->_text->drawText(centerx - _engine->_text->getTextSize(playerName) / 2, top, playerName); _engine->_text->drawText(centerx - _engine->_text->getTextSize(playerName) / 2, top, playerName);
_engine->copyBlockPhys(left, top, right, bottom); _engine->flip();
// TODO: _engine->copyBlockPhys(left, top, right, bottom);
} }
int32 MenuOptions::enterPlayerName(int32 textIdx) { int32 MenuOptions::enterPlayerName(int32 textIdx) {
@ -191,18 +192,35 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99); _engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
drawPlayerName(halfScreenWidth, 100, 1); drawPlayerName(halfScreenWidth, 100, 1);
drawSelectableCharacters(); drawSelectableCharacters();
_engine->flip();
do { // we don't want custom events here - as we are entering the player name
_engine->readKeys(); ScopedKeyMapperDisable scopedKeyMapperDisable;
for (;;) {
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
if (event.type == Common::EVENT_KEYDOWN) {
if (event.kbd.keycode == Common::KEYCODE_KP_ENTER || event.kbd.keycode == Common::KEYCODE_RETURN) {
return 1;
}
const size_t size = strlen(playerName);
if (size >= sizeof(playerName) - 1) {
return 1;
}
playerName[size] = event.kbd.ascii;
playerName[size + 1] = '\0';
debug("name: %s", playerName);
drawPlayerName(halfScreenWidth, 100, 1);
_engine->flip();
}
}
if (_engine->shouldQuit()) { if (_engine->shouldQuit()) {
break; break;
} }
} while (_engine->_input->isPressedEnter()); _engine->_system->delayMillis(1);
};
} }
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
return 1; return 1;
} }

View file

@ -44,7 +44,7 @@ public:
int32 canShowCredits = 0; int32 canShowCredits = 0;
char playerName[256] = ""; char playerName[32] = "";
/** Main menu new game options */ /** Main menu new game options */
void newGameMenu(); void newGameMenu();

View file

@ -56,177 +56,231 @@ public:
Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const { Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
using namespace Common; using namespace Common;
Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "twine", "Little Big Adventure");
Action *act; Action *act;
KeymapArray array(3);
{
Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, mainKeyMapId, "Little Big Adventure");
act = new Action("PAUSE", _("Pause")); act = new Action("PAUSE", _("Pause"));
act->setCustomEngineActionEvent(TwinEActionType::Pause); act->setCustomEngineActionEvent(TwinEActionType::Pause);
act->addDefaultInputMapping("p"); act->addDefaultInputMapping("p");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("NEXTROOM", _("Debug Next Room")); act = new Action("NEXTROOM", _("Debug Next Room"));
act->setCustomEngineActionEvent(TwinEActionType::NextRoom); act->setCustomEngineActionEvent(TwinEActionType::NextRoom);
act->addDefaultInputMapping("r"); act->addDefaultInputMapping("r");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("PREVIOUSROOM", _("Debug Previous Room")); act = new Action("PREVIOUSROOM", _("Debug Previous Room"));
act->setCustomEngineActionEvent(TwinEActionType::PreviousRoom); act->setCustomEngineActionEvent(TwinEActionType::PreviousRoom);
act->addDefaultInputMapping("f"); act->addDefaultInputMapping("f");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("APPLYCELLINGGRID", _("Debug Apply Celling Grid")); act = new Action("APPLYCELLINGGRID", _("Debug Apply Celling Grid"));
act->setCustomEngineActionEvent(TwinEActionType::ApplyCellingGrid); act->setCustomEngineActionEvent(TwinEActionType::ApplyCellingGrid);
act->addDefaultInputMapping("t"); act->addDefaultInputMapping("t");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("INCREASECELLINGGRIDINDEX", _("Debug Increase Celling Grid Index")); act = new Action("INCREASECELLINGGRIDINDEX", _("Debug Increase Celling Grid Index"));
act->setCustomEngineActionEvent(TwinEActionType::IncreaseCellingGridIndex); act->setCustomEngineActionEvent(TwinEActionType::IncreaseCellingGridIndex);
act->addDefaultInputMapping("g"); act->addDefaultInputMapping("g");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DECREASECELLINGGRIDINDEX", _("Debug Decrease Celling Grid Index")); act = new Action("DECREASECELLINGGRIDINDEX", _("Debug Decrease Celling Grid Index"));
act->setCustomEngineActionEvent(TwinEActionType::DecreaseCellingGridIndex); act->setCustomEngineActionEvent(TwinEActionType::DecreaseCellingGridIndex);
act->addDefaultInputMapping("b"); act->addDefaultInputMapping("b");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up")); act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp); act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp);
act->addDefaultInputMapping("s"); act->addDefaultInputMapping("s");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down")); act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown); act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown);
act->addDefaultInputMapping("x"); act->addDefaultInputMapping("x");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left")); act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft); act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft);
act->addDefaultInputMapping("y"); act->addDefaultInputMapping("y");
act->addDefaultInputMapping("z"); act->addDefaultInputMapping("z");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right")); act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight); act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight);
act->addDefaultInputMapping("c"); act->addDefaultInputMapping("c");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour")); act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour"));
act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourNormal); act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourNormal);
act->addDefaultInputMapping("F1"); act->addDefaultInputMapping("F1");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("ATHLETICBEHAVIOUR", _("Athletic Behaviour")); act = new Action("ATHLETICBEHAVIOUR", _("Athletic Behaviour"));
act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAthletic); act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAthletic);
act->addDefaultInputMapping("F2"); act->addDefaultInputMapping("F2");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("AGGRESSIVEBEHAVIOUR", _("Aggressive Behaviour")); act = new Action("AGGRESSIVEBEHAVIOUR", _("Aggressive Behaviour"));
act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAggressive); act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAggressive);
act->addDefaultInputMapping("F3"); act->addDefaultInputMapping("F3");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("DISCREETBEHAVIOUR", _("Discreet Behaviour")); act = new Action("DISCREETBEHAVIOUR", _("Discreet Behaviour"));
act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourDiscreet); act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourDiscreet);
act->addDefaultInputMapping("F4"); act->addDefaultInputMapping("F4");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("BEHAVIOURACTION", _("Behaviour Action")); act = new Action("BEHAVIOURACTION", _("Behaviour Action"));
act->setCustomEngineActionEvent(TwinEActionType::ExecuteBehaviourAction); act->setCustomEngineActionEvent(TwinEActionType::ExecuteBehaviourAction);
act->addDefaultInputMapping("SPACE"); act->addDefaultInputMapping("SPACE");
act->addDefaultInputMapping("JOY_A"); act->addDefaultInputMapping("JOY_A");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("CHANGEBEHAVIOUR", _("Change Behaviour")); act = new Action("CHANGEBEHAVIOUR", _("Change Behaviour"));
act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu); act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu);
act->addDefaultInputMapping("CTRL"); act->addDefaultInputMapping("CTRL");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("OPTIONSMENU", _("Options Menu")); act = new Action("OPTIONSMENU", _("Options Menu"));
act->setCustomEngineActionEvent(TwinEActionType::OptionsMenu); act->setCustomEngineActionEvent(TwinEActionType::OptionsMenu);
act->addDefaultInputMapping("F6"); act->addDefaultInputMapping("F6");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("CENTER", _("Center")); act = new Action("CENTER", _("Center"));
act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen); act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen);
act->addDefaultInputMapping("RETURN"); act->addDefaultInputMapping("RETURN");
act->addDefaultInputMapping("KP_ENTER"); act->addDefaultInputMapping("KP_ENTER");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("USESELECTEDOBJECT", _("Use Selected Object")); act = new Action("USESELECTEDOBJECT", _("Use Selected Object"));
act->setCustomEngineActionEvent(TwinEActionType::UseSelectedObject); act->setCustomEngineActionEvent(TwinEActionType::UseSelectedObject);
act->addDefaultInputMapping("SHIFT+RETURN"); act->addDefaultInputMapping("SHIFT+RETURN");
act->addDefaultInputMapping("SHIFT+KP_ENTER"); act->addDefaultInputMapping("SHIFT+KP_ENTER");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("THROWMAGICBALL", _("Throw Magic Ball")); act = new Action("THROWMAGICBALL", _("Throw Magic Ball"));
act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall); act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall);
act->addDefaultInputMapping("ALT"); act->addDefaultInputMapping("ALT");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("MOVEFORWARD", _("Move Forward")); act = new Action("MOVEFORWARD", _("Move Forward"));
act->setCustomEngineActionEvent(TwinEActionType::MoveForward); act->setCustomEngineActionEvent(TwinEActionType::MoveForward);
act->addDefaultInputMapping("UP"); act->addDefaultInputMapping("UP");
act->addDefaultInputMapping("KP8"); act->addDefaultInputMapping("KP8");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("MOVEBACKWARD", _("Move Backward")); act = new Action("MOVEBACKWARD", _("Move Backward"));
act->setCustomEngineActionEvent(TwinEActionType::MoveBackward); act->setCustomEngineActionEvent(TwinEActionType::MoveBackward);
act->addDefaultInputMapping("DOWN"); act->addDefaultInputMapping("DOWN");
act->addDefaultInputMapping("KP2"); act->addDefaultInputMapping("KP2");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("TurnRight", _("Turn Right")); act = new Action("TURNRIGHT", _("Turn Right"));
act->setCustomEngineActionEvent(TwinEActionType::TurnRight); act->setCustomEngineActionEvent(TwinEActionType::TurnRight);
act->addDefaultInputMapping("RIGHT"); act->addDefaultInputMapping("RIGHT");
act->addDefaultInputMapping("KP6"); act->addDefaultInputMapping("KP6");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("TurnLeft", _("Turn Left")); act = new Action("TURNLEFT", _("Turn Left"));
act->setCustomEngineActionEvent(TwinEActionType::TurnLeft); act->setCustomEngineActionEvent(TwinEActionType::TurnLeft);
act->addDefaultInputMapping("LEFT"); act->addDefaultInputMapping("LEFT");
act->addDefaultInputMapping("KP4"); act->addDefaultInputMapping("KP4");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("USEPROTOPACK", _("Use Protopack")); act = new Action("USEPROTOPACK", _("Use Protopack"));
act->setCustomEngineActionEvent(TwinEActionType::UseProtoPack); act->setCustomEngineActionEvent(TwinEActionType::UseProtoPack);
act->addDefaultInputMapping("j"); act->addDefaultInputMapping("j");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("OPENHOLOMAP", _("Open Holomap")); act = new Action("OPENHOLOMAP", _("Open Holomap"));
act->setCustomEngineActionEvent(TwinEActionType::OpenHolomap); act->setCustomEngineActionEvent(TwinEActionType::OpenHolomap);
act->addDefaultInputMapping("h"); act->addDefaultInputMapping("h");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("INVENTORY", _("Inventory")); act = new Action("INVENTORY", _("Inventory"));
act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu); act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu);
act->addDefaultInputMapping("LSHIFT"); act->addDefaultInputMapping("LSHIFT");
act->addDefaultInputMapping("RSHIFT"); act->addDefaultInputMapping("RSHIFT");
act->addDefaultInputMapping("i"); act->addDefaultInputMapping("i");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("SPECIALACTION", _("Special Action")); act = new Action("SPECIALACTION", _("Special Action"));
act->setCustomEngineActionEvent(TwinEActionType::SpecialAction); act->setCustomEngineActionEvent(TwinEActionType::SpecialAction);
act->addDefaultInputMapping("w"); act->addDefaultInputMapping("w");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("ESCAPE", _("Escape")); act = new Action("ESCAPE", _("Escape"));
act->setCustomEngineActionEvent(TwinEActionType::Escape); act->setCustomEngineActionEvent(TwinEActionType::Escape);
act->addDefaultInputMapping("ESCAPE"); act->addDefaultInputMapping("ESCAPE");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
act = new Action("PAGEUP", _("Page Up")); act = new Action("PAGEUP", _("Page Up"));
act->setCustomEngineActionEvent(TwinEActionType::PageUp); act->setCustomEngineActionEvent(TwinEActionType::PageUp);
act->addDefaultInputMapping("PAGEUP"); act->addDefaultInputMapping("PAGEUP");
engineKeyMap->addAction(act); gameKeyMap->addAction(act);
const int delta = (int)TwinEActionType::Max - (int)engineKeyMap->getActions().size(); array[0] = gameKeyMap;
if (delta != 0) {
error("Registered key map actions differs from TwinEActionType by %i", delta);
} }
return Keymap::arrayOf(engineKeyMap); {
Keymap *uiKeyMap = new Keymap(Keymap::kKeymapTypeGame, uiKeyMapId, "Little Big Adventure UI");
act = new Action("ACCEPT", _("Accept"));
act->setCustomEngineActionEvent(TwinEActionType::UIEnter);
act->addDefaultInputMapping("RETURN");
act->addDefaultInputMapping("KP_ENTER");
uiKeyMap->addAction(act);
act = new Action("ABORT", _("Abort"));
act->setCustomEngineActionEvent(TwinEActionType::UIAbort);
act->addDefaultInputMapping("ESCAPE");
uiKeyMap->addAction(act);
act = new Action("UP", _("Up"));
act->setCustomEngineActionEvent(TwinEActionType::UIUp);
act->addDefaultInputMapping("UP");
act->addDefaultInputMapping("KP8");
uiKeyMap->addAction(act);
act = new Action("DOWN", _("Down"));
act->setCustomEngineActionEvent(TwinEActionType::UIDown);
act->addDefaultInputMapping("DOWN");
act->addDefaultInputMapping("KP2");
uiKeyMap->addAction(act);
act = new Action("RIGHT", _("Right"));
act->setCustomEngineActionEvent(TwinEActionType::UIRight);
act->addDefaultInputMapping("RIGHT");
act->addDefaultInputMapping("KP6");
uiKeyMap->addAction(act);
act = new Action("LEFT", _("Left"));
act->setCustomEngineActionEvent(TwinEActionType::UILeft);
act->addDefaultInputMapping("LEFT");
act->addDefaultInputMapping("KP4");
uiKeyMap->addAction(act);
array[1] = uiKeyMap;
}
{
Keymap *cutsceneKeyMap = new Keymap(Keymap::kKeymapTypeGame, cutsceneKeyMapId, "Little Big Adventure Cutscenes");
act = new Action("ABORT", _("Abort"));
act->setCustomEngineActionEvent(TwinEActionType::CutsceneAbort);
act->addDefaultInputMapping("RETURN");
act->addDefaultInputMapping("KP_ENTER");
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("SPACE");
cutsceneKeyMap->addAction(act);
array[2] = cutsceneKeyMap;
}
return array;
} }
} // namespace TwinE } // namespace TwinE

View file

@ -198,6 +198,7 @@ void Redraw::updateOverlayTypePosition(int16 X1, int16 Y1, int16 X2, int16 Y2) {
} }
} }
// TODO: convert to bool and check if this isn't always true...
void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
int16 tmp_projPosX; int16 tmp_projPosX;
int16 tmp_projPosY; int16 tmp_projPosY;

View file

@ -29,6 +29,7 @@
#include "common/str.h" #include "common/str.h"
#include "common/system.h" #include "common/system.h"
#include "common/textconsole.h" #include "common/textconsole.h"
#include "common/translation.h"
#include "engines/util.h" #include "engines/util.h"
#include "graphics/managed_surface.h" #include "graphics/managed_surface.h"
#include "graphics/palette.h" #include "graphics/palette.h"
@ -47,8 +48,8 @@
#include "twine/grid.h" #include "twine/grid.h"
#include "twine/holomap.h" #include "twine/holomap.h"
#include "twine/hqrdepack.h" #include "twine/hqrdepack.h"
#include "twine/interface.h"
#include "twine/input.h" #include "twine/input.h"
#include "twine/interface.h"
#include "twine/menu.h" #include "twine/menu.h"
#include "twine/menuoptions.h" #include "twine/menuoptions.h"
#include "twine/movements.h" #include "twine/movements.h"
@ -323,6 +324,8 @@ void TwinEEngine::processActorSamplePosition(int32 actorIdx) {
} }
int32 TwinEEngine::runGameEngine() { // mainLoopInteration int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_input->enabledKeyMap(mainKeyMapId);
readKeys(); readKeys();
if (_scene->needChangeScene > -1) { if (_scene->needChangeScene > -1) {
@ -364,7 +367,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->redrawEngineActions(1); _redraw->redrawEngineActions(1);
} }
if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) { if (_input->toggleActionIfActive(TwinEActionType::OptionsMenu)) {
freezeTime(); freezeTime();
_sound->pauseSamples(); _sound->pauseSamples();
_menu->OptionsMenuState[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame _menu->OptionsMenuState[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame
@ -379,7 +382,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
// inventory menu // inventory menu
loopInventoryItem = -1; loopInventoryItem = -1;
if (loopCurrentKey == twineactions[TwinEActionType::InventoryMenu].localKey && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) { if (_input->isActionActive(TwinEActionType::InventoryMenu) && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
freezeTime(); freezeTime();
_menu->processInventoryMenu(); _menu->processInventoryMenu();
@ -488,19 +491,19 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
} }
// Process behaviour menu // Process behaviour menu
if ((loopCurrentKey == twineactions[TwinEActionType::BehaviourMenu].localKey || if ((_input->isActionActive(TwinEActionType::BehaviourMenu, false) ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey || _input->isActionActive(TwinEActionType::QuickBehaviourNormal, false) ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey || _input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false) ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey || _input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false) ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) && _input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) &&
_scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) { _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey) { if (_input->isActionActive(TwinEActionType::QuickBehaviourNormal, false)) {
_actor->heroBehaviour = HeroBehaviourType::kNormal; _actor->heroBehaviour = HeroBehaviourType::kNormal;
} else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey) { } else if (_input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false)) {
_actor->heroBehaviour = HeroBehaviourType::kAthletic; _actor->heroBehaviour = HeroBehaviourType::kAthletic;
} else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey) { } else if (_input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false)) {
_actor->heroBehaviour = HeroBehaviourType::kAggressive; _actor->heroBehaviour = HeroBehaviourType::kAggressive;
} else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) { } else if (_input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) {
_actor->heroBehaviour = HeroBehaviourType::kDiscrete; _actor->heroBehaviour = HeroBehaviourType::kDiscrete;
} }
freezeTime(); freezeTime();
@ -510,7 +513,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
} }
// use Proto-Pack // use Proto-Pack
if (loopCurrentKey == twineactions[TwinEActionType::UseProtoPack].localKey && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) { if (_input->isActionActive(TwinEActionType::UseProtoPack, false) && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) {
if (_gameState->gameFlags[InventoryItems::kiBookOfBu]) { if (_gameState->gameFlags[InventoryItems::kiBookOfBu]) {
_scene->sceneHero->body = 0; _scene->sceneHero->body = 0;
} else { } else {
@ -543,7 +546,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
} }
// Process Pause // Process Pause
if (loopCurrentKey == twineactions[TwinEActionType::Pause].localKey) { if (_input->toggleActionIfActive(TwinEActionType::Pause)) {
freezeTime(); freezeTime();
_text->setFontColor(15); _text->setFontColor(15);
_text->drawText(5, 446, "Pause"); // no key for pause in Text Bank _text->drawText(5, 446, "Pause"); // no key for pause in Text Bank
@ -554,7 +557,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
break; break;
} }
g_system->delayMillis(10); g_system->delayMillis(10);
} while (_input->internalKeyCode != 0x19 && !_input->pressedKey); } while (!_input->toggleActionIfActive(TwinEActionType::Pause));
unfreezeTime(); unfreezeTime();
_redraw->redrawEngineActions(1); _redraw->redrawEngineActions(1);
} }
@ -760,6 +763,7 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
_screens->lockPalette = true; _screens->lockPalette = true;
_movements->setActorAngle(0, -256, 5, &loopMovePtr); _movements->setActorAngle(0, -256, 5, &loopMovePtr);
while (quitGame == -1) { while (quitGame == -1) {
start = g_system->getMillis(); start = g_system->getMillis();