Addedum to the control fixes in b11564168 (#1693, #1982):

- Allow configuring keyboard keys with modifier keys
 - Allow using Alt as a key in game on linux
   (I'm still puzzled why only Ctrl and Shift where implemented in so many places)
 - Adjust the deserializer and PlayerControls.txt to match the serializer for mouse keys
 - Refactor C4PlayerControl::DoMouseInput a little bit
 - Try to fix the Mac build (attempt 1)
 - Fix a bug in C4KeyCodeEx::CompileFunc where it set an incorrect KeyComboItem::sKeyName
 - Fix(?) StdCompilerConfigRead not doing anything on NoSeparator
install-platforms
Julius Michaelis 2018-01-18 00:40:39 +01:00
parent 9eef4e2a9f
commit 914d3798a4
12 changed files with 160 additions and 157 deletions

View File

@ -614,12 +614,12 @@
Priority=75
[Assignment]
Key=Mouse1Wheel1Up
Key=Mouse0Wheel1Up
GUIGroup=50
Control=InventoryShiftBackward
[Assignment]
Key=Mouse1Wheel1Down
Key=Mouse0Wheel1Down
GUIGroup=50
Control=InventoryShiftForward
@ -741,7 +741,7 @@
# Use
[Assignment]
Key=Mouse1ButtonLeft
Key=Mouse0Left
Priority=100
GUIName=$KEY_MouseUse$
GUIDesc=$KEY_MouseUse_Desc$
@ -750,7 +750,7 @@
Control=Use
[Assignment]
Key=Mouse1ButtonRight
Key=Mouse0Right
Priority=100
GUIName=$KEY_MouseThrow$
GUIDesc=$KEY_MouseThrow_Desc$
@ -759,7 +759,7 @@
Control=Throw
[Assignment]
Key=Mouse1ButtonRight
Key=Mouse0Right
Priority=80
GUIName=$KEY_MouseUseAlt$
GUIDesc=$KEY_MouseUseAlt_Desc$
@ -770,13 +770,13 @@
# Zoom
[Assignment]
Key=Ctrl+Mouse1Wheel1Up
Key=Ctrl+Mouse0Wheel1Up
GUIGroup=60
Priority=100
Control=WheelZoomIn
[Assignment]
Key=Ctrl+Mouse1Wheel1Down
Key=Ctrl+Mouse0Wheel1Down
GUIGroup=60
Priority=100
Control=WheelZoomOut
@ -1034,24 +1034,24 @@
# click in gui
[Assignment]
Key=Mouse1ButtonLeft
Key=Mouse0Left
Priority=300
Control=GUIClick1
[Assignment]
Key=Mouse1ButtonRight
Key=Mouse0Right
Priority=300
Control=GUIClick2
# Aiming
[Assignment]
Key=Mouse1Move
Key=Mouse0Move
Control=Aim
Priority=50
[Assignment]
Key=Mouse1Move
Key=Mouse0Move
Control=GUICursor
Priority=100

View File

@ -234,6 +234,7 @@ void C4GameResList::LoadFoldersWithLocalDefs(const char *szPath)
SCopy(szPath,szFoldername,iBackslash);
// Open folder
if (SEqualNoCase(GetExtension(szFoldername),"ocf"))
{
if (Reloc.Open(hGroup, szFoldername))
{
// Check for contained defs
@ -252,6 +253,7 @@ void C4GameResList::LoadFoldersWithLocalDefs(const char *szPath)
{
LogF("Internal WARNING: Could not inspect folder %s for definitions.", szFoldername);
}
}
}
}

View File

@ -201,8 +201,6 @@ void C4PlayerControlAssignment::KeyComboItem::UpdateKeyName()
{
// update key name from key
sKeyName.Copy(Key.ToString(false, false));
if (Key.dwShift)
sKeyName.Take(FormatString("%s+%s", C4KeyCodeEx::KeyShift2String((C4KeyShiftState) Key.dwShift).getData(), sKeyName.getData()));
}
void C4PlayerControlAssignment::CompileFunc(StdCompiler *pComp)
@ -1394,40 +1392,11 @@ void C4PlayerControl::AddKeyBinding(const C4KeyCodeEx &key, bool fHoldKey, int32
C4CustomKey::PRIO_PlrControl));
}
bool C4PlayerControl::DoMouseInput(uint8_t mouse_id, int32_t mouseevent, float game_x, float game_y, float gui_x, float gui_y, bool is_ctrl_down, bool is_shift_down, bool is_alt_down, int wheel_dir)
bool C4PlayerControl::DoMouseInput(uint8_t mouse_id, int32_t mouseevent, float game_x, float game_y, float gui_x, float gui_y, DWORD modifier_flags)
{
// convert moueevent to key code
uint8_t mouseevent_code;
C4KeyCodeEx mouseevent_keycode;
bool is_down = true;
switch (mouseevent)
{
case C4MC_Button_None: mouseevent_code = KEY_MOUSE_Move; break;
case C4MC_Button_LeftUp: is_down = false; // nobreak
case C4MC_Button_LeftDown: mouseevent_code = KEY_MOUSE_ButtonLeft; break;
case C4MC_Button_LeftDouble: mouseevent_code = KEY_MOUSE_ButtonLeftDouble; break;
case C4MC_Button_RightUp: is_down = false; // nobreak
case C4MC_Button_RightDown: mouseevent_code = KEY_MOUSE_ButtonRight; break;
case C4MC_Button_RightDouble: mouseevent_code = KEY_MOUSE_ButtonRightDouble; break;
case C4MC_Button_MiddleUp: is_down = false; // nobreak
case C4MC_Button_MiddleDown: mouseevent_code = KEY_MOUSE_ButtonMiddle; break;
case C4MC_Button_MiddleDouble: mouseevent_code = KEY_MOUSE_ButtonMiddleDouble; break;
case C4MC_Button_X1Up: is_down = false; // nobreak
case C4MC_Button_X1Down: mouseevent_code = KEY_MOUSE_ButtonX1; break;
case C4MC_Button_X1Double: mouseevent_code = KEY_MOUSE_ButtonX1Double; break;
case C4MC_Button_X2Up: is_down = false; // nobreak
case C4MC_Button_X2Down: mouseevent_code = KEY_MOUSE_ButtonX2; break;
case C4MC_Button_X2Double: mouseevent_code = KEY_MOUSE_ButtonX2Double; break;
case C4MC_Button_Wheel:
if (!wheel_dir) return false;
mouseevent_code = (wheel_dir > 0) ? KEY_MOUSE_Wheel1Up : KEY_MOUSE_Wheel1Down; break;
default: assert(false); return false;
}
// compose keycode
if (is_ctrl_down) mouseevent_keycode.dwShift |= KEYS_Control;
if (is_shift_down) mouseevent_keycode.dwShift |= KEYS_Shift;
if (is_alt_down) mouseevent_keycode.dwShift |= KEYS_Alt;
mouseevent_keycode.Key = KEY_Mouse(mouse_id, mouseevent_code);
bool is_down;
C4KeyCodeEx mouseevent_keycode = C4KeyCodeEx::FromC4MC(mouse_id, mouseevent, modifier_flags, &is_down);
// first, try processing it as GUI mouse event. if not assigned, process as Game mous event
// TODO: May route this through Game.DoKeyboardInput instead - would allow assignment of mouse events in CustomConfig
// and would get rid of the Game.KeyboardInput.SetLastKeyExtraData-hack

View File

@ -429,7 +429,7 @@ public:
void Execute();
// mouse input
bool DoMouseInput(uint8_t mouse_id, int32_t mouseevent, float game_x, float game_y, float gui_x, float gui_y, bool is_ctrl_down, bool is_shift_down, bool is_alt_down, int wheel_dir);
bool DoMouseInput(uint8_t mouse_id, int32_t mouseevent, float game_x, float game_y, float gui_x, float gui_y, DWORD flags);
// control enable/disable
bool SetControlDisabled(int ctrl, bool is_disabled) { return Sync.SetControlDisabled(ctrl, is_disabled); }

View File

@ -18,6 +18,7 @@
#include "C4Include.h"
#include "gui/C4KeyboardInput.h"
#include "gui/C4MouseControl.h"
#include "c4group/C4Components.h"
#include "platform/C4Window.h"
@ -186,14 +187,53 @@ const C4KeyCodeMapEntry KeyCodeMap[] = {
};
#endif
C4KeyCodeEx::C4KeyCodeEx(C4KeyCode key, C4KeyShiftState Shift, bool fIsRepeated, int32_t deviceId)
C4KeyCodeEx::C4KeyCodeEx(C4KeyCode key, DWORD Shift, bool fIsRepeated, int32_t deviceId)
: Key(key), dwShift(Shift), fRepeated(fIsRepeated), deviceId(deviceId)
{
}
C4KeyCodeEx C4KeyCodeEx::FromC4MC(int8_t mouse_id, int32_t iButton, DWORD dwKeyParam, bool *is_down)
{
bool dummy;
if (!is_down)
is_down = &dummy;
*is_down = true;
C4KeyCode mouseevent_code;
int wheel_dir = 0;
if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyParam >> 16);
switch (iButton)
{
case C4MC_Button_None: mouseevent_code = KEY_MOUSE_Move; break;
case C4MC_Button_LeftDown: mouseevent_code = KEY_MOUSE_ButtonLeft; break;
case C4MC_Button_LeftUp: mouseevent_code = KEY_MOUSE_ButtonLeft; *is_down = false; break;
case C4MC_Button_LeftDouble: mouseevent_code = KEY_MOUSE_ButtonLeftDouble; break;
case C4MC_Button_RightDown: mouseevent_code = KEY_MOUSE_ButtonRight; break;
case C4MC_Button_RightDouble: mouseevent_code = KEY_MOUSE_ButtonRightDouble; break;
case C4MC_Button_RightUp: mouseevent_code = KEY_MOUSE_ButtonRight; *is_down = false; break;
case C4MC_Button_MiddleDown: mouseevent_code = KEY_MOUSE_ButtonMiddle; break;
case C4MC_Button_MiddleUp: mouseevent_code = KEY_MOUSE_ButtonMiddle; *is_down = false; break;
case C4MC_Button_MiddleDouble: mouseevent_code = KEY_MOUSE_ButtonMiddleDouble; break;
case C4MC_Button_X1Down: mouseevent_code = KEY_MOUSE_ButtonX1; break;
case C4MC_Button_X1Up: mouseevent_code = KEY_MOUSE_ButtonX1; *is_down = false; break;
case C4MC_Button_X1Double: mouseevent_code = KEY_MOUSE_ButtonX1Double; break;
case C4MC_Button_X2Down: mouseevent_code = KEY_MOUSE_ButtonX2; break;
case C4MC_Button_X2Up: mouseevent_code = KEY_MOUSE_ButtonX2; *is_down = false; break;
case C4MC_Button_X2Double: mouseevent_code = KEY_MOUSE_ButtonX2Double; break;
case C4MC_Button_Wheel:
if (!wheel_dir) assert("Attempted to record mouse wheel movement without a direction");
mouseevent_code = (wheel_dir > 0) ? KEY_MOUSE_Wheel1Up : KEY_MOUSE_Wheel1Down; break;
}
C4KeyCodeEx key{KEY_Mouse(mouse_id, mouseevent_code), KEYS_None};
if (dwKeyParam & MK_CONTROL) key.dwShift |= KEYS_Control;
if (dwKeyParam & MK_SHIFT) key.dwShift |= KEYS_Shift;
if (dwKeyParam & MK_ALT) key.dwShift |= KEYS_Alt;
return key;
}
void C4KeyCodeEx::FixShiftKeys()
{
// reduce stuff like Ctrl+RightCtrl to simply RightCtrl
if ((dwShift & KEYS_Alt) && (Key == K_ALT_L || Key == K_ALT_R)) dwShift &= ~KEYS_Alt;
if ((dwShift & KEYS_Control) && (Key == K_CONTROL_L || Key == K_CONTROL_R)) dwShift &= ~KEYS_Control;
if ((dwShift & KEYS_Shift) && (Key == K_SHIFT_L || Key == K_SHIFT_R)) dwShift &= ~KEYS_Shift;
}
@ -272,38 +312,36 @@ C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName)
{
// skip number
while (isdigit(*key_str)) ++key_str;
// check for known mouse events (e.g. Mouse1Move or GameMouse1Wheel)
if (!stricmp(key_str, "Move")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Move);
if (!stricmp(key_str, "Wheel1Up")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Wheel1Up);
if (!stricmp(key_str, "Wheel1Down")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Wheel1Down);
if (SEqualNoCase(key_str, "Button", 6)) // e.g. Mouse1ButtonLeft or GameMouse1ButtonRightDouble
{
// check for known mouse button events
uint8_t mouseevent_id = 0;
// check for known mouse events (e.g. Mouse0Move or GameMouse0Wheel)
if (!stricmp(key_str, "Move")) return KEY_Mouse(mouse_id, KEY_MOUSE_Move);
if (!stricmp(key_str, "Wheel1Up")) return KEY_Mouse(mouse_id, KEY_MOUSE_Wheel1Up);
if (!stricmp(key_str, "Wheel1Down")) return KEY_Mouse(mouse_id, KEY_MOUSE_Wheel1Down);
// check for known mouse button events
if (SEqualNoCase(key_str, "Button", 6)) // e.g. Mouse0ButtonLeft or GameMouse0ButtonRightDouble (This line is left here to not break anything, the buttons are now named Mouse0Left)
key_str += 6;
if (SEqualNoCase(key_str, "Left",4)) { mouseevent_id=KEY_MOUSE_ButtonLeft; key_str += 4; }
else if (SEqualNoCase(key_str, "Right",5)) { mouseevent_id=KEY_MOUSE_ButtonRight; key_str += 5; }
else if (SEqualNoCase(key_str, "Middle",6)) { mouseevent_id=KEY_MOUSE_ButtonMiddle; key_str += 6; }
else if (SEqualNoCase(key_str, "X1",2)) { mouseevent_id=KEY_MOUSE_ButtonX1; key_str += 2; }
else if (SEqualNoCase(key_str, "X2",2)) { mouseevent_id=KEY_MOUSE_ButtonX2; key_str += 2; }
else if (isdigit(*key_str))
uint8_t mouseevent_id = 0;
if (SEqualNoCase(key_str, "Left",4)) { mouseevent_id=KEY_MOUSE_ButtonLeft; key_str += 4; }
else if (SEqualNoCase(key_str, "Right",5)) { mouseevent_id=KEY_MOUSE_ButtonRight; key_str += 5; }
else if (SEqualNoCase(key_str, "Middle",6)) { mouseevent_id=KEY_MOUSE_ButtonMiddle; key_str += 6; }
else if (SEqualNoCase(key_str, "X1",2)) { mouseevent_id=KEY_MOUSE_ButtonX1; key_str += 2; }
else if (SEqualNoCase(key_str, "X2",2)) { mouseevent_id=KEY_MOUSE_ButtonX2; key_str += 2; }
else if (isdigit(*key_str))
{
// indexed mouse button (e.g. Mouse0Button4 or Mouse0Button4Double)
int button_index;
if (sscanf(key_str, "%d", &button_index) == 1)
{
// indexed mouse button (e.g. Mouse1Button4 or Mouse1Button4Double)
int button_index;
if (sscanf(key_str, "%d", &button_index) == 1)
{
mouseevent_id=static_cast<uint8_t>(KEY_MOUSE_Button1+button_index-1);
while (isdigit(*key_str)) ++key_str;
}
}
if (mouseevent_id)
{
// valid event if finished or followed by "Double"
if (!*key_str) return KEY_Mouse(mouse_id-1, mouseevent_id);
if (!stricmp(key_str, "Double")) return KEY_Mouse(mouse_id-1, mouseevent_id+(KEY_MOUSE_Button1Double-KEY_MOUSE_Button1));
// invalid mouse key...
mouseevent_id=static_cast<uint8_t>(KEY_MOUSE_Button1+button_index);
while (isdigit(*key_str)) ++key_str;
}
}
if (mouseevent_id)
{
// valid event if finished or followed by "Double"
if (!*key_str) return KEY_Mouse(mouse_id, mouseevent_id);
if (!stricmp(key_str, "Double")) return KEY_Mouse(mouse_id, mouseevent_id+(KEY_MOUSE_Button1Double-KEY_MOUSE_Button1));
// invalid mouse key...
}
}
}
@ -523,7 +561,16 @@ void C4KeyCodeEx::CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBuf)
}
dwShift = dwSetShift;
Key = eCode;
if (pOutBuf) pOutBuf->Take(std::move(sCode));
if (pOutBuf) {
// FIXME: This function is used both, to deserialize things like CON_Right and Shift+$12
// For CON_…, eCode and dwShift will be zero, and sCode will contain the key name.
// For Shift+… sCode will only contain the last token. What is correct here?
// Reading C4PlayerControlAssignment::KeyComboItem::CompileFunc suggests that setting not value for parsed combinations may be correct.
if (eCode == 0)
pOutBuf->Take(std::move(sCode));
else
pOutBuf->Copy(ToString(false, false));
}
}
}
else

View File

@ -18,6 +18,8 @@
#ifndef INC_C4KeyboardInput
#define INC_C4KeyboardInput
#include "platform/C4Window.h"
// key context classifications
enum C4KeyScope
{
@ -178,6 +180,12 @@ inline uint8_t Key_GetMouseEvent(C4KeyCode key)
return ((uint32_t)key) & uint8_t(0xff);
}
inline constexpr bool KEY_IsModifier(C4KeyCode k) {
return k == K_CONTROL_L || k == K_SHIFT_L || k == K_ALT_L ||
k == K_CONTROL_R || k == K_SHIFT_R || k == K_ALT_R;
}
#ifdef _WIN32
#define TOUPPERIFX11(key) (key)
@ -228,7 +236,8 @@ struct C4KeyCodeEx
void CompileFunc(StdCompiler *pComp, StdStrBuf *pOutBuf=nullptr);
C4KeyCodeEx(C4KeyCode Key = KEY_Default, C4KeyShiftState Shift = KEYS_None, bool fIsRepeated = false, int32_t deviceId = -1);
C4KeyCodeEx(C4KeyCode Key = KEY_Default, DWORD Shift = KEYS_None, bool fIsRepeated = false, int32_t deviceId = -1);
static C4KeyCodeEx FromC4MC(int8_t mouse_id, int32_t button, DWORD param, bool * is_down = nullptr);
bool IsRepeated() const { return fRepeated; }
@ -473,6 +482,9 @@ public:
// a key that auto-registers itself into main game keyboard input class and does dereg when deleted
class C4KeyBinding : protected C4CustomKey
{
// Stuffing these into an std::vector ends badly, so I've marked them non-copyable.
C4KeyBinding(const C4KeyBinding&) = delete;
C4KeyBinding& operator=(const C4KeyBinding&) = delete;
public:
C4KeyBinding(const C4KeyCodeEx &DefCode, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority = PRIO_Base); // ctor for default key
C4KeyBinding(const CodeList &rDefCodes, const char *szName, C4KeyScope Scope, C4KeyboardCallbackInterface *pCallback, unsigned int uiPriority = PRIO_Base); // ctor for default key

View File

@ -106,6 +106,7 @@ void C4MouseControl::Execute()
WORD wKeyState=0;
if (ControlDown) wKeyState|=MK_CONTROL;
if (ShiftDown) wKeyState|=MK_SHIFT;
if (AltDown) wKeyState|=MK_ALT;
Move(C4MC_Button_None, VpX, VpY, wKeyState);
}
}
@ -312,14 +313,8 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl
if (!TargetObject)
// safety (can't really happen in !IsPassive, but w/e
if (pPlayer && pPlayer->ControlSet)
{
if (!menuProcessed && pPlayer->ControlSet->IsMouseControlAssigned(iButton))
{
int wheel_dir = 0;
if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyFlags >> 16);
pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, (dwKeyFlags & MK_CONTROL) != 0, (dwKeyFlags & MK_SHIFT) != 0, (dwKeyFlags & MK_ALT) != 0, wheel_dir);
}
}
pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, dwKeyFlags);
}
void C4MouseControl::DoMoveInput()
@ -330,7 +325,7 @@ void C4MouseControl::DoMoveInput()
if (!(pPlayer=::Players.Get(Player))) return;
if (!pPlayer->ControlSet) return;
if (!pPlayer->ControlSet->IsMouseControlAssigned(C4MC_Button_None)) return;
pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, C4MC_Button_None, GameX, GameY, GuiX, GuiY, ControlDown, ShiftDown, AltDown, 0);
pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, C4MC_Button_None, GameX, GameY, GuiX, GuiY, (ControlDown && MK_CONTROL) | (ShiftDown && MK_SHIFT) | (AltDown && MK_ALT));
}
void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom)

View File

@ -148,8 +148,16 @@ C4StartupOptionsDlg::KeySelDialog::KeySelDialog(const C4PlayerControlAssignment
: C4GUI::MessageDialog(GetDlgMessage(assignment, assignment_set).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::MessageDialog::btnAbort | C4GUI::MessageDialog::btnReset, GetDlgIcon(assignment_set), C4GUI::MessageDialog::dsRegular),
key(KEY_Undefined), assignment(assignment), assignment_set(assignment_set)
{
pKeyListener = new C4KeyBinding(
C4KeyCodeEx(KEY_Any, KEYS_None),
const uint32_t KEYS_Allmod = KEYS_Shift | KEYS_Control | KEYS_Alt;
C4CustomKey::CodeList keys;
static_assert(KEYS_None == 0, "");
for (uint32_t k = KEYS_None; k <= KEYS_Allmod; k++) {
if (~KEYS_Allmod & k) // There is some efficient bit-twiddling (k = KEYS_Allmod & (k - KEYS_Allmod) instead of k++), but I figure that's overkill. (Relies on (defined) unsigned overflow)
continue;
keys.emplace_back(KEY_Any, k);
}
KeyListeners = std::make_unique<C4KeyBinding>(
keys,
"DefineKey",
KEYSCOPE_Gui,
new C4GUI::DlgKeyCBPassKey<C4StartupOptionsDlg::KeySelDialog>(
@ -187,13 +195,6 @@ C4GUI::Icons C4StartupOptionsDlg::KeySelDialog::GetDlgIcon(const C4PlayerControl
return C4GUI::Ico_Keyboard;
}
C4StartupOptionsDlg::KeySelDialog::~KeySelDialog()
{
delete pKeyListener;
}
void C4StartupOptionsDlg::KeySelDialog::MouseInput(C4GUI::CMouse& rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
{
// Original action
@ -212,40 +213,13 @@ void C4StartupOptionsDlg::KeySelDialog::MouseInput(C4GUI::CMouse& rMouse, int32_
else
return;
}
// Only process the input event if the user certainly didn't click a button or anything
// Only process the input event if the user certainly didn't click a button or anything...
// Logic duplication of C4PlayerControl::DoMouseInput (and C4MouseControl::Move for the wheel_dir.) There has to be a better way. :(
uint8_t mouseevent_code;
int wheel_dir = 0;
if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyParam >> 16);
switch (iButton)
{
case C4MC_Button_LeftUp:
case C4MC_Button_RightUp:
case C4MC_Button_MiddleUp:
case C4MC_Button_X1Up:
case C4MC_Button_X2Up:
case C4MC_Button_None:
if (iButton == C4MC_Button_None) // mouse got moved
return;
case C4MC_Button_LeftDown: mouseevent_code = KEY_MOUSE_ButtonLeft; break;
case C4MC_Button_LeftDouble: mouseevent_code = KEY_MOUSE_ButtonLeftDouble; break;
case C4MC_Button_RightDown: mouseevent_code = KEY_MOUSE_ButtonRight; break;
case C4MC_Button_RightDouble: mouseevent_code = KEY_MOUSE_ButtonRightDouble; break;
case C4MC_Button_MiddleDown: mouseevent_code = KEY_MOUSE_ButtonMiddle; break;
case C4MC_Button_MiddleDouble: mouseevent_code = KEY_MOUSE_ButtonMiddleDouble; break;
case C4MC_Button_X1Down: mouseevent_code = KEY_MOUSE_ButtonX1; break;
case C4MC_Button_X1Double: mouseevent_code = KEY_MOUSE_ButtonX1Double; break;
case C4MC_Button_X2Down: mouseevent_code = KEY_MOUSE_ButtonX2; break;
case C4MC_Button_X2Double: mouseevent_code = KEY_MOUSE_ButtonX2Double; break;
case C4MC_Button_Wheel:
if (!wheel_dir) return;
mouseevent_code = (wheel_dir > 0) ? KEY_MOUSE_Wheel1Up : KEY_MOUSE_Wheel1Down; break;
}
C4KeyCodeEx key{KEY_Mouse(0, mouseevent_code), KEYS_None};
if (dwKeyParam & MK_CONTROL) key.dwShift |= KEYS_Control;
if (dwKeyParam & MK_SHIFT) key.dwShift |= KEYS_Shift;
if (dwKeyParam & MK_ALT) key.dwShift |= KEYS_Alt;
KeyDown(key);
bool down;
auto key = C4KeyCodeEx::FromC4MC(0 /* FIXME: more mice! */, iButton, dwKeyParam, &down);
KeyPress(key, down);
}
bool C4StartupOptionsDlg::KeySelDialog::KeyPress(const C4KeyCodeEx &key, bool fDown)
@ -266,12 +240,9 @@ bool C4StartupOptionsDlg::KeySelDialog::KeyPress(const C4KeyCodeEx &key, bool fD
if (!assignment_set->HasKeyboard()) return false;
}
// FIXME: There doesn't seem to be any kind of KEY_IsModifier function…
switch (key.Key) {
case K_CONTROL_L: case K_SHIFT_L: case K_ALT_L:
case K_CONTROL_R: case K_SHIFT_R: case K_ALT_R:
if (fDown)
return false;
}
if ((KEY_IsModifier(key.Key) && fDown) ||
(!KEY_IsModifier(key.Key) && !fDown))
return false;
// okay, use it
this->key=key;
Close(true);

View File

@ -156,7 +156,7 @@ private:
class KeySelDialog : public C4GUI::MessageDialog
{
private:
class C4KeyBinding *pKeyListener;
std::unique_ptr<C4KeyBinding> KeyListeners;
C4KeyCodeEx key;
const class C4PlayerControlAssignment *assignment;
const class C4PlayerControlAssignmentSet *assignment_set;
@ -171,7 +171,7 @@ private:
void MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override;
public:
KeySelDialog(const class C4PlayerControlAssignment *assignment, const class C4PlayerControlAssignmentSet *assignment_set);
~KeySelDialog() override;
~KeySelDialog() override = default;
C4KeyCodeEx GetKeyCode() { return key; }

View File

@ -19,32 +19,34 @@
#ifndef INC_STDWINDOW
#define INC_STDWINDOW
#include "C4ForbidLibraryCompilation.h"
#if defined(USE_SDL_MAINLOOP)
#include <SDL.h>
#define MK_SHIFT (KMOD_LSHIFT | KMOD_RSHIFT)
#define MK_CONTROL (KMOD_LCTRL | KMOD_RCTRL)
#define MK_ALT (KMOD_LALT | KMOD_RALT)
#elif defined(USE_CONSOLE)
#ifndef _WIN32
#define MK_SHIFT 0
#define MK_CONTROL 0
#endif
#define MK_ALT 0
#include <SDL.h>
#define MK_SHIFT (KMOD_LSHIFT | KMOD_RSHIFT)
#define MK_CONTROL (KMOD_LCTRL | KMOD_RCTRL)
#define MK_ALT (KMOD_LALT | KMOD_RALT)
#elif defined(USE_COCOA)
// declare as extern variables and initialize them in StdMacWindow.mm so as to not include objc headers
extern int MK_SHIFT;
extern int MK_CONTROL;
extern int MK_ALT;
// declare as extern variables and initialize them in StdMacWindow.mm so as to not include objc headers
extern int MK_SHIFT;
extern int MK_CONTROL;
extern int MK_ALT;
#elif defined(USE_WIN32_WINDOWS)
#include "platform/C4windowswrapper.h"
#ifndef MK_ALT
#define MK_ALT 0x20 // as defined in oleidl.h
#endif
#include "platform/C4windowswrapper.h"
#ifndef MK_ALT
#define MK_ALT 0x20 // as defined in oleidl.h
#endif
#else
#if !defined(MK_SHIFT)
#define MK_SHIFT 0
#endif
#if !defined(MK_CONTROL)
#define MK_CONTROL 0
#endif
#if !defined(MK_ALT)
#define MK_ALT 0
#endif
#endif
#if defined(USE_WIN32_WINDOWS) || defined(USE_CONSOLE) || defined(USE_SDL_MAINLOOP)
#if !defined(USE_COCOA)
#define K_ESCAPE 1
#define K_1 2
#define K_2 3
@ -157,7 +159,7 @@ extern int MK_ALT;
#define K_NUM0 K_INSERT
#define K_DECIMAL K_DELETE
#define K_DIVIDE K_SLASH
#elif defined(USE_X11) || defined(USE_CONSOLE)
#elif defined(USE_X11) || defined(USE_CONSOLE - Do not forget guard include when reenabling this comment)
*/
#define K_NUM7 71
#define K_NUM8 72
@ -193,7 +195,7 @@ extern int MK_ALT;
#define K_PRINT 99
#define K_CENTER 76
#elif defined(USE_COCOA)
#else // !defined(USE_COCOA)
#import "platform/ObjectiveCAssociated.h"
// FIXME
// declare as extern variables and initialize them in StdMacWindow.mm so as to not include objc headers

View File

@ -525,6 +525,10 @@ bool StdCompilerConfigRead::Separator(Sep eSep)
}
}
void StdCompilerConfigRead::NoSeparator() {
has_separator_mismatch = false;
}
void StdCompilerConfigRead::DWord(int32_t &rInt)
{
rInt = int32_t(ReadDWord());

View File

@ -130,6 +130,7 @@ public:
// Separators
bool Separator(Sep eSep) override;
void NoSeparator() override;
// Data writers
void DWord(int32_t &rInt) override;