ULTIMA: NUVIE: Fix alt-code cheats

Alt-codes were no longer working with the default keymap
since commit 12a47d956e
"Add support for ScummVM keymapper"

Codes were handled via hardcoded EVENT_KEYDOWN events, which are now
eaten by the keymapper (at least when using default keybinds).

Remove current alt-code handling and use the keymapper instead.
The code is now evaluated when the alt-code-mode key is released to
match original behavior.

Also always store alt-code as an int to avoid unnecessary
string conversion.
This commit is contained in:
PushmePullyu 2023-12-18 06:20:15 +01:00 committed by Matthew Duggan
parent 8bb3679bd3
commit 045543e10c
7 changed files with 79 additions and 86 deletions

View File

@ -238,74 +238,6 @@ bool Events::handleSDL_KEYDOWN(const Common::Event *event_) {
return true;
}
byte mods = event_->kbd.flags;
// alt-code input
if (mods & Common::KBD_ALT) {
if (mode == MOVE_MODE)
switch (event_->kbd.keycode) {
case Common::KEYCODE_KP0:
case Common::KEYCODE_0:
alt_code_str[alt_code_len++] = '0';
break;
case Common::KEYCODE_KP1:
case Common::KEYCODE_1:
alt_code_str[alt_code_len++] = '1';
break;
case Common::KEYCODE_KP2:
case Common::KEYCODE_2:
alt_code_str[alt_code_len++] = '2';
break;
case Common::KEYCODE_KP3:
case Common::KEYCODE_3:
alt_code_str[alt_code_len++] = '3';
break;
case Common::KEYCODE_KP4:
case Common::KEYCODE_4:
alt_code_str[alt_code_len++] = '4';
break;
case Common::KEYCODE_KP5:
case Common::KEYCODE_5:
alt_code_str[alt_code_len++] = '5';
break;
case Common::KEYCODE_KP6:
case Common::KEYCODE_6:
alt_code_str[alt_code_len++] = '6';
break;
case Common::KEYCODE_KP7:
case Common::KEYCODE_7:
alt_code_str[alt_code_len++] = '7';
break;
case Common::KEYCODE_KP8:
case Common::KEYCODE_8:
alt_code_str[alt_code_len++] = '8';
break;
case Common::KEYCODE_KP9:
case Common::KEYCODE_9:
alt_code_str[alt_code_len++] = '9';
break;
default:
keybinder->HandleEvent(event_);
return true;
}
if (alt_code_len != 0) {
alt_code_str[alt_code_len] = '\0';
if (alt_code_len == 3) {
alt_code(alt_code_str);
clear_alt_code();
}
}
return true;
}
keybinder->HandleEvent(event_);
return true;
@ -347,9 +279,6 @@ bool Events::handleEvent(const Common::Event *event_) {
case Common::EVENT_MOUSEMOVE:
break;
case Common::EVENT_KEYUP:
if (event_->kbd.flags & Common::KBD_ALT) {
clear_alt_code();
}
break;
case Common::EVENT_KEYDOWN:
@ -360,10 +289,10 @@ bool Events::handleEvent(const Common::Event *event_) {
return false;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
keybinder->handleScummVMBoundEvent(event_);
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
default:
break;
}
@ -1669,10 +1598,9 @@ void Events::alt_code_input(const char *in) {
}
}
/* Get an alt-code from `cs' and use it.
/* Use alt-code in `c'.
*/
void Events::alt_code(const char *cs) {
uint16 c = (uint16) strtol(cs, nullptr, 10);
void Events::alt_code(int c) {
switch (c) {
case 300: // display portrait by number
scroll->display_string("Portrait? ");
@ -3828,6 +3756,18 @@ bool Events::input_really_needs_directon() const {
return false;
}
void Events::toggleAltCodeMode(bool enable) {
if (!enable && altCodeVal != 0)
alt_code(altCodeVal); // leaving alt-code mode: evaluate it
// a code was either just handled or we newly entered alt-code mode: reset it
clear_alt_code();
}
void Events::appendAltCode(int code) {
altCodeVal *= 10;
altCodeVal += code;
}
bool shouldQuit() {
return g_engine->shouldQuit();
}

View File

@ -204,8 +204,7 @@ private:
EventInput input; // collected/received input (of any type)
// Std::vector<EventMode> mode_stack; // current mode is at the end of the list
int ts; //timestamp for TimeLeft() method.
char alt_code_str[4]; // string representation of alt-code input
uint8 alt_code_len; // how many characters have been input for alt-code
int altCodeVal;
uint16 active_alt_code; // alt-code that needs more input
uint8 alt_code_input_num; // alt-code can get multiple inputs
@ -401,12 +400,13 @@ public:
void walk_to_mouse_cursor(uint32 mx, uint32 my);
void multiuse(uint16 wx, uint16 wy);
void alt_code(const char *cs);
void alt_code(int c);
void alt_code_input(const char *in);
void clear_alt_code() {
alt_code_str[0] = '\0';
alt_code_len = 0;
}
void clear_alt_code() { altCodeVal = 0; }
void toggleAltCodeMode(bool enable);
void appendAltCode(int code);
bool alt_code_teleport(const char *location_string);
void alt_code_infostring();
void alt_code_teleport_menu(uint32 selection);

View File

@ -449,6 +449,17 @@ void ActionCloseGumps(int param) {
EVENT->close_gumps();
}
void ActionToggleAltCodeMode (int param) {
if (EVENT->get_mode() == MOVE_MODE) {
EVENT->toggleAltCodeMode(param == kAltCodeModeBegin ? true : false);
}
}
void ActionAppendAltCode(int param) {
if (EVENT->get_mode() == MOVE_MODE)
EVENT->appendAltCode(param);
}
void ActionUseItem(int param) {
if (EVENT->get_mode() != MOVE_MODE && EVENT->get_mode() != EQUIP_MODE)
return;

View File

@ -87,6 +87,8 @@ void ActionShowKeys(int param);
void ActionDecreaseDebug(int param);
void ActionIncreaseDebug(int param);
void ActionCloseGumps(int param);
void ActionToggleAltCodeMode(int param);
void ActionAppendAltCode(int param);
void ActionUseItem(int param);
void ActionAssetViewer(int param);

View File

@ -64,6 +64,10 @@ struct Action {
ActionKeyType keyType;
};
const char *appendAltCodeActionStr = "ALT_CODE";
const char *toggleAltCodeModeActionStr = "TOGGLE_ALT_CODE_MODE";
const uint toggleAltCodeModeEventID = Common::hashit(toggleAltCodeModeActionStr); // to identify END (KEYUP) events for alt-code mode toggle action
const Action NuvieActions[] = {
{ "WALK_WEST", ActionWalkWest, Action::KeyNormal, true, WEST_KEY },
{ "WALK_EAST", ActionWalkEast, Action::KeyNormal, true, EAST_KEY },
@ -134,6 +138,8 @@ const Action NuvieActions[] = {
{ "HEAL_PARTY", ActionHealParty, Action::KeyCheat, true, OTHER_KEY },
{ "TELEPORT_TO_CURSOR", ActionTeleportToCursor, Action::KeyCheat, true, OTHER_KEY },
{ "TOGGLE_CHEATS", ActionToggleCheats, Action::KeyNormal, true, OTHER_KEY },
{ toggleAltCodeModeActionStr, ActionToggleAltCodeMode, Action::KeyNormal, true, OTHER_KEY },
{ appendAltCodeActionStr, ActionAppendAltCode, Action::KeyNormal, true, OTHER_KEY },
{ "DO_NOTHING", ActionDoNothing, Action::KeyNotShown, true, OTHER_KEY },
};
@ -402,10 +408,17 @@ bool KeyBinder::HandleEvent(const Common::Event *ev) {
}
bool KeyBinder::handleScummVMBoundEvent(const Common::Event *ev) {
ParseHashedActionMap::iterator iter = _actionsHashed.find(ev->customType);
if (iter != _actionsHashed.end()) {
const ActionType action = iter->_value;
return DoAction(action);
if (ev->type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
ParseHashedActionMap::iterator iter = _actionsHashed.find(ev->customType);
if (iter != _actionsHashed.end()) {
const ActionType action = iter->_value;
return DoAction(action);
}
} else if (ev->type == Common::EVENT_CUSTOM_ENGINE_ACTION_END && ev->customType == toggleAltCodeModeEventID) {
// Evaluate and reset alt code when corresponding key is released
ActionToggleAltCodeMode(kAltCodeModeEnd);
return true;
}
return false;
}
@ -692,6 +705,17 @@ void KeyBinder::FillParseMaps() {
_actionsHashed[actionId.hash()] = at;
}
}
if (!_actions.contains(appendAltCodeActionStr))
error("No base definition for alt-code action %s", appendAltCodeActionStr);
for (int i = 0; i <= 9; ++i) {
Common::String actionId = Common::String::format("%s_%d", appendAltCodeActionStr, i);
const Action *action = _actions[appendAltCodeActionStr];
ActionType at;
at.action = action;
at.param = i;
_actionsHashed[actionId.hash()] = at;
}
}
uint8 KeyBinder::get_axis(uint8 index) const {

View File

@ -36,6 +36,11 @@ enum joy_axes_pairs {
AXES_PAIR1, AXES_PAIR2, AXES_PAIR3, AXES_PAIR4, UNHANDLED_AXES_PAIR
};
enum altCodeMode {
kAltCodeModeBegin = 0,
kAltCodeModeEnd = 1
};
struct Action;
struct ActionType {
const Action *action;

View File

@ -107,6 +107,17 @@ static const NuvieActionDescription NuvieActionDescriptions[] = {
{ "INCREASE_DEBUG", "Increase debug", "C+i", nullptr },
{ "CLOSE_GUMPS", "Close gumps", "z", nullptr },
//{ "USE_ITEM", "Use item", nullptr, nullptr }, // TODO: this takes an item no parameter
{ "TOGGLE_ALT_CODE_MODE", "Enter ALT code (hold)", "LALT", nullptr },
{ "ALT_CODE_0", "ALT Code 0", "A+KP0", "A+0" },
{ "ALT_CODE_1", "ALT Code 1", "A+KP1", "A+1" },
{ "ALT_CODE_2", "ALT Code 2", "A+KP2", "A+2" },
{ "ALT_CODE_3", "ALT Code 3", "A+KP3", "A+3" },
{ "ALT_CODE_4", "ALT Code 4", "A+KP4", "A+4" },
{ "ALT_CODE_5", "ALT Code 5", "A+KP5", "A+5" },
{ "ALT_CODE_6", "ALT Code 6", "A+KP6", "A+6" },
{ "ALT_CODE_7", "ALT Code 7", "A+KP7", "A+7" },
{ "ALT_CODE_8", "ALT Code 8", "A+KP8", "A+8" },
{ "ALT_CODE_9", "ALT Code 9", "A+KP9", "A+9" },
};
static const NuvieActionDescription CheatKeyDescriptions[] = {