diff --git a/code/REDALERT/EDIT.CPP b/code/REDALERT/EDIT.CPP index 45783a9..1684c36 100644 --- a/code/REDALERT/EDIT.CPP +++ b/code/REDALERT/EDIT.CPP @@ -253,39 +253,8 @@ int EditClass::Action(unsigned flags, KeyNumType & key) } else { #ifdef WIN32 - KeyASCIIType ascii = (KeyASCIIType)(Keyboard->To_ASCII(key) & 0xff); - - /* - ** Allow numeric keypad presses to map to ascii numbers - */ - if ((key & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9') { - - key = (KeyNumType)(key & ~WWKEY_VK_BIT); - if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))) { - if (Handle_Key (ascii) ) { - flags &= ~KEYBOARD; - key = KN_NONE; - } - } - } else { - /* - ** Filter out all special keys except return and backspace - */ if ((!(key & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 255) - || key == KN_RETURN || key == KN_BACKSPACE) { - - - - if ((!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))) { - if (Handle_Key(Keyboard->To_ASCII(key))) { - flags &= ~KEYBOARD; - key = KN_NONE; - } - } - } else { - flags &= ~KEYBOARD; - key = KN_NONE; - } - } + //KeyASCIIType ascii = (KeyASCIIType)(Keyboard->To_ASCII(key) & 0xff); + Handle_Key(key, flags); } #else //WIN32 @@ -374,11 +343,12 @@ void EditClass::Draw_Text(char const * text) * HISTORY: * * 01/21/1995 JLB : Created. * *=============================================================================================*/ -bool EditClass::Handle_Key(KeyASCIIType ascii) +bool EditClass::Handle_Key(KeyNumType key, unsigned flags) { - unsigned char testAscii = (unsigned char)ascii; + unsigned char testAscii = UserInput.KeyB.ASCII; + //if (key & KN_SHIFT_BIT || key & KN_CAPSLOCK_BIT) testAscii = toupper(testAscii); - switch (ascii) { + switch (key & 0xff) { /* ** Handle the special case of a non-keyboard event. It is possible that this ** key code might be passed to this routine if this routine has been overridden @@ -394,14 +364,14 @@ bool EditClass::Handle_Key(KeyASCIIType ascii) ** so that the controlling program will know that the text can be ** processed. */ - case KA_RETURN: + case KN_RETURN: Clear_Focus(); return(false); /* ** When the BACKSPACE key is pressed, remove the last character in the edit string. */ - case KA_BACKSPACE: + case KN_BACKSPACE: if (Length) { Length--; String[Length] = '\0'; @@ -457,6 +427,7 @@ bool EditClass::Handle_Key(KeyASCIIType ascii) */ String[Length++] = testAscii; String[Length] = '\0'; + Flag_To_Redraw(); break; } diff --git a/code/REDALERT/EDIT.H b/code/REDALERT/EDIT.H index 92168d9..5d861ad 100644 --- a/code/REDALERT/EDIT.H +++ b/code/REDALERT/EDIT.H @@ -91,7 +91,7 @@ class EditClass : public ControlClass virtual int Action (unsigned flags, KeyNumType &key); virtual void Draw_Background(void); virtual void Draw_Text(char const * text); - virtual bool Handle_Key(KeyASCIIType ascii); + virtual bool Handle_Key(KeyNumType ascii, unsigned flags); private: int IsReadOnly; diff --git a/code/REDALERT/GADGET.CPP b/code/REDALERT/GADGET.CPP index eb2ce84..4d3b60c 100644 --- a/code/REDALERT/GADGET.CPP +++ b/code/REDALERT/GADGET.CPP @@ -471,7 +471,7 @@ void GadgetClass::Draw_All(bool forced) *=========================================================================*/ KeyNumType GadgetClass::Input(void) { - EventMessage* eventMessage = NULL; + EventMessage eventMessage; KeyNumType key = KN_NONE; int flags = 0; int forced = false; @@ -490,11 +490,11 @@ KeyNumType GadgetClass::Input(void) /* ** Fetch any pending keyboard input. */ - UserInput.Process_Input(); // key, flags); + UserInput.Process_Input(key, flags); if ( EventQueue.Check() ) { eventMessage = EventQueue.Get(); - eventMessage->Key_Flags( key, flags ); + eventMessage.Key_Flags( key, flags ); } /* @@ -518,7 +518,7 @@ KeyNumType GadgetClass::Input(void) ** If there is a gadget that has the keyboard focus, then route all keyboard ** events to it. */ - if ( Focused && eventMessage != NULL && eventMessage->EventType == EventMessageType::EVENT_KEYBOARD ) { + if ( Focused && eventMessage.EventType == EventMessageType::EVENT_KEYBOARD ) { Focused->Draw_Me(false); Focused->Clicked_On(key, flags, UserInput.Mouse.X, UserInput.Mouse.Y); if (Focused) { diff --git a/code/REDALERT/io/EventQueue.cpp b/code/REDALERT/io/EventQueue.cpp index 94919a1..eef7a05 100644 --- a/code/REDALERT/io/EventQueue.cpp +++ b/code/REDALERT/io/EventQueue.cpp @@ -2,20 +2,22 @@ #include "EventQueue.h" /* - Clears the event queue + Clears the event queue and frees memory */ void EventQueueClass::Clear() { - while (this->eventQueue.size() > 0) this->eventQueue.pop(); + while (this->eventQueue.size() > 0) { + this->eventQueue.pop(); + } } /* - Inserts a new KeyNumType event into the FIFO buffer. KeyNumType represents a key press or mouse button - Input: KeyNumType + optional flag bits for SHIFT/CTRL/etc. cast as unsigned short + Inserts a new event message event into the FIFO buffer. */ -void EventQueueClass::Put(EventMessage* input) +void EventQueueClass::Put(EventMessage input) { - this->eventQueue.push(input); + if ( Is_Buffer_Full() ) return; + this->eventQueue.push( input ); } /* @@ -29,12 +31,12 @@ bool EventQueueClass::Check() const /* Get the first (unprocessed) element in the event queue */ -EventMessage* EventQueueClass::Get() +EventMessage EventQueueClass::Get() { // wait for buffer while( !this->Check() ) { } - - EventMessage* returnVal = this->eventQueue.front(); + + EventMessage returnVal = this->eventQueue.front(); this->eventQueue.pop(); return returnVal; @@ -46,95 +48,110 @@ EventMessage* EventQueueClass::Get() char EventQueueClass::Get_ASCII() { // get the last key from the buffer - KeyboardEventMessage* keyMessage = dynamic_cast( this->Get() ); - unsigned short key = keyMessage->Key; - - // check if it is a keyboard - if (key == KN_LMOUSE || key == KN_RMOUSE) return 0x0; - - // convert to ascii - char ascii; - unsigned short key_raw = (UINT)(key & 0xFF); - - // find the SDL keycode - auto sdl_Key = sdl_keyMapping_reverse.find( (KeyNumType)key_raw ); - if (sdl_Key != sdl_keyMapping_reverse.end()) - { - // convert to ascii - ascii = SDL_GetKeyName( sdl_Key->first )[0]; - - // convert to uppercase - if (keyMessage->Shift || keyMessage->CapsLock) ascii = toupper(ascii); - } - - return 0x0; + EventMessage eventMessage = this->Get(); + return eventMessage.Keyboard.ASCII; } -KeyboardEventMessage::KeyboardEventMessage(KeyNumType key, bool shift, bool alt, bool control, bool capsLock) { +EventMessage::EventMessage(KeyNumType key, char ascii, bool shift, bool alt, bool control, bool capsLock) { + this->Clear(); + + this->Valid = true; this->EventType = EventMessageType::EVENT_KEYBOARD; - this->Key = key; - this->Shift = shift; - this->Alt = alt; - this->Control = control; - this->CapsLock = capsLock; - this->Flags = 0; - if (this->Shift) this->Flags |= KN_SHIFT_BIT; - if (this->Alt) this->Flags |= KN_ALT_BIT; - if (this->Control) this->Flags |= KN_CTRL_BIT; + this->Keyboard.Key = key; + this->Keyboard.Shift = shift; + this->Keyboard.Alt = alt; + this->Keyboard.Control = control; + this->Keyboard.CapsLock = capsLock; + this->Keyboard.ASCII = ascii; } -void KeyboardEventMessage::Key_Flags(KeyNumType& key, int& flags) +EventMessage::EventMessage(int x, int y, unsigned short button, MouseButtonState buttonState) { - flags = this->Flags; - flags |= GadgetClass::KEYBOARD; + this->Clear(); - key = (KeyNumType)this->Key; -} - -MouseEventMessage::MouseEventMessage(int x, int y, unsigned short button, UserInputClass::MouseButtonState buttonState) -{ + this->Valid = true; this->EventType = EventMessageType::EVENT_MOUSE; - this->x = x; - this->y = y; - this->Button = button; - this->ButtonState = buttonState; + this->Mouse.x = x; + this->Mouse.y = y; + this->Mouse.Button = button; + this->Mouse.ButtonState = buttonState; this->Flags = 0; -} -void MouseEventMessage::Key_Flags(KeyNumType& key, int& flags) -{ - key = (KeyNumType)this->Button; - - if (key == KN_LMOUSE) { - switch (this->ButtonState) - { - case UserInputClass::MouseButtonState::MOUSE_BUTTON_DOWN: - flags = GadgetClass::LEFTPRESS; - break; - case UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE: - flags = GadgetClass::LEFTRELEASE; - break; - case UserInputClass::MouseButtonState::MOUSE_BUTTON_HOLD: - flags = GadgetClass::LEFTHELD; - break; - } + if (buttonState == MouseButtonState::MOUSE_BUTTON_UP) { + this->Flags = (button == KN_LMOUSE) ? GadgetClass::LEFTUP : GadgetClass::RIGHTUP; } - if (key == KN_RMOUSE) { - switch (this->ButtonState) - { - case UserInputClass::MouseButtonState::MOUSE_BUTTON_DOWN: - flags = GadgetClass::RIGHTPRESS; - break; - case UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE: - flags = GadgetClass::RIGHTRELEASE; - break; - case UserInputClass::MouseButtonState::MOUSE_BUTTON_HOLD: - flags = GadgetClass::RIGHTHELD; - break; + if (buttonState == MouseButtonState::MOUSE_BUTTON_DOWN) { + this->Flags = (button == KN_LMOUSE) ? GadgetClass::LEFTPRESS : GadgetClass::RIGHTPRESS; + } + + if (buttonState == MouseButtonState::MOUSE_BUTTON_HOLD) { + this->Flags = (button == KN_LMOUSE) ? GadgetClass::LEFTHELD : GadgetClass::RIGHTHELD; + } + + if (buttonState == MouseButtonState::MOUSE_BUTTON_RELEASE) { + this->Flags = (button == KN_LMOUSE) ? GadgetClass::LEFTRELEASE : GadgetClass::RIGHTRELEASE; + } +} + + +void EventMessage::Key_Flags(KeyNumType& key, int& flags) +{ + if (this->EventType == EventMessageType::EVENT_KEYBOARD) + { + flags = this->Flags; + flags |= GadgetClass::KEYBOARD; + + unsigned short outputKey = this->Keyboard.Key; + + if (this->Keyboard.Shift) outputKey |= KN_SHIFT_BIT; + if (this->Keyboard.Alt) outputKey |= KN_ALT_BIT; + if (this->Keyboard.Control) outputKey |= KN_CTRL_BIT; + + key = (KeyNumType)outputKey; + } + + if (this->EventType == EventMessageType::EVENT_MOUSE) + { + key = (KeyNumType)this->Mouse.Button; + + if (key == KN_LMOUSE) { + switch (this->Mouse.ButtonState) + { + case MouseButtonState::MOUSE_BUTTON_UP: + flags = GadgetClass::LEFTUP; + break; + case MouseButtonState::MOUSE_BUTTON_DOWN: + flags = GadgetClass::LEFTPRESS; + break; + case MouseButtonState::MOUSE_BUTTON_RELEASE: + flags = GadgetClass::LEFTRELEASE; + break; + case MouseButtonState::MOUSE_BUTTON_HOLD: + flags = GadgetClass::LEFTHELD; + break; + } + } + + if (key == KN_RMOUSE) { + switch (this->Mouse.ButtonState) + { + case MouseButtonState::MOUSE_BUTTON_UP: + flags = GadgetClass::LEFTUP; + break; + case MouseButtonState::MOUSE_BUTTON_DOWN: + flags = GadgetClass::RIGHTPRESS; + break; + case MouseButtonState::MOUSE_BUTTON_RELEASE: + flags = GadgetClass::RIGHTRELEASE; + break; + case MouseButtonState::MOUSE_BUTTON_HOLD: + flags = GadgetClass::RIGHTHELD; + break; + } } } } \ No newline at end of file diff --git a/code/REDALERT/io/EventQueue.h b/code/REDALERT/io/EventQueue.h index 0767b4a..be92699 100644 --- a/code/REDALERT/io/EventQueue.h +++ b/code/REDALERT/io/EventQueue.h @@ -1,4 +1,5 @@ #pragma once +#include /* * WWKeyboardClass::Buff_Get -- Lowlevel function to get a key from key buffer* @@ -22,10 +23,11 @@ extern UserInputClass UserInput; /* Event type definitions */ -typedef enum { +typedef enum EventMessageType { + EVENT_NONE, EVENT_KEYBOARD, EVENT_MOUSE -} EventMessageType; +}; /* Event types @@ -33,42 +35,69 @@ typedef enum { class EventMessage { public: EventMessageType EventType; + bool Valid; - virtual void Key_Flags(KeyNumType& key, int& flags) = 0; - virtual ~EventMessage() = default; -}; + EventMessage() { + this->EventType == EVENT_NONE; -class KeyboardEventMessage : public EventMessage { - public: - KeyNumType Key; - bool Shift; - bool Alt; - bool Control; - bool CapsLock; + this->Keyboard.Key = KN_NONE; + this->Keyboard.Shift = false; + this->Keyboard.Alt = false; + this->Keyboard.Control = false; + this->Keyboard.CapsLock = false; + + this->Mouse.x = -1; + this->Mouse.y = -1; + this->Mouse.Button = 0; + this->Mouse.ButtonState = MouseButtonState::MOUSE_BUTTON_UP; + + this->Flags = 0; + + this->Valid = false; + } + + // for keyboard + struct { + KeyNumType Key; + char ASCII; + bool Shift; + bool Alt; + bool Control; + bool CapsLock; + } Keyboard; + + // for mouse + struct { + int x; + int y; + unsigned short Button; + MouseButtonState ButtonState; + } Mouse; // for cascading functions unsigned short Flags; - KeyboardEventMessage(KeyNumType key, bool shift = false, bool alt = false, bool control = false, bool capsLock = false); - virtual void Key_Flags(KeyNumType& key, int& flags); + EventMessage( KeyNumType key, char asciis, bool shift, bool alt, bool control, bool capsLock ); + EventMessage( int x, int y, unsigned short button = KN_LMOUSE, MouseButtonState buttonState = MouseButtonState::MOUSE_BUTTON_DOWN ); - virtual ~KeyboardEventMessage() = default; -}; + void Key_Flags(KeyNumType& key, int& flags); + private: + void Clear() { + this->Keyboard.Key = KN_NONE; + this->Keyboard.Shift = false; + this->Keyboard.Alt = false; + this->Keyboard.Control = false; + this->Keyboard.CapsLock = false; -class MouseEventMessage : public EventMessage { - public: - int x; - int y; - unsigned short Button; - UserInputClass::MouseButtonState ButtonState; + this->Mouse.x = -1; + this->Mouse.y = -1; + this->Mouse.Button = 0; + this->Mouse.ButtonState = MouseButtonState::MOUSE_BUTTON_UP; - // for cascading functions - unsigned short Flags; + this->Flags = 0; - MouseEventMessage(int x, int y, unsigned short button = KN_LMOUSE, UserInputClass::MouseButtonState buttonState = UserInputClass::MouseButtonState::MOUSE_BUTTON_DOWN); - virtual void Key_Flags(KeyNumType& key, int& flags); - - virtual ~MouseEventMessage() = default; + this->Valid = false; + } }; class EventQueueClass { @@ -77,15 +106,15 @@ class EventQueueClass { int Get_Mouse_Y() const { return UserInput.Mouse.Y; } void Clear(); - void Put(EventMessage* input); + void Put(EventMessage input); bool Check() const; - EventMessage* Get(); + EventMessage Get(); char EventQueueClass::Get_ASCII(); private: const int MaxCapacity = 100; - std::queue eventQueue; + std::queue< EventMessage > eventQueue; bool Is_Buffer_Full() const { return this->eventQueue.size() == MaxCapacity; } bool Is_Buffer_Empty() const { return this->eventQueue.size() == 0; } diff --git a/code/REDALERT/io/UserInput.cpp b/code/REDALERT/io/UserInput.cpp index 818f64d..cab49c4 100644 --- a/code/REDALERT/io/UserInput.cpp +++ b/code/REDALERT/io/UserInput.cpp @@ -49,6 +49,8 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) const Uint32 MouseState = SDL_GetMouseState(&Mouse.X, &Mouse.Y); + flags = 0; + Keyboard->MouseQX = Mouse.X; Keyboard->MouseQY = Mouse.Y; @@ -87,8 +89,9 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) case SDL_MOUSEMOTION: if ( !( MouseState & SDL_BUTTON(SDL_BUTTON_LEFT) ) ) { - flags = GadgetClass::LEFTUP; + flags |= GadgetClass::LEFTUP; } + break; case SDL_MOUSEBUTTONDOWN: @@ -96,9 +99,9 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_DOWN; key = KN_LMOUSE; - flags = GadgetClass::LEFTPRESS; + flags |= GadgetClass::LEFTPRESS; - EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE) ); + EventQueue.Put( EventMessage( Mouse.X, Mouse.Y, KN_LMOUSE ) ); Keyboard->Put_Element(KN_LMOUSE); @@ -112,12 +115,12 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) else if (event.button.button == SDL_BUTTON_RIGHT) { Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_DOWN; - EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_RMOUSE) ); + EventQueue.Put( EventMessage( Mouse.X, Mouse.Y, KN_RMOUSE ) ); Keyboard->Put_Element(KN_RMOUSE); key = KN_RMOUSE; - flags = GadgetClass::RIGHTPRESS; + flags |= GadgetClass::RIGHTPRESS; numFramesLMouse = 0; } @@ -127,17 +130,17 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) if (event.button.button == SDL_BUTTON_LEFT) { Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_RELEASE; - EventQueue.Put(new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE)); + EventQueue.Put( EventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, MouseButtonState::MOUSE_BUTTON_RELEASE) ); - flags = GadgetClass::LEFTRELEASE; + flags |= GadgetClass::LEFTRELEASE; numFramesLMouse = 0; } else if (event.button.button == SDL_BUTTON_RIGHT) { Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_RELEASE; - EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_RMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE) ); + EventQueue.Put( EventMessage(Mouse.X, Mouse.Y, KN_RMOUSE, MouseButtonState::MOUSE_BUTTON_RELEASE) ); - flags = GadgetClass::RIGHTRELEASE; + flags |= GadgetClass::RIGHTRELEASE; numFramesLMouse = 0; } break; @@ -159,6 +162,11 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) } int keyFlags = 0x00; + KeyB.Shift = false; + KeyB.Alt = false; + KeyB.Control = false; + KeyB.CapsLock = false; + if (state[SDL_SCANCODE_RSHIFT] || state[SDL_SCANCODE_LSHIFT]) { KeyB.Shift = true; keyFlags |= KN_SHIFT_BIT; @@ -176,16 +184,20 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) KeyB.CapsLock = true; } - // handle match between SDL and internals (non-text keys) + // handle match between SDL and internals ( non-text keys ) auto element = sdl_keyMapping.find((SDL_KeyCode)event.key.keysym.sym); if (element != sdl_keyMapping.end()) { //EventQueue.Put( element->second | keyFlags ); - EventQueue.Put( new KeyboardEventMessage( (KeyNumType)element->second, KeyB.Shift, KeyB.Alt, KeyB.Control, KeyB.CapsLock ) ); + EventQueue.Put( EventMessage( (KeyNumType)element->second, element->second, KeyB.Shift, KeyB.Alt, KeyB.Control, KeyB.CapsLock ) ); Keyboard->Put_Element( element->second | keyFlags); - KeyB.ASCII = element->second; + KeyB.LastKey = element->first; + if (event.text.text[0] == (event.text.text[0] & 0xFF)) + { + KeyB.ASCII = element->second; + } } break; @@ -207,8 +219,8 @@ void UserInputClass::Process_Input(KeyNumType& key, int& flags) if (!leftMouseProcessed && numFramesLMouse != 0) { Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_HOLD; - flags = GadgetClass::LEFTHELD; + flags |= GadgetClass::LEFTHELD; - EventQueue.Put(new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_HOLD)); + EventQueue.Put( EventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, MouseButtonState::MOUSE_BUTTON_HOLD) ); } } \ No newline at end of file diff --git a/code/REDALERT/io/UserInput.h b/code/REDALERT/io/UserInput.h index 41f37c9..6d9db2e 100644 --- a/code/REDALERT/io/UserInput.h +++ b/code/REDALERT/io/UserInput.h @@ -93,22 +93,22 @@ const int USERINPUT_SHIFT_BIT = 0x100; const int USERINPUT_CTRL_BIT = 0x200; const int USERINPUT_ALT_BIT = 0x400; +typedef enum { + MOUSE_BUTTON_UP, + MOUSE_BUTTON_DOWN, + MOUSE_BUTTON_HOLD, + MOUSE_BUTTON_RELEASE, +} MouseButtonState; + +typedef enum { + INPUT_ACTION_NONE, + INPUT_ACTION_KEYBOARD, + INPUT_ACTION_MOUSE, +} InputAction; + class UserInputClass { public: - typedef enum { - MOUSE_BUTTON_UP, - MOUSE_BUTTON_DOWN, - MOUSE_BUTTON_HOLD, - MOUSE_BUTTON_RELEASE, - } MouseButtonState; - - typedef enum { - INPUT_ACTION_NONE, - INPUT_ACTION_KEYBOARD, - INPUT_ACTION_MOUSE, - } InputAction; - UserInputClass(); void UserInputClass::Process_Input( KeyNumType& key = g_globalKeyNumType, int& flags = g_globalKeyFlags );