diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index f8efb95..b794edb 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -8,6 +8,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../) set(CMAKE_VERBOSE_MAKEFILE ON) +set(src_io + ./REDALERT/io/UserInput.cpp + ./REDALERT/io/UserInput.h +) + set(src_win32lib ./REDALERT/WIN32LIB/TOBUFF.cpp ./RedAlert/WIN32LIB/ALLOC.CPP @@ -708,8 +713,8 @@ set(src_external add_definitions(-DCHEAT_KEYS -DIMGUI_IMPL_OPENGL_LOADER_GLEW -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS) add_compile_options(/permissive+ /Zc:forScope- /Zp1) -add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external}) +add_executable(RedAlert ${src_io} ${src_win32lib} ${src_redalert} ${src_external}) set_target_properties(RedAlert PROPERTIES OUTPUT_NAME "RedAlert" LINK_FLAGS "/PDB:\"RedAlert.pdb\" /SUBSYSTEM:WINDOWS" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../bin" ) -target_include_directories(RedAlert PRIVATE ./external/devil/;./external/;./redalert/win32lib;./external/lua/;./external/imgui;./external/dxsdk/Include;./external/ffmpeg-win32/include;./external/sdl2/include;./win32lib;./external/openal/include) +target_include_directories(RedAlert PRIVATE ./external/devil/;./external/;./redalert/io;./redalert/win32lib;./external/lua/;./external/imgui;./external/dxsdk/Include;./external/ffmpeg-win32/include;./external/sdl2/include;./win32lib;./external/openal/include) target_link_libraries(RedAlert "opengl32.lib" "winmm.lib" "Ws2_32.lib" "${CMAKE_SOURCE_DIR}/external/devil/DevIL.lib" "${CMAKE_SOURCE_DIR}/external/sdl2/lib/x86/SDL2.lib" "${CMAKE_SOURCE_DIR}/external/openal/out/build/x86-Release/OpenAL32.lib") diff --git a/code/REDALERT/CONQUER.CPP b/code/REDALERT/CONQUER.CPP index a0ae38f..4fec68c 100644 --- a/code/REDALERT/CONQUER.CPP +++ b/code/REDALERT/CONQUER.CPP @@ -891,45 +891,45 @@ void Keyboard_Process(KeyNumType & input) ** state! */ if (input != 0 && (plain == Options.KeyTeam1 || plain == KN_1)) { - Handle_Team(0, action); - input = KN_NONE; - } - if (input != 0 && (plain == Options.KeyTeam2 || plain == KN_2)) { Handle_Team(1, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam3 || plain == KN_3)) { + if (input != 0 && (plain == Options.KeyTeam2 || plain == KN_2)) { Handle_Team(2, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam4 || plain == KN_4)) { + if (input != 0 && (plain == Options.KeyTeam3 || plain == KN_3)) { Handle_Team(3, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam5 || plain == KN_5)) { + if (input != 0 && (plain == Options.KeyTeam4 || plain == KN_4)) { Handle_Team(4, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam6 || plain == KN_6)) { + if (input != 0 && (plain == Options.KeyTeam5 || plain == KN_5)) { Handle_Team(5, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam7 || plain == KN_7)) { + if (input != 0 && (plain == Options.KeyTeam6 || plain == KN_6)) { Handle_Team(6, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam8 || plain == KN_8)) { + if (input != 0 && (plain == Options.KeyTeam7 || plain == KN_7)) { Handle_Team(7, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam9 || plain == KN_9)) { + if (input != 0 && (plain == Options.KeyTeam8 || plain == KN_8)) { Handle_Team(8, action); input = KN_NONE; } - if (input != 0 && (plain == Options.KeyTeam10 || plain == KN_0)) { + if (input != 0 && (plain == Options.KeyTeam9 || plain == KN_9)) { Handle_Team(9, action); input = KN_NONE; } + if (input != 0 && (plain == Options.KeyTeam10 || plain == KN_0)) { + Handle_Team(0, action); + input = KN_NONE; + } /* ** Handle the bookmark hotkeys. diff --git a/code/REDALERT/DISPLAY.CPP b/code/REDALERT/DISPLAY.CPP index 4401a5a..52929de 100644 --- a/code/REDALERT/DISPLAY.CPP +++ b/code/REDALERT/DISPLAY.CPP @@ -3309,16 +3309,15 @@ int DisplayClass::TacticalClass::Selection_At_Mouse(unsigned flags, KeyNumType & { int x, y; // Sub cell pixel coordinates. bool edge = false; - if (flags & (LEFTPRESS | LEFTRELEASE | RIGHTPRESS | RIGHTRELEASE)) { - x = Keyboard->MouseQX; - y = Keyboard->MouseQY; - } - else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); + + x = UserInput.Mouse.X; + y = UserInput.Mouse.Y; - if (x == 0 || y == 199 || x == 319) edge = true; + if (x == 0 || y == SeenBuff.Get_Height() || x == SeenBuff.Get_Width()) + { + edge = true; } + COORDINATE coord = Map.Pixel_To_Coord(x, y); CELL cell = Coord_Cell(coord); @@ -3345,7 +3344,7 @@ int DisplayClass::TacticalClass::Selection_At_Mouse(unsigned flags, KeyNumType & if (object != nullptr) { - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); + bool shiftdown = UserInput.KeyB.Shift = true; if (shiftdown) { @@ -3387,16 +3386,15 @@ int DisplayClass::TacticalClass::Command_Object(unsigned flags, KeyNumType & key { int x, y; // Sub cell pixel coordinates. bool edge = false; - if (flags & (LEFTPRESS | LEFTRELEASE | RIGHTPRESS | RIGHTRELEASE)) { - x = Keyboard->MouseQX; - y = Keyboard->MouseQY; - } - else { - x = Get_Mouse_X(); - y = Get_Mouse_Y(); - if (x == 0 || y == 199 || x == 319) edge = true; + x = UserInput.Mouse.X; + y = UserInput.Mouse.Y; + + if (x == 0 || y == SeenBuff.Get_Height() || x == SeenBuff.Get_Width()) + { + edge = true; } + COORDINATE coord = Map.Pixel_To_Coord(x, y); CELL cell = Coord_Cell(coord); diff --git a/code/REDALERT/ENDING.CPP b/code/REDALERT/ENDING.CPP index 8f5e10f..f7d0ff9 100644 --- a/code/REDALERT/ENDING.CPP +++ b/code/REDALERT/ENDING.CPP @@ -122,10 +122,10 @@ void Nod_Ending(void) if ((key & 0xFF) == KN_LMOUSE && !(key & KN_RLSE_BIT)) { int mousex = MouseQX; int mousey = MouseQY; - if (mousey >= 22 && mousey <= 177) { + if (mousex >= 22 && mousey <= 177) { done++; - if (mousex < 160 && mousey < 100) selection = 2; - if (mousex < 160 && mousey >= 100) selection = 3; + if (mousex < 160 && mousey < 100) selection = 2; + if (mousex < 160 && mousey >= 100) selection = 3; if (mousex >= 160 && mousey >= 100) selection = 4; } } diff --git a/code/REDALERT/EXTERNS.H b/code/REDALERT/EXTERNS.H index 4526440..4b91e44 100644 --- a/code/REDALERT/EXTERNS.H +++ b/code/REDALERT/EXTERNS.H @@ -91,6 +91,8 @@ extern void const *LightningShapes; extern int NewINIFormat; +extern bool renderConsole; + #ifdef FIXIT_ANTS extern bool AntsEnabled; @@ -158,6 +160,7 @@ extern PKey FastKey; extern PKey SlowKey; extern RulesClass Rule; extern KeyboardClass * Keyboard; +extern UserInputClass UserInput; extern RandomStraw CryptRandom; extern RandomClass NonCriticalRandomNumber; extern CarryoverClass * Carryover; @@ -365,6 +368,8 @@ extern GroundType Ground[LAND_COUNT]; /* ** Constant externs (data is not modified during game play). */ +extern std::map const sdl_keyMapping; + extern char const * Missions[MISSION_COUNT]; extern char const Keys[]; extern char const * const VQName[VQ_COUNT]; diff --git a/code/REDALERT/FUNCTION.H b/code/REDALERT/FUNCTION.H index 89a207a..5db6e4e 100644 --- a/code/REDALERT/FUNCTION.H +++ b/code/REDALERT/FUNCTION.H @@ -199,11 +199,10 @@ struct NoInitClass { #define TIMER_H #endif -#ifdef WIN32 #include "key.h" -#endif +#include "io/UserInput.h" -#include +#include #include "mpu.h" #include "bench.h" #include "rect.h" @@ -212,7 +211,7 @@ struct NoInitClass { #include "face.h" #include "random.h" #include "crc.h" -#include "compat.h" +#include "compat.h" #include "fixed.h" #include "base64.h" #include "pipe.h" @@ -1072,7 +1071,7 @@ extern DynamicVectorClass xxx2; template <>class DynamicVectorClass; extern DynamicVectorClass xxx3; -void WWSDL_ProcessEvents(KeyNumType& key, int& flags); +void WWSDL_ProcessEvents(KeyNumType& key, int& flags, bool presentBuffer = true); void Device_Present(void); /* diff --git a/code/REDALERT/GADGET.CPP b/code/REDALERT/GADGET.CPP index fa22be4..f4207a8 100644 --- a/code/REDALERT/GADGET.CPP +++ b/code/REDALERT/GADGET.CPP @@ -84,8 +84,6 @@ GadgetClass * GadgetClass::Focused = 0; static RemapControlType _GreyScheme = {15}; RemapControlType * GadgetClass::ColorScheme = &_GreyScheme; -int mousex, mousey; - /*********************************************************************************************** * GadgetClass::GadgetClass -- Constructor for gadget object. * * * @@ -569,7 +567,7 @@ KeyNumType GadgetClass::Input(void) if (StuckOn) { StuckOn->Draw_Me(false); GadgetClass * oldstuck = StuckOn; - StuckOn->Clicked_On(key, flags, mousex, mousey); + StuckOn->Clicked_On(key, flags, UserInput.Mouse.X, UserInput.Mouse.Y); if (StuckOn) { StuckOn->Draw_Me(false); } else { @@ -583,7 +581,7 @@ KeyNumType GadgetClass::Input(void) */ if (Focused && (flags & KEYBOARD)) { Focused->Draw_Me(false); - Focused->Clicked_On(key, flags, mousex, mousey); + Focused->Clicked_On(key, flags, UserInput.Mouse.X, UserInput.Mouse.Y); if (Focused) { Focused->Draw_Me(false); } @@ -610,7 +608,7 @@ KeyNumType GadgetClass::Input(void) ** Process this button. If the button was recognized and action was ** performed, then bail from further processing (speed reasons?). */ - if (next_button->Clicked_On(key, flags, mousex, mousey)) { + if (next_button->Clicked_On(key, flags, UserInput.Mouse.X, UserInput.Mouse.Y)) { /* ** Some buttons will require repainting when they perform some action. diff --git a/code/REDALERT/GLOBALS.CPP b/code/REDALERT/GLOBALS.CPP index ac288ad..2e9c522 100644 --- a/code/REDALERT/GLOBALS.CPP +++ b/code/REDALERT/GLOBALS.CPP @@ -252,6 +252,12 @@ CCINIClass AftermathINI; RulesClass Rule; +/*************************************************************************** +** All user input, mouse and keyboard, is routed through the object pointed to by this +** user input class pointer. +*/ +UserInputClass UserInput; + /*************************************************************************** ** All keyboard input is routed through the object pointed to by this ** keyboard class pointer. diff --git a/code/REDALERT/KEY.CPP b/code/REDALERT/KEY.CPP index 582806b..53764ca 100644 --- a/code/REDALERT/KEY.CPP +++ b/code/REDALERT/KEY.CPP @@ -51,7 +51,8 @@ * WWKeyboardClass::Put_Mouse_Message -- Stores a mouse type message into the keyboard buffer* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#include "key.h" +//#include "key.h" +#include "FUNCTION.H" #include "monoc.h" @@ -316,8 +317,9 @@ char WWKeyboardClass::To_ASCII(unsigned short key) int result = 1; int scancode = 0; - scancode = MapVirtualKey(key & 0xFF, 0); - result = ToAscii((UINT)(key & 0xFF), (UINT)scancode, (PBYTE)KeyState, (LPWORD)buffer, (UINT)0); + //scancode = MapVirtualKey(key & 0xFF, 0); + //result = ToAscii((UINT)(key & 0xFF), (UINT)scancode, (PBYTE)KeyState, (LPWORD)buffer, (UINT)0); + buffer[0] = UserInput.KeyB.ASCII; /* ** Restore the KeyState buffer back to pristine condition. diff --git a/code/REDALERT/MAPEDDLG.CPP b/code/REDALERT/MAPEDDLG.CPP index e19b0f6..7d80932 100644 --- a/code/REDALERT/MAPEDDLG.CPP +++ b/code/REDALERT/MAPEDDLG.CPP @@ -719,7 +719,6 @@ static int map_y2; // map coords y2, pixel coords bool sizemap_cancel = false; // true = user cancels bool sizemap_process = true; void Imgui_SizeMap(void) { - extern int mousex, mousey; bool toolActive = false; ImGuiStyle& style = ImGui::GetStyle(); diff --git a/code/REDALERT/MAPEDIT.CPP b/code/REDALERT/MAPEDIT.CPP index d8f7dfe..ff3c30c 100644 --- a/code/REDALERT/MAPEDIT.CPP +++ b/code/REDALERT/MAPEDIT.CPP @@ -1506,7 +1506,6 @@ int mainmenu_x = -1; int mainmenu_y = -1; void Imgui_MapEdit_MainMenu(void) { - extern int mousex, mousey; bool toolActive = false; ImGuiStyle& style = ImGui::GetStyle(); @@ -1559,15 +1558,14 @@ void Imgui_MapEdit_MainMenu(void) { *=========================================================================*/ void MapEditClass::Main_Menu(void) { - extern int mousex, mousey; int selection; // option the user picks bool process; // menu stays up while true int rc; Imgui_Dialog_Function = Imgui_MapEdit_MainMenu; mainmenu_selection = -1; - mainmenu_x = mousex; - mainmenu_y = mousey; + mainmenu_x = UserInput.Mouse.X; + mainmenu_y = UserInput.Mouse.Y; /* ** Main Menu loop diff --git a/code/REDALERT/MAPSEL.CPP b/code/REDALERT/MAPSEL.CPP index d893c50..9d1989a 100644 --- a/code/REDALERT/MAPSEL.CPP +++ b/code/REDALERT/MAPSEL.CPP @@ -326,12 +326,12 @@ int Mouse_Over_Spot(int house, int scenario) { int retval = -1; for (int selection = 0; selection < 3 && MapCoords[house][scenario][selection].x != -1; selection++) { - int mousex = Get_Mouse_X() / RESFACTOR; + int mousex = UserInput.Mouse.X / RESFACTOR; int mousey = Get_Mouse_Y() / RESFACTOR; - if (mousex >= MapCoords[house][scenario][selection].x && - mousey >= MapCoords[house][scenario][selection].y && - mousex <= MapCoords[house][scenario][selection].x+11 && - mousey <= MapCoords[house][scenario][selection].y+9) { + if (UserInput.Mouse.X >= MapCoords[house][scenario][selection].x && + UserInput.Mouse.Y >= MapCoords[house][scenario][selection].y && + UserInput.Mouse.X <= MapCoords[house][scenario][selection].x+11 && + UserInput.Mouse.Y <= MapCoords[house][scenario][selection].y+9) { retval = selection; break; diff --git a/code/REDALERT/MENUS.CPP b/code/REDALERT/MENUS.CPP index d7b0e28..ccdcd9c 100644 --- a/code/REDALERT/MENUS.CPP +++ b/code/REDALERT/MENUS.CPP @@ -267,8 +267,8 @@ int Check_Menu(int menu, char const * text[], char *, long field, int index, Key mx2=mx1+(menuptr[ITEMWIDTH]*FontWidth)-1; /* structure as */ my2=my1+(menuptr[ITEMSHIGH]*menuskip)-1; /* necessary */ - tempy=Get_Mouse_Y(); - if (Coordinates_In_Region(Get_Mouse_X(), tempy, mx1, my1, mx2, my2)&& MenuUpdate) { + tempy=UserInput.Mouse.Y; + if (Coordinates_In_Region(UserInput.Mouse.X, tempy, mx1, my1, mx2, my2)&& MenuUpdate) { newitem=(tempy-my1)/menuskip; } @@ -299,8 +299,8 @@ int Check_Menu(int menu, char const * text[], char *, long field, int index, Key */ case KN_RMOUSE: case KN_LMOUSE: - if (Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY, mx1, my1, mx2, my2)) { - newitem = (Keyboard->MouseQY - my1) / menuskip; + if (Coordinates_In_Region(UserInput.Mouse.X, UserInput.Mouse.Y, mx1, my1, mx2, my2)) { + newitem = (UserInput.Mouse.Y - my1) / menuskip; } else { UnknownKey = key; // Pass the unprocessed button click back. break; @@ -772,7 +772,7 @@ int Main_Menu(unsigned long ) case KN_LMOUSE: - if (Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY, + if (Coordinates_In_Region(UserInput.Mouse.X, UserInput.Mouse.Y, 9*RESFACTOR, 10*RESFACTOR, 79*RESFACTOR, 24*RESFACTOR)){ @@ -786,7 +786,7 @@ int Main_Menu(unsigned long ) // secret ANT missions if (Is_Counterstrike_Installed() == true) { - if ((Keyboard->Down(KN_LSHIFT) || Keyboard->Down(KN_RSHIFT)) && Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY, 260*RESFACTOR, 0, 320*RESFACTOR, 50*RESFACTOR)) { + if ((Keyboard->Down(KN_LSHIFT) || Keyboard->Down(KN_RSHIFT)) && Coordinates_In_Region(UserInput.Mouse.X, UserInput.Mouse.Y, 260*RESFACTOR, 0, 320*RESFACTOR, 50*RESFACTOR)) { AntsEnabled = true; process = false; retval = 2; // To match SEL_START_NEW_GAME diff --git a/code/REDALERT/TECHNO.CPP b/code/REDALERT/TECHNO.CPP index 2a9e3c8..5700235 100644 --- a/code/REDALERT/TECHNO.CPP +++ b/code/REDALERT/TECHNO.CPP @@ -138,11 +138,6 @@ */ #define MAX_UNCLOAK_STAGE 38 -//Added for getting the input for special character keys from the client -// - 6/26/2019 JAS -extern bool DLL_Export_Get_Input_Key_State(KeyNumType key); - - /*************************************************************************** ** These are the pointers to the special shape data that the units may need. */ @@ -3523,14 +3518,9 @@ ActionType TechnoClass::What_Action(ObjectClass const * object) const return(ACTION_SELF); } - //bool altdown = (Keyboard->Down(Options.KeyForceMove1) || Keyboard->Down(Options.KeyForceMove2)); - //bool ctrldown = (Keyboard->Down(Options.KeyForceAttack1) || Keyboard->Down(Options.KeyForceAttack2)); - //bool shiftdown = (Keyboard->Down(Options.KeySelect1) || Keyboard->Down(Options.KeySelect2)); - //Added for getting the input for special character keys from the client - // - 6/26/2019 JAS - bool altdown = DLL_Export_Get_Input_Key_State(KN_LALT); - bool ctrldown = DLL_Export_Get_Input_Key_State(KN_LCTRL); - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); + bool altdown = (Keyboard->Down(Options.KeyForceMove1) || Keyboard->Down(Options.KeyForceMove2)); + bool ctrldown = (Keyboard->Down(Options.KeyForceAttack1) || Keyboard->Down(Options.KeyForceAttack2)); + bool shiftdown = (Keyboard->Down(Options.KeySelect1) || Keyboard->Down(Options.KeySelect2)); /* ** Special guard area mission is possible if both the control and the @@ -3646,14 +3636,9 @@ ActionType TechnoClass::What_Action(CELL cell) const CellClass const * cellptr = &Map[cell]; OverlayTypeClass const * optr = NULL; - //bool altdown = (Keyboard->Down(Options.KeyForceMove1) || Keyboard->Down(Options.KeyForceMove2)); - //bool ctrldown = (Keyboard->Down(Options.KeyForceAttack1) || Keyboard->Down(Options.KeyForceAttack2)); - //bool shiftdown = (Keyboard->Down(Options.KeySelect1) || Keyboard->Down(Options.KeySelect2)); - //Added for getting the input for special character keys from the client - // - 6/26/2019 JAS - bool altdown = DLL_Export_Get_Input_Key_State(KN_LALT); - bool ctrldown = DLL_Export_Get_Input_Key_State(KN_LCTRL); - bool shiftdown = DLL_Export_Get_Input_Key_State(KN_LSHIFT); + bool altdown = (Keyboard->Down(Options.KeyForceMove1) || Keyboard->Down(Options.KeyForceMove2)); + bool ctrldown = (Keyboard->Down(Options.KeyForceAttack1) || Keyboard->Down(Options.KeyForceAttack2)); + bool shiftdown = (Keyboard->Down(Options.KeySelect1) || Keyboard->Down(Options.KeySelect2)); /* ** Disable recognizing the key forced fire option when dealing with buildings. diff --git a/code/REDALERT/WIN32LIB/MOUSEWW.CPP b/code/REDALERT/WIN32LIB/MOUSEWW.CPP index 5bf3f2a..dcefb52 100644 --- a/code/REDALERT/WIN32LIB/MOUSEWW.CPP +++ b/code/REDALERT/WIN32LIB/MOUSEWW.CPP @@ -31,15 +31,15 @@ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "imgui.h" -#include "mouse.h" +#include "../FUNCTION.H" +#include "MOUSE.H" #include "../image.h" -#include static WWMouseClass *_Mouse=NULL; void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 ); -extern bool GameInFocus; -extern int mousex, mousey; +extern bool GameInFocus; +extern UserInputClass UserInput; /*********************************************************************************************** * MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class * @@ -241,8 +241,8 @@ void WWMouseClass::RenderMouse(void) { //ImVec2 size(current_cursor->width, current_cursor->height); //ImGui::Image((ImTextureID)current_cursor->image, size); - int _my = mousey + (current_cursor->height * 0.25); - int xstart = mousex - Get_Hotspot_X(); + int _my = UserInput.Mouse.Y + (current_cursor->height * 0.25); + int xstart = UserInput.Mouse.X - Get_Hotspot_X(); int ystart = _my - Get_Hotspot_Y(); int yend = current_cursor->height + ystart - 1; int xend = current_cursor->width + xstart - 1; @@ -483,7 +483,7 @@ int WWMouseClass::Get_Mouse_State(void) *=============================================================================================*/ int WWMouseClass::Get_Mouse_X(void) { - return mousex; + return UserInput.Mouse.X; } @@ -499,7 +499,7 @@ int WWMouseClass::Get_Mouse_X(void) *=============================================================================================*/ int WWMouseClass::Get_Mouse_Y(void) { - return mousey; + return UserInput.Mouse.Y; } /*********************************************************************************************** @@ -515,8 +515,8 @@ int WWMouseClass::Get_Mouse_Y(void) *=============================================================================================*/ void WWMouseClass::Get_Mouse_XY(int &x, int &y) { - x = mousex; - y = mousey; + x = UserInput.Mouse.X; + y = UserInput.Mouse.Y; } //#pragma off(unreferenced) @@ -575,14 +575,13 @@ void *Set_Mouse_Cursor(int hotx, int hoty, int cursor) extern int DLLForceMouseX; extern int DLLForceMouseY; -extern int mousex, mousey; int Get_Mouse_X(void) { - return mousex; + return UserInput.Mouse.X; } int Get_Mouse_Y(void) { - return mousey; + return UserInput.Mouse.Y; } \ No newline at end of file diff --git a/code/REDALERT/WINSTUB.CPP b/code/REDALERT/WINSTUB.CPP index 87fd8a2..4e60f57 100644 --- a/code/REDALERT/WINSTUB.CPP +++ b/code/REDALERT/WINSTUB.CPP @@ -88,16 +88,6 @@ void Show_OldFrameBuffer(bool show) { std::vector loaded_images; -auto utf8_decode = [](const std::string& str) -> std::wstring -{ - if (str.empty()) return std::wstring(); - int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); - std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); - return wstrTo; -}; - - Image_t* Image_LoadImage(const char* name) { // Check to see if the image is already loaded. for (int i = 0; i < loaded_images.size(); i++) { @@ -677,133 +667,8 @@ void __cdecl SetPalette(unsigned char *palette, long, unsigned long) } -void WWSDL_ProcessEvents(KeyNumType& key, int& flags) { - static int numFramesLMouse = 0; - extern int mousex, mousey; - bool leftMouseProcessed = false; - - SDL_GetMouseState(&mousex, &mousey); - - Keyboard->MouseQX = mousex; - Keyboard->MouseQY = mousey; - - // if (flags == LEFTRELEASE || flags == RIGHTRELEASE) - // flags = 0; - - SDL_Event event; - - while (SDL_PollEvent(&event)) { - const Uint8* state = SDL_GetKeyboardState(NULL); - - switch (event.type) - { - case SDL_SYSWMEVENT: - if ( event.syswm.msg->msg.win.msg == WM_DESTROY ) - { - Invalidate_Cached_Icons(); - VisiblePage.Un_Init(); - HiddenPage.Un_Init(); - AllSurfaces.Release(); - if (!InDebugger) Reset_Video_Mode(); - - /* - ** If we are shutting down gracefully than flag that the message loop has finished. - ** If this is a forced shutdown (ReadyToQuit == 0) then try and close down everything - ** before we exit. - */ - PostQuitMessage(0); - - switch (ReadyToQuit) { - case 1: - ReadyToQuit = 2; - break; - case 0: - ExitProcess(0); - break; - } - } - - break; - - case SDL_MOUSEMOTION: - flags = GadgetClass::LEFTUP; - break; - - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT) { - flags = GadgetClass::LEFTPRESS; - leftMouseProcessed = true; - numFramesLMouse++; - key = KN_LMOUSE; - } - else if (event.button.button == SDL_BUTTON_RIGHT) { - numFramesLMouse = 0; - flags = GadgetClass::RIGHTPRESS; - key = KN_RMOUSE; - } - break; - - case SDL_MOUSEBUTTONUP: - if (event.button.button == SDL_BUTTON_LEFT) { - flags = GadgetClass::LEFTRELEASE; - numFramesLMouse = 0; - } - else if (event.button.button == SDL_BUTTON_RIGHT) { - flags = GadgetClass::RIGHTRELEASE; - numFramesLMouse = 0; - } - break; - - case SDL_KEYDOWN: - if (event.key.keysym.scancode == SDL_SCANCODE_GRAVE) { - renderConsole = !renderConsole; - - if (renderConsole) { - ShowCursor(TRUE); - Hide_Mouse(); - } - else { - ShowCursor(FALSE); - Show_Mouse(); - } - break; - } - - // handle backspace and ENTER - if (event.key.keysym.scancode == SDL_SCANCODE_BACKSPACE) Keyboard->Put_Element( KN_BACKSPACE ); - if (event.key.keysym.scancode == ( SDL_SCANCODE_RETURN || SDL_SCANCODE_KP_ENTER ) ) Keyboard->Put_Element( KN_RETURN ); - - break; - case SDL_TEXTINPUT: - int keyFlags = 0x00; - - if (state[SDL_SCANCODE_RSHIFT] || state[SDL_SCANCODE_LSHIFT]) keyFlags |= KN_SHIFT_BIT; - if (state[SDL_SCANCODE_RALT] || state[SDL_SCANCODE_LALT]) keyFlags |= KN_ALT_BIT; - - std::wstring input_utf16 = utf8_decode( std::string( event.text.text ) ); - - if( input_utf16.length() == 1 ) - { - short vKey = VkKeyScanW( input_utf16[0] ); - Keyboard->Put_Element( vKey | keyFlags ); - } - - break; - } - - if (Debug_Map || renderConsole) - { - ImGui_ImplSDL2_ProcessEvent(&event); - } - - } - - if (!leftMouseProcessed && numFramesLMouse != 0) - { - flags = GadgetClass::LEFTHELD; - } - - Device_Present(); +void WWSDL_ProcessEvents(KeyNumType& key, int& flags, bool presentBuffer) { + UserInput.Process_Input(key, flags, presentBuffer); } #ifndef NDEBUG diff --git a/code/REDALERT/io/UserInput.cpp b/code/REDALERT/io/UserInput.cpp new file mode 100644 index 0000000..669291d --- /dev/null +++ b/code/REDALERT/io/UserInput.cpp @@ -0,0 +1,149 @@ +#include "../FUNCTION.H" +#include "UserInput.h" + +extern KeyboardClass * Keyboard; + +/* +auto utf8_decode = [](const std::string& str) -> std::wstring +{ + if (str.empty()) return std::wstring(); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); + return wstrTo; +}; +*/ + +void UserInputClass::Process_Input(KeyNumType& key, int& flags, bool presentBuffer) +{ + bool leftMouseProcessed = false; + + SDL_GetMouseState(&Mouse.X, &Mouse.Y); + + Keyboard->MouseQX = Mouse.X; + Keyboard->MouseQY = Mouse.Y; + + static SDL_Event event; + memset(&event, 0, sizeof(SDL_Event)); + + while (SDL_PollEvent(&event)) { + const Uint8* state = SDL_GetKeyboardState(NULL); + + switch (event.type) + { + case SDL_SYSWMEVENT: + if (event.syswm.msg->msg.win.msg == WM_DESTROY) + { + Invalidate_Cached_Icons(); + VisiblePage.Un_Init(); + HiddenPage.Un_Init(); + AllSurfaces.Release(); + if (!InDebugger) Reset_Video_Mode(); + + PostQuitMessage(0); + + switch (ReadyToQuit) { + case 1: + ReadyToQuit = 2; + break; + case 0: + ExitProcess(0); + break; + } + } + + break; + + case SDL_MOUSEMOTION: + flags = GadgetClass::LEFTUP; + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) { + Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_DOWN; + + flags = GadgetClass::LEFTPRESS; + leftMouseProcessed = true; + numFramesLMouse++; + key = KN_LMOUSE; + } + else if (event.button.button == SDL_BUTTON_RIGHT) { + Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_DOWN; + + numFramesLMouse = 0; + flags = GadgetClass::RIGHTPRESS; + key = KN_RMOUSE; + } + break; + + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) { + Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_RELEASE; + + flags = GadgetClass::LEFTRELEASE; + numFramesLMouse = 0; + } + else if (event.button.button == SDL_BUTTON_RIGHT) { + Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_RELEASE; + + flags = GadgetClass::RIGHTRELEASE; + numFramesLMouse = 0; + } + break; + + case SDL_KEYDOWN: + { + if (event.key.keysym.scancode == SDL_SCANCODE_GRAVE) { + renderConsole = !renderConsole; + + if (renderConsole) { + ShowCursor(TRUE); + Hide_Mouse(); + } + else { + ShowCursor(FALSE); + Show_Mouse(); + } + break; + } + + int keyFlags = 0x00; + if (state[SDL_SCANCODE_RSHIFT] || state[SDL_SCANCODE_LSHIFT]) keyFlags |= KN_SHIFT_BIT; + if (state[SDL_SCANCODE_RALT] || state[SDL_SCANCODE_LALT]) keyFlags |= KN_ALT_BIT; + if (state[SDL_SCANCODE_RCTRL] || state[SDL_SCANCODE_LCTRL]) keyFlags |= KN_CTRL_BIT; + + // 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()) + { + Keyboard->Put_Element(element->second | keyFlags); + KeyB.ASCII = element->second; + } + + break; + } + case SDL_TEXTINPUT: + // limit to range 0-255 + if (event.text.text[0] == ( event.text.text[0] & 0xFF ) ) + { + KeyB.ASCII = (char)event.text.text[0]; + } + } + + if (Debug_Map || renderConsole) + { + ImGui_ImplSDL2_ProcessEvent(&event); + } + } + + if (!leftMouseProcessed && numFramesLMouse != 0) + { + Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_HOLD; + flags = GadgetClass::LEFTHELD; + } + + if (presentBuffer) + { + Device_Present(); + } +} \ No newline at end of file diff --git a/code/REDALERT/io/UserInput.h b/code/REDALERT/io/UserInput.h new file mode 100644 index 0000000..5955353 --- /dev/null +++ b/code/REDALERT/io/UserInput.h @@ -0,0 +1,144 @@ +#ifndef USERINPUT_H +#define USERINPUT_H + +#include +#include +#include + +#include "examples/imgui_impl_sdl.h" + +// Mapping of SDL KeyCode values to internal KeyNumType +std::map const sdl_keyMapping = { + { SDLK_a, KN_A }, + { SDLK_b, KN_B }, + { SDLK_c, KN_C }, + { SDLK_d, KN_D }, + { SDLK_e, KN_E }, + { SDLK_f, KN_F }, + { SDLK_g, KN_G }, + { SDLK_h, KN_H }, + { SDLK_i, KN_I }, + { SDLK_j, KN_J }, + { SDLK_k, KN_K }, + { SDLK_l, KN_N }, + { SDLK_m, KN_M }, + { SDLK_n, KN_N }, + { SDLK_o, KN_O }, + { SDLK_p, KN_P }, + { SDLK_q, KN_Q }, + { SDLK_r, KN_R }, + { SDLK_s, KN_S }, + { SDLK_t, KN_T }, + { SDLK_u, KN_U }, + { SDLK_v, KN_V }, + { SDLK_w, KN_W }, + { SDLK_x, KN_X }, + { SDLK_y, KN_Y }, + { SDLK_z, KN_Z }, + + { SDLK_0, KN_0 }, + { SDLK_1, KN_1 }, + { SDLK_2, KN_2 }, + { SDLK_3, KN_3 }, + { SDLK_4, KN_4 }, + { SDLK_5, KN_5 }, + { SDLK_6, KN_6 }, + { SDLK_7, KN_7 }, + { SDLK_8, KN_8 }, + { SDLK_9, KN_9 }, + + { SDLK_KP_MULTIPLY, KN_KEYPAD_ASTERISK }, + { SDLK_KP_DIVIDE, KN_KEYPAD_SLASH }, + { SDLK_MINUS, KN_MINUS }, + { SDLK_EQUALS, KN_EQUAL }, + + { SDLK_RIGHTBRACKET, KN_RBRACKET }, + { SDLK_LEFTBRACKET, KN_LBRACKET }, + { SDLK_SEMICOLON, KN_SEMICOLON }, + { SDLK_COMMA, KN_COMMA }, + { SDLK_PERIOD, KN_PERIOD }, + { SDLK_SLASH, KN_SLASH }, + { SDLK_BACKSLASH, KN_BACKSLASH }, + + { SDLK_F1, KN_F1 }, + { SDLK_F2, KN_F2 }, + { SDLK_F3, KN_F3 }, + { SDLK_F4, KN_F4 }, + { SDLK_F5, KN_F5 }, + { SDLK_F6, KN_F6 }, + { SDLK_F7, KN_F7 }, + { SDLK_F8, KN_F8 }, + { SDLK_F9, KN_F9 }, + { SDLK_F10, KN_F10 }, + { SDLK_F11, KN_F12 }, + { SDLK_F12, KN_F12 }, + + { SDLK_BACKSPACE, KN_BACKSPACE }, + { SDLK_KP_ENTER, KN_RETURN }, + { SDLK_RETURN, KN_RETURN }, + { SDLK_ESCAPE, KN_ESC }, +}; + +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; + + void UserInputClass::Process_Input(KeyNumType& key, int& flags, bool presentBuffer = true); + + InputAction LastAction; + + class KeyboardState { + public: + SDL_KeyCode LastKey; + char ASCII; + + bool Shift; + bool Control; + bool Alt; + + void ResetState() { + this->Shift = false; + this->Control = false; + this->Alt = false; + + LastKey = SDLK_UNKNOWN; + ASCII = 0x0; + } + }; + + KeyboardState KeyB; + + class MouseState { + public: + int X; + int Y; + + MouseButtonState Button_Left; + MouseButtonState Button_Middle; + MouseButtonState Button_Right; + + void ResetState() { + this->Button_Left = MouseButtonState::MOUSE_BUTTON_UP; + this->Button_Middle = MouseButtonState::MOUSE_BUTTON_UP; + this->Button_Right = MouseButtonState::MOUSE_BUTTON_UP; + } + }; + + MouseState Mouse; + private: + int numFramesLMouse = 0; +}; + +#endif \ No newline at end of file