mirror of https://github.com/stella-emu/stella.git
refactor key mapping using hash map
key mapping now allows key + modifier combinations
This commit is contained in:
parent
a2a3844d3d
commit
fc79665d3a
|
@ -0,0 +1,167 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include "KeyMap.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
KeyMap::KeyMap(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::add(const Event::Type event, const Mapping& input)
|
||||||
|
{
|
||||||
|
myMap[convertMod(input)] = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::add(const Event::Type event, const int mode, const int key, const int mod)
|
||||||
|
{
|
||||||
|
add(event, Mapping(mode, key, mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::erase(const Mapping& input)
|
||||||
|
{
|
||||||
|
myMap.erase(convertMod(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::erase(const int mode, const int key, const int mod)
|
||||||
|
{
|
||||||
|
erase(Mapping(mode, key, mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Event::Type KeyMap::get(const Mapping& input) const
|
||||||
|
{
|
||||||
|
auto find = myMap.find(convertMod(input));
|
||||||
|
|
||||||
|
if (find != myMap.end())
|
||||||
|
return find->second;
|
||||||
|
|
||||||
|
return Event::Type::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Event::Type KeyMap::get(const int mode, const int key, const int mod) const
|
||||||
|
{
|
||||||
|
return get(Mapping(mode, key, mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string KeyMap::getEventMappingDesc(const Event::Type event, const int mode) const
|
||||||
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
#ifndef BSPF_MACOS
|
||||||
|
string modifier = "Ctrl";
|
||||||
|
#else
|
||||||
|
string modifier = "Cmd";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (auto item : myMap)
|
||||||
|
{
|
||||||
|
if (item.second == event && item.first.mode == mode)
|
||||||
|
{
|
||||||
|
if (buf.str() != "")
|
||||||
|
buf << ", ";
|
||||||
|
if (item.first.mod & StellaMod::KBDM_CTRL) buf << modifier << "+";
|
||||||
|
if (item.first.mod & StellaMod::KBDM_ALT) buf << "Alt+";
|
||||||
|
if (item.first.mod & StellaMod::KBDM_SHIFT) buf << "Shift+";
|
||||||
|
buf << StellaKeyName::forKey(item.first.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string KeyMap::saveMapping(const int mode) const
|
||||||
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
|
||||||
|
for (auto item : myMap)
|
||||||
|
{
|
||||||
|
if (item.first.mode == mode)
|
||||||
|
{
|
||||||
|
if (buf.str() != "")
|
||||||
|
buf << "|";
|
||||||
|
buf << item.second << ":" << item.first.key << "," << item.first.mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int KeyMap::loadMapping(string& list, const int mode)
|
||||||
|
{
|
||||||
|
// Since istringstream swallows whitespace, we have to make the
|
||||||
|
// delimiters be spaces
|
||||||
|
std::replace(list.begin(), list.end(), '|', ' ');
|
||||||
|
std::replace(list.begin(), list.end(), ':', ' ');
|
||||||
|
std::replace(list.begin(), list.end(), ',', ' ');
|
||||||
|
istringstream buf(list);
|
||||||
|
int event, key, mod, i = 0;
|
||||||
|
|
||||||
|
while (buf >> event && buf >> key && buf >> mod && ++i)
|
||||||
|
add(Event::Type(event), mode, key, mod);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string KeyMap::getDesc(const Mapping& input) const
|
||||||
|
{
|
||||||
|
return "TODO";
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string KeyMap::getDesc(const int mode, const int key, const int mod) const
|
||||||
|
{
|
||||||
|
return getDesc(Mapping(mode, key, mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::eraseMode(const int mode)
|
||||||
|
{
|
||||||
|
for (auto item : myMap)
|
||||||
|
if (item.first.mode == mode)
|
||||||
|
erase(item.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void KeyMap::eraseEvent(const Event::Type event, const int mode)
|
||||||
|
{
|
||||||
|
for (auto item : myMap)
|
||||||
|
if (item.second == event && item.first.mode == mode)
|
||||||
|
erase(item.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
KeyMap::Mapping KeyMap::convertMod(const Mapping& input) const
|
||||||
|
{
|
||||||
|
Mapping i = input;
|
||||||
|
|
||||||
|
// limit to modifiers we want to support
|
||||||
|
i.mod = StellaMod(i.mod & (StellaMod::KBDM_SHIFT | StellaMod::KBDM_ALT | StellaMod::KBDM_CTRL));
|
||||||
|
|
||||||
|
// merge left and right modifiers
|
||||||
|
if (i.mod & KBDM_CTRL) i.mod = StellaMod(i.mod | KBDM_CTRL);
|
||||||
|
if (i.mod & KBDM_SHIFT) i.mod = StellaMod(i.mod | KBDM_SHIFT);
|
||||||
|
if (i.mod & KBDM_ALT) i.mod = StellaMod(i.mod | KBDM_ALT);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef KEYMAP_HXX
|
||||||
|
#define KEYMAP_HXX
|
||||||
|
|
||||||
|
#include "Event.hxx"
|
||||||
|
#include "EventHandlerConstants.hxx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
This class handles keyboard mappings in Stella.
|
||||||
|
|
||||||
|
@author Thomas Jentzsch
|
||||||
|
*/
|
||||||
|
class KeyMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Mapping
|
||||||
|
{
|
||||||
|
EventMode mode;
|
||||||
|
StellaKey key;
|
||||||
|
StellaMod mod;
|
||||||
|
|
||||||
|
Mapping() : mode(EventMode(0)), key(StellaKey(0)), mod(StellaMod(0)) { }
|
||||||
|
Mapping(const Mapping& k) : mode(k.mode), key(k.key), mod(k.mod) { }
|
||||||
|
explicit Mapping(EventMode mode, StellaKey key, StellaMod mod = StellaMod::KBDM_NONE)
|
||||||
|
: mode(mode), key(key), mod(mod) { }
|
||||||
|
explicit Mapping(int mode, int key, int mod = StellaMod::KBDM_NONE)
|
||||||
|
: mode(EventMode(mode)), key(StellaKey(key)), mod(StellaMod(mod)) { }
|
||||||
|
|
||||||
|
bool operator==(const Mapping& other) const
|
||||||
|
{
|
||||||
|
return (mode == other.mode
|
||||||
|
&& key == other.key
|
||||||
|
&& mod == other.mod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyMap();
|
||||||
|
virtual ~KeyMap() = default;
|
||||||
|
|
||||||
|
/** Add new mapping for given event */
|
||||||
|
void add(const Event::Type event, const Mapping& input);
|
||||||
|
void add(const Event::Type event, const int mode, const int key, const int mod = StellaMod::KBDM_NONE);
|
||||||
|
|
||||||
|
/** Erase mapping */
|
||||||
|
void erase(const Mapping& input);
|
||||||
|
void erase(const int mode, const int key, const int mod = StellaMod::KBDM_NONE);
|
||||||
|
|
||||||
|
/** Get event for mapping */
|
||||||
|
Event::Type get(const Mapping& input) const;
|
||||||
|
Event::Type get(const int mode, const int key, const int mod = StellaMod::KBDM_NONE) const;
|
||||||
|
|
||||||
|
/** Get the mapping(s) description for given event and mode */
|
||||||
|
string getEventMappingDesc(const Event::Type event, const int mode) const;
|
||||||
|
|
||||||
|
/** Get mapping description */
|
||||||
|
string getDesc(const Mapping& input) const;
|
||||||
|
string getDesc(const int mode, const int key, const int mod = StellaMod::KBDM_NONE) const;
|
||||||
|
|
||||||
|
string saveMapping(const int mode) const;
|
||||||
|
int loadMapping(string& list, const int mode);
|
||||||
|
|
||||||
|
/** Erase all mappings for given mode */
|
||||||
|
void eraseMode(const int mode);
|
||||||
|
/** Erase given event's mapping for given mode */
|
||||||
|
void eraseEvent(const Event::Type event, const int mode);
|
||||||
|
/** clear all mappings for a modes */
|
||||||
|
// void clear() { myMap.clear(); }
|
||||||
|
size_t size() { return myMap.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//** Convert modifiers */
|
||||||
|
Mapping convertMod(const Mapping& input) const;
|
||||||
|
|
||||||
|
struct KeyHash {
|
||||||
|
size_t operator()(const Mapping& k)const {
|
||||||
|
return std::hash<long long>()(((long long)k.mode)
|
||||||
|
^ (((long long)k.key) << 16)
|
||||||
|
^ (((long long)k.mod) << 32));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<Mapping, Event::Type, KeyHash> myMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@
|
||||||
#include "TIASurface.hxx"
|
#include "TIASurface.hxx"
|
||||||
#include "PNGLibrary.hxx"
|
#include "PNGLibrary.hxx"
|
||||||
#include "PKeyboardHandler.hxx"
|
#include "PKeyboardHandler.hxx"
|
||||||
|
#include "KeyMap.hxx"
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "Debugger.hxx"
|
#include "Debugger.hxx"
|
||||||
|
@ -43,33 +44,12 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(
|
||||||
myAltKeyCounter(0),
|
myAltKeyCounter(0),
|
||||||
myUseCtrlKeyFlag(myOSystem.settings().getBool("ctrlcombo"))
|
myUseCtrlKeyFlag(myOSystem.settings().getBool("ctrlcombo"))
|
||||||
{
|
{
|
||||||
// Since istringstream swallows whitespace, we have to make the
|
string list = myOSystem.settings().getString("keymap_emu");
|
||||||
// delimiters be spaces
|
int i = myKeyMap.loadMapping(list, kEmulationMode);
|
||||||
string list = myOSystem.settings().getString("keymap");
|
list = myOSystem.settings().getString("keymap_ui");
|
||||||
replace(list.begin(), list.end(), ':', ' ');
|
i += myKeyMap.loadMapping(list, kMenuMode);
|
||||||
istringstream buf(list);
|
|
||||||
|
|
||||||
IntArray map;
|
if (!i)
|
||||||
int value;
|
|
||||||
Event::Type e;
|
|
||||||
|
|
||||||
// Get event count, which should be the first int in the list
|
|
||||||
buf >> value;
|
|
||||||
e = Event::Type(value);
|
|
||||||
if(e == Event::LastType)
|
|
||||||
while(buf >> value)
|
|
||||||
map.push_back(value);
|
|
||||||
|
|
||||||
// Only fill the key mapping array if the data is valid
|
|
||||||
if(e == Event::LastType && map.size() == KBDK_LAST * kNumModes)
|
|
||||||
{
|
|
||||||
// Fill the keymap table with events
|
|
||||||
auto ev = map.cbegin();
|
|
||||||
for(int mode = 0; mode < kNumModes; ++mode)
|
|
||||||
for(int i = 0; i < KBDK_LAST; ++i)
|
|
||||||
myKeyTable[i][mode] = Event::Type(*ev++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
setDefaultMapping(Event::NoType, kEmulationMode);
|
setDefaultMapping(Event::NoType, kEmulationMode);
|
||||||
setDefaultMapping(Event::NoType, kMenuMode);
|
setDefaultMapping(Event::NoType, kMenuMode);
|
||||||
|
@ -83,16 +63,13 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod
|
||||||
// Otherwise, only reset the given event
|
// Otherwise, only reset the given event
|
||||||
bool eraseAll = (event == Event::NoType);
|
bool eraseAll = (event == Event::NoType);
|
||||||
if(eraseAll)
|
if(eraseAll)
|
||||||
{
|
// Erase all mappings of given mode
|
||||||
// Erase all mappings
|
myKeyMap.eraseMode(mode);
|
||||||
for(int i = 0; i < KBDK_LAST; ++i)
|
|
||||||
myKeyTable[i][mode] = Event::NoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto setDefaultKey = [&](StellaKey key, Event::Type k_event)
|
auto setDefaultKey = [&](StellaKey key, Event::Type k_event, StellaMod mod = StellaMod::KBDM_NONE)
|
||||||
{
|
{
|
||||||
if(eraseAll || k_event == event)
|
if(eraseAll || k_event == event)
|
||||||
myKeyTable[key][mode] = k_event;
|
myKeyMap.add(k_event, mode, key, mod);
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(mode)
|
switch(mode)
|
||||||
|
@ -213,53 +190,33 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PhysicalKeyboardHandler::eraseMapping(Event::Type event, EventMode mode)
|
void PhysicalKeyboardHandler::eraseMapping(Event::Type event, EventMode mode)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < KBDK_LAST; ++i)
|
// This key cannot be remapped
|
||||||
// This key cannot be remapped
|
if (event != Event::UINavNext || mode != EventMode::kMenuMode)
|
||||||
if(myKeyTable[i][mode] == event && !(i == KBDK_TAB && mode == EventMode::kMenuMode))
|
myKeyMap.eraseEvent(event, mode);
|
||||||
myKeyTable[i][mode] = Event::NoType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PhysicalKeyboardHandler::saveMapping()
|
void PhysicalKeyboardHandler::saveMapping()
|
||||||
{
|
{
|
||||||
// Iterate through the keymap table and create a colon-separated list
|
myOSystem.settings().setValue("keymap_emu", myKeyMap.saveMapping(kEmulationMode));
|
||||||
// Prepend the event count, so we can check it on next load
|
myOSystem.settings().setValue("keymap_ui", myKeyMap.saveMapping(kMenuMode));
|
||||||
ostringstream keybuf;
|
|
||||||
keybuf << Event::LastType;
|
|
||||||
for(int mode = 0; mode < kNumModes; ++mode)
|
|
||||||
for(int i = 0; i < KBDK_LAST; ++i)
|
|
||||||
keybuf << ":" << myKeyTable[i][mode];
|
|
||||||
|
|
||||||
myOSystem.settings().setValue("keymap", keybuf.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string PhysicalKeyboardHandler::getMappingDesc(Event::Type event, EventMode mode) const
|
string PhysicalKeyboardHandler::getMappingDesc(Event::Type event, EventMode mode) const
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
return myKeyMap.getEventMappingDesc(event, mode);
|
||||||
|
|
||||||
for(int k = 0; k < KBDK_LAST; ++k)
|
|
||||||
{
|
|
||||||
if(myKeyTable[k][mode] == event)
|
|
||||||
{
|
|
||||||
if(buf.str() != "")
|
|
||||||
buf << ", ";
|
|
||||||
buf << StellaKeyName::forKey(StellaKey(k));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode,
|
bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode,
|
||||||
StellaKey key)
|
StellaKey key, StellaMod mod)
|
||||||
{
|
{
|
||||||
// These keys cannot be remapped
|
// These keys cannot be remapped
|
||||||
if((key == KBDK_TAB && mode == EventMode::kMenuMode) || Event::isAnalog(event))
|
if((key == KBDK_TAB && mode == EventMode::kMenuMode) || Event::isAnalog(event))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
myKeyTable[key][mode] = event;
|
myKeyMap.add(event, mode, key, mod);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +274,7 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle keys which switch eventhandler state
|
// Handle keys which switch eventhandler state
|
||||||
if(!pressed && myHandler.changeStateByEvent(myKeyTable[key][kEmulationMode]))
|
if (!pressed && myHandler.changeStateByEvent(myKeyMap.get(kEmulationMode, key, mod)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,15 +282,15 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre
|
||||||
switch(estate)
|
switch(estate)
|
||||||
{
|
{
|
||||||
case EventHandlerState::EMULATION:
|
case EventHandlerState::EMULATION:
|
||||||
myHandler.handleEvent(myKeyTable[key][kEmulationMode], pressed);
|
myHandler.handleEvent(myKeyMap.get(kEmulationMode, key, mod), pressed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EventHandlerState::PAUSE:
|
case EventHandlerState::PAUSE:
|
||||||
switch(myKeyTable[key][kEmulationMode])
|
switch (myKeyMap.get(kEmulationMode, key, mod))
|
||||||
{
|
{
|
||||||
case Event::TakeSnapshot:
|
case Event::TakeSnapshot:
|
||||||
case Event::DebuggerMode:
|
case Event::DebuggerMode:
|
||||||
myHandler.handleEvent(myKeyTable[key][kEmulationMode], pressed);
|
myHandler.handleEvent(myKeyMap.get(kEmulationMode, key, mod), pressed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -26,6 +26,7 @@ class Event;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "EventHandlerConstants.hxx"
|
#include "EventHandlerConstants.hxx"
|
||||||
|
#include "KeyMap.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class handles all physical keyboard-related operations in Stella.
|
This class handles all physical keyboard-related operations in Stella.
|
||||||
|
@ -41,6 +42,7 @@ class Event;
|
||||||
class PhysicalKeyboardHandler
|
class PhysicalKeyboardHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PhysicalKeyboardHandler(OSystem& system, EventHandler& handler, Event& event);
|
PhysicalKeyboardHandler(OSystem& system, EventHandler& handler, Event& event);
|
||||||
|
|
||||||
void setDefaultMapping(Event::Type type, EventMode mode);
|
void setDefaultMapping(Event::Type type, EventMode mode);
|
||||||
|
@ -49,13 +51,13 @@ class PhysicalKeyboardHandler
|
||||||
string getMappingDesc(Event::Type, EventMode mode) const;
|
string getMappingDesc(Event::Type, EventMode mode) const;
|
||||||
|
|
||||||
/** Bind a physical keyboard event to a virtual event/action. */
|
/** Bind a physical keyboard event to a virtual event/action. */
|
||||||
bool addMapping(Event::Type event, EventMode mode, StellaKey key);
|
bool addMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod);
|
||||||
|
|
||||||
/** Handle a physical keyboard event. */
|
/** Handle a physical keyboard event. */
|
||||||
void handleEvent(StellaKey key, StellaMod mod, bool pressed);
|
void handleEvent(StellaKey key, StellaMod mod, bool pressed);
|
||||||
|
|
||||||
Event::Type eventForKey(StellaKey key, EventMode mode) const {
|
Event::Type eventForKey(StellaKey key, EventMode mode) const {
|
||||||
return myKeyTable[key][mode];
|
return myKeyMap.get(mode, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See comments on 'myAltKeyCounter' for more information. */
|
/** See comments on 'myAltKeyCounter' for more information. */
|
||||||
|
@ -72,11 +74,8 @@ class PhysicalKeyboardHandler
|
||||||
EventHandler& myHandler;
|
EventHandler& myHandler;
|
||||||
Event& myEvent;
|
Event& myEvent;
|
||||||
|
|
||||||
// Array of key events, indexed by StellaKey
|
// Hashmap of key events
|
||||||
Event::Type myKeyTable[KBDK_LAST][kNumModes];
|
KeyMap myKeyMap;
|
||||||
// Array of mod keys, indexed by StellaKey
|
|
||||||
// TODO - uncomment when this is ready
|
|
||||||
//StellaMod myModKeyTable[KBDK_LAST][kNumModes];
|
|
||||||
|
|
||||||
// Sometimes key combos with the Alt key become 'stuck' after the
|
// Sometimes key combos with the Alt key become 'stuck' after the
|
||||||
// window changes state, and we want to ignore that event
|
// window changes state, and we want to ignore that event
|
||||||
|
|
|
@ -6,6 +6,7 @@ MODULE_OBJS := \
|
||||||
src/common/FBSurfaceSDL2.o \
|
src/common/FBSurfaceSDL2.o \
|
||||||
src/common/FrameBufferSDL2.o \
|
src/common/FrameBufferSDL2.o \
|
||||||
src/common/FSNodeZIP.o \
|
src/common/FSNodeZIP.o \
|
||||||
|
src/common/KeyMap.o \
|
||||||
src/common/Logger.o \
|
src/common/Logger.o \
|
||||||
src/common/main.o \
|
src/common/main.o \
|
||||||
src/common/MouseControl.o \
|
src/common/MouseControl.o \
|
||||||
|
|
|
@ -848,9 +848,9 @@ void EventHandler::removePhysicalJoystickFromDatabase(const string& name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key)
|
bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod)
|
||||||
{
|
{
|
||||||
bool mapped = myPKeyHandler->addMapping(event, mode, key);
|
bool mapped = myPKeyHandler->addMapping(event, mode, key, mod);
|
||||||
if(mapped)
|
if(mapped)
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
|
|
||||||
|
|
|
@ -181,8 +181,9 @@ class EventHandler
|
||||||
@param event The event we are remapping
|
@param event The event we are remapping
|
||||||
@param mode The mode where this event is active
|
@param mode The mode where this event is active
|
||||||
@param key The key to bind to this event
|
@param key The key to bind to this event
|
||||||
|
@param mod The modifier to bind to this event
|
||||||
*/
|
*/
|
||||||
bool addKeyMapping(Event::Type event, EventMode mode, StellaKey key);
|
bool addKeyMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Bind a physical joystick axis direction to an event/action and regenerate
|
Bind a physical joystick axis direction to an event/action and regenerate
|
||||||
|
|
|
@ -82,7 +82,8 @@ Settings::Settings()
|
||||||
setPermanent(AudioSettings::SETTING_STEREO, AudioSettings::DEFAULT_STEREO);
|
setPermanent(AudioSettings::SETTING_STEREO, AudioSettings::DEFAULT_STEREO);
|
||||||
|
|
||||||
// Input event options
|
// Input event options
|
||||||
setPermanent("keymap", "");
|
setPermanent("keymap_emu", "");
|
||||||
|
setPermanent("keymap_ui", "");
|
||||||
setPermanent("joymap", "");
|
setPermanent("joymap", "");
|
||||||
setPermanent("combomap", "");
|
setPermanent("combomap", "");
|
||||||
setPermanent("joydeadzone", "13");
|
setPermanent("joydeadzone", "13");
|
||||||
|
|
|
@ -254,14 +254,14 @@ void EventMappingWidget::enableButtons(bool state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool EventMappingWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
bool EventMappingWidget::handleKeyUp(StellaKey key, StellaMod mod)
|
||||||
{
|
{
|
||||||
// Remap keys in remap mode
|
// Remap keys in remap mode
|
||||||
if(myRemapStatus && myActionSelected >= 0)
|
if (myRemapStatus && myActionSelected >= 0)
|
||||||
{
|
{
|
||||||
Event::Type event =
|
Event::Type event =
|
||||||
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
|
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
|
||||||
if(instance().eventHandler().addKeyMapping(event, myEventMode, key))
|
if (instance().eventHandler().addKeyMapping(event, myEventMode, key, mod))
|
||||||
stopRemapping();
|
stopRemapping();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -57,7 +57,7 @@ class EventMappingWidget : public Widget, public CommandSender
|
||||||
kComboCmd = 'cmbo'
|
kComboCmd = 'cmbo'
|
||||||
};
|
};
|
||||||
|
|
||||||
bool handleKeyDown(StellaKey key, StellaMod mod) override;
|
bool handleKeyUp(StellaKey key, StellaMod mod) override;
|
||||||
void handleJoyDown(int stick, int button) override;
|
void handleJoyDown(int stick, int button) override;
|
||||||
void handleJoyAxis(int stick, int axis, int value) override;
|
void handleJoyAxis(int stick, int axis, int value) override;
|
||||||
bool handleJoyHat(int stick, int hat, JoyHat value) override;
|
bool handleJoyHat(int stick, int hat, JoyHat value) override;
|
||||||
|
|
|
@ -448,15 +448,15 @@ void InputDialog::setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void InputDialog::handleKeyDown(StellaKey key, StellaMod mod)
|
void InputDialog::handleKeyUp(StellaKey key, StellaMod mod)
|
||||||
{
|
{
|
||||||
// Remap key events in remap mode, otherwise pass to parent dialog
|
// Remap key events in remap mode, otherwise pass to parent dialog
|
||||||
if(myEmulEventMapper->remapMode())
|
if (myEmulEventMapper->remapMode())
|
||||||
myEmulEventMapper->handleKeyDown(key, mod);
|
myEmulEventMapper->handleKeyUp(key, mod);
|
||||||
else if(myMenuEventMapper->remapMode())
|
else if (myMenuEventMapper->remapMode())
|
||||||
myMenuEventMapper->handleKeyDown(key, mod);
|
myMenuEventMapper->handleKeyUp(key, mod);
|
||||||
else
|
else
|
||||||
Dialog::handleKeyDown(key, mod);
|
Dialog::handleKeyUp(key, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -43,7 +43,7 @@ class InputDialog : public Dialog
|
||||||
virtual ~InputDialog();
|
virtual ~InputDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleKeyDown(StellaKey key, StellaMod mod) override;
|
void handleKeyUp(StellaKey key, StellaMod mod) override;
|
||||||
void handleJoyDown(int stick, int button) override;
|
void handleJoyDown(int stick, int button) override;
|
||||||
void handleJoyAxis(int stick, int axis, int value) override;
|
void handleJoyAxis(int stick, int axis, int value) override;
|
||||||
bool handleJoyHat(int stick, int hat, JoyHat value) override;
|
bool handleJoyHat(int stick, int hat, JoyHat value) override;
|
||||||
|
|
|
@ -374,8 +374,9 @@
|
||||||
<ClCompile Include="..\common\EventHandlerSDL2.cxx" />
|
<ClCompile Include="..\common\EventHandlerSDL2.cxx" />
|
||||||
<ClCompile Include="..\common\FBSurfaceSDL2.cxx" />
|
<ClCompile Include="..\common\FBSurfaceSDL2.cxx" />
|
||||||
<ClCompile Include="..\common\FpsMeter.cxx" />
|
<ClCompile Include="..\common\FpsMeter.cxx" />
|
||||||
<ClCompile Include="..\common\FrameBufferSDL2.cxx" />
|
<ClCompile Include="..\common\FrameBufferSDL2.cxx" />
|
||||||
<ClCompile Include="..\common\FSNodeZIP.cxx" />
|
<ClCompile Include="..\common\FSNodeZIP.cxx" />
|
||||||
|
<ClCompile Include="..\common\KeyMap.cxx" />
|
||||||
<ClCompile Include="..\common\Logger.cxx" />
|
<ClCompile Include="..\common\Logger.cxx" />
|
||||||
<ClCompile Include="..\common\main.cxx" />
|
<ClCompile Include="..\common\main.cxx" />
|
||||||
<ClCompile Include="..\common\MouseControl.cxx" />
|
<ClCompile Include="..\common\MouseControl.cxx" />
|
||||||
|
@ -1072,6 +1073,7 @@
|
||||||
<ClInclude Include="..\common\FrameBufferSDL2.hxx" />
|
<ClInclude Include="..\common\FrameBufferSDL2.hxx" />
|
||||||
<ClInclude Include="..\common\FSNodeFactory.hxx" />
|
<ClInclude Include="..\common\FSNodeFactory.hxx" />
|
||||||
<ClInclude Include="..\common\FSNodeZIP.hxx" />
|
<ClInclude Include="..\common\FSNodeZIP.hxx" />
|
||||||
|
<ClInclude Include="..\common\KeyMap.hxx" />
|
||||||
<ClInclude Include="..\common\LinkedObjectPool.hxx" />
|
<ClInclude Include="..\common\LinkedObjectPool.hxx" />
|
||||||
<ClInclude Include="..\common\Logger.hxx" />
|
<ClInclude Include="..\common\Logger.hxx" />
|
||||||
<ClInclude Include="..\common\MediaFactory.hxx" />
|
<ClInclude Include="..\common\MediaFactory.hxx" />
|
||||||
|
|
|
@ -903,6 +903,9 @@
|
||||||
<ClCompile Include="..\common\PKeyboardHandler.cxx">
|
<ClCompile Include="..\common\PKeyboardHandler.cxx">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\common\KeyMap.cxx">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\emucore\tia\Audio.cxx">
|
<ClCompile Include="..\emucore\tia\Audio.cxx">
|
||||||
<Filter>Source Files\emucore\tia</Filter>
|
<Filter>Source Files\emucore\tia</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1994,12 +1997,17 @@
|
||||||
<ClInclude Include="..\gui\R77HelpDialog.hxx">
|
<ClInclude Include="..\gui\R77HelpDialog.hxx">
|
||||||
<Filter>Header Files\gui</Filter>
|
<Filter>Header Files\gui</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\common\KeyMap.hxx">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="stella.ico">
|
<None Include="stella.ico">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\emucore\tia\frame-manager\module.mk" />
|
<None Include="..\emucore\tia\frame-manager\module.mk" />
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="stella.rc">
|
<ResourceCompile Include="stella.rc">
|
||||||
|
|
Loading…
Reference in New Issue