diff --git a/gzdoom.vcproj b/gzdoom.vcproj index a2d74253..54882509 100644 --- a/gzdoom.vcproj +++ b/gzdoom.vcproj @@ -1973,6 +1973,10 @@ RelativePath=".\src\win32\i_input.h" > + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54e6e0fe..bf85c9d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -414,6 +414,7 @@ if( WIN32 ) win32/i_cd.cpp win32/i_crash.cpp win32/i_input.cpp + win32/i_keyboard.cpp win32/i_mouse.cpp win32/i_main.cpp win32/i_movie.cpp diff --git a/src/c_bind.cpp b/src/c_bind.cpp index a6d8488e..b2912e1a 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -191,14 +191,14 @@ const char *KeyNames[NUM_KEYS] = NULL, NULL, NULL, NULL, NULL, NULL, "voldown", NULL, //A8 "volup", NULL, "webhome", "kp,", NULL, "kp/", NULL, "sysrq", //B0 "ralt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //B8 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, "home", //C0 + NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0 "uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8 "downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0 NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8 NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0 "webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, "pause", //F8 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F8 // non-keyboard buttons that can be bound "mouse1", "mouse2", "mouse3", "mouse4", // 8 mouse buttons diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index e9924785..5403141e 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -352,7 +352,7 @@ const char *myasctime () /* */ /************************************************************************/ #ifdef _WIN32 -void DoCreatePath(const char * fn) +void DoCreatePath(const char *fn) { char drive[_MAX_DRIVE]; char path[PATH_MAX]; @@ -367,17 +367,20 @@ void DoCreatePath(const char * fn) _mkdir(p); } -void CreatePath(const char * fn) +void CreatePath(const char *fn) { - char name[PATH_MAX]; char c = fn[strlen(fn)-1]; - if (c!='\\' && c!='/') + if (c != '\\' && c != '/') { - mysnprintf(name, countof(name), "%s/", fn); + FString name(fn); + name += '/'; DoCreatePath(name); } - else DoCreatePath(fn); + else + { + DoCreatePath(fn); + } } #else void CreatePath(const char *fn) diff --git a/src/d_main.cpp b/src/d_main.cpp index 8ff94da8..ddf7c1a7 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -783,7 +783,10 @@ void D_ErrorCleanup () playeringame[0] = 1; players[0].playerstate = PST_LIVE; gameaction = ga_fullconsole; - menuactive = MENU_Off; + if (gamestate == GS_DEMOSCREEN) + { + menuactive = MENU_Off; + } insave = false; } diff --git a/src/doomdef.h b/src/doomdef.h index 008adee9..bc48a78a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -104,6 +104,7 @@ enum ESkillLevels // DOOM keyboard definition. Everything below 0x100 matches // a DirectInput key code. // +#define KEY_PAUSE 0xc5 // DIK_PAUSE #define KEY_RIGHTARROW 0xcd // DIK_RIGHT #define KEY_LEFTARROW 0xcb // DIK_LEFT #define KEY_UPARROW 0xc8 // DIK_UP @@ -126,7 +127,6 @@ enum ESkillLevels #define KEY_F12 0x58 // DIK_F12 #define KEY_BACKSPACE 0x0e // DIK_BACK -#define KEY_PAUSE 0xff #define KEY_EQUALS 0x0d // DIK_EQUALS #define KEY_MINUS 0x0c // DIK_MINUS diff --git a/src/g_game.cpp b/src/g_game.cpp index 2f37e292..b139fa1f 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1777,24 +1777,27 @@ FString G_BuildSaveName (const char *prefix, int slot) { leader = save_dir; } +#ifdef unix + if (leader.IsEmpty()) + { + leader = "~" GAME_DIR; + } +#endif } size_t len = leader.Len(); if (leader[0] != '\0' && leader[len-1] != '\\' && leader[len-1] != '/') { slash = "/"; } - name.Format("%s%s%s", leader.GetChars(), slash, prefix); + name << leader << slash; + name = NicePath(name); + CreatePath(name); + name << prefix; if (slot >= 0) { name.AppendFormat("%d.zds", slot); } -#ifdef unix - if (leader[0] == 0) - { - return GetUserFile (name); - } -#endif - return NicePath(name); + return name; } CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -1911,7 +1914,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio insave = true; G_SnapshotLevel (); - FILE *stdfile = fopen (filename.GetChars(), "wb"); + FILE *stdfile = fopen (filename, "wb"); if (stdfile == NULL) { diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index f72e6a47..5140d54a 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1707,6 +1707,41 @@ void APowerHighJump::EndEffect( ) } } +// Double firing speed rune --------------------------------------------- + +IMPLEMENT_CLASS(APowerDoubleFiringSpeed) + +//=========================================================================== +// +// APowerDoubleFiringSpeed :: InitEffect +// +//=========================================================================== + +void APowerDoubleFiringSpeed::InitEffect( ) +{ + if (Owner== NULL || Owner->player == NULL) + return; + + // Give the player the power to shoot twice as fast. + Owner->player->cheats |= CF_DOUBLEFIRINGSPEED; +} + +//=========================================================================== +// +// APowerDoubleFiringSpeed :: EndEffect +// +//=========================================================================== + +void APowerDoubleFiringSpeed::EndEffect( ) +{ + // Nothing to do if there's no owner. + if (Owner != NULL && Owner->player != NULL) + { + // Take away the shooting twice as fast power. + Owner->player->cheats &= ~CF_DOUBLEFIRINGSPEED; + } +} + // Morph powerup ------------------------------------------------------ IMPLEMENT_CLASS(APowerMorph) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 187ed056..adbe991a 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -245,6 +245,14 @@ protected: void EndEffect( ); }; +class APowerDoubleFiringSpeed : public APowerup +{ + DECLARE_CLASS( APowerDoubleFiringSpeed, APowerup ) +protected: + void InitEffect( ); + void EndEffect( ); +}; + class APowerMorph : public APowerup { DECLARE_CLASS( APowerMorph, APowerup ) diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index c141d547..c9d2b47f 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -1610,11 +1610,12 @@ void DSBarInfo::DrawString(const char* str, SBarInfoCoordinate x, SBarInfoCoordi void DSBarInfo::DrawNumber(int num, int len, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool fillzeros, bool drawshadow) { FString value; - int maxval = (int) ceil(pow(10., len))-1; + // 10^9 is a largest we can hold in a 32-bit int. So if we go any larger we have to toss out the positions limit. + int maxval = len <= 9 ? (int) ceil(pow(10., len))-1 : INT_MAX; if(!fillzeros || len == 1) num = clamp(num, -maxval, maxval); else //The community wanted negatives to take the last digit, but we can only do this if there is room - num = clamp(num, (int) -(ceil(pow(10., len-1))-1), maxval); + num = clamp(num, len <= 9 ? (int) -(ceil(pow(10., len-1))-1) : INT_MIN, maxval); value.Format("%d", num); if(fillzeros) { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 1401cd33..8df4cb1e 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -391,20 +391,24 @@ void cht_DoCheat (player_t *player, int cheat) { return; } - // Take away all weapons that are either non-wimpy or use ammo. - for (item = player->mo->Inventory; item != NULL; ) { - AInventory *next = item->Inventory; - if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) + // Take away all weapons that are either non-wimpy or use ammo. + AInventory **invp = &player->mo->Inventory, **lastinvp; + for (item = *invp; item != NULL; item = *invp) { - AWeapon *weap = static_cast (item); - if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || - weap->AmmoType1 != NULL) + lastinvp = invp; + invp = &(*invp)->Inventory; + if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) { - item->Destroy (); + AWeapon *weap = static_cast (item); + if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || + weap->AmmoType1 != NULL) + { + item->Destroy (); + invp = lastinvp; + } } } - item = next; } msg = GStrings("TXT_CHEATIDKFA"); break; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 16787cac..539f0553 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -875,7 +875,7 @@ void P_AutoUseStrifeHealth (player_t *player) void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags) { unsigned ang; - player_t *player; + player_t *player = NULL; fixed_t thrust; int temp; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 70ee7bcb..5ce3f17f 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -772,6 +772,11 @@ void P_MovePsprites (player_t *player) if (psp->tics != -1) // a -1 tic count never changes { psp->tics--; + + // [BC] Apply double firing speed. + if ( psp->tics && ( player->cheats & CF_DOUBLEFIRINGSPEED )) + psp->tics--; + if(!psp->tics) { P_SetPsprite (player, i, psp->state->GetNextState()); diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index b42c0385..ab27dfde 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -21,7 +21,8 @@ static void I_CheckGUICapture (); static void I_CheckNativeMouse (); -bool GUICapture; +static bool GUICapture; +static bool NativeMouse = true; extern int paused; diff --git a/src/svnrevision.h b/src/svnrevision.h index 71995839..bcb806b0 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "1602" -#define ZD_SVN_REVISION_NUMBER 1602 +#define ZD_SVN_REVISION_STRING "1616" +#define ZD_SVN_REVISION_NUMBER 1616 diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 1cf31ff8..e3273fd1 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -60,9 +60,6 @@ #endif // Compensate for w32api's lack -#ifndef GET_XBUTTON_WPARAM -#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) -#endif #ifndef WM_WTSSESSION_CHANGE #define WM_WTSSESSION_CHANGE 0x02B1 #define WTS_CONSOLE_CONNECT 1 @@ -70,9 +67,6 @@ #define WTS_SESSION_LOCK 7 #define WTS_SESSION_UNLOCK 8 #endif -#ifndef SetClassLongPtr -#define SetClassLongPtr SetClassLong -#endif #ifndef PBT_APMSUSPEND // w32api does not #define the PBT_ macros in winuser.h like the PSDK does #include @@ -130,12 +124,11 @@ extern bool SpawnEAXWindow; static HMODULE DInputDLL; -static void KeyRead (); -static BOOL I_StartupKeyboard (); static HRESULT InitJoystick (); bool GUICapture; extern FMouse *Mouse; +extern FKeyboard *Keyboard; bool VidResizing; @@ -152,7 +145,6 @@ EXTERN_CVAR (Bool, lookstrafe) extern BOOL paused; -bool HaveFocus; static bool noidle = false; LPDIRECTINPUT8 g_pdi; @@ -160,13 +152,6 @@ LPDIRECTINPUT g_pdi3; static LPDIRECTINPUTDEVICE8 g_pJoy; -// These can also be earlier IDirectInputDevice interfaces. -// Since IDirectInputDevice8 just added new methods to it -// without rearranging the old ones, I just maintain one -// pointer for each device instead of two. - -static LPDIRECTINPUTDEVICE8 g_pKey; - TArray JoystickNames; static DIDEVCAPS JoystickCaps; @@ -300,8 +285,6 @@ CVAR (Float, joy_forwardspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_sidespeed, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_upspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -// set this to false to make keypad-enter a usable separate key! -CVAR (Bool, k_mergekeys, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) static FBaseCVar * const JoyConfigVars[] = @@ -313,51 +296,6 @@ static FBaseCVar * const JoyConfigVars[] = }; static BYTE KeyState[256]; -static BYTE DIKState[2][NUM_KEYS]; -static int KeysReadCount; -static int ActiveDIKState; - -// Convert DIK_* code to ASCII using Qwerty keymap -static const BYTE Convert [256] = -{ - // 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 9, // 0 - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, 0, 'a', 's', // 1 - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', 0,'\\', 'z', 'x', 'c', 'v', // 2 - 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, // 3 - 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', // 4 - '2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '=', 0, 0, // 8 - 0, '@', ':', '_', 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, // 9 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A - 0, 0, 0, ',', 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C - 0, 0, 0, 0, 0, 0, 0, 0 - -}; - -static void FlushDIKState (int low=0, int high=NUM_KEYS-1) -{ - int i; - event_t event; - BYTE *state = DIKState[ActiveDIKState]; - - memset (&event, 0, sizeof(event)); - event.type = EV_KeyUp; - for (i = low; i <= high; ++i) - { - if (state[i]) - { - state[i] = 0; - event.data1 = i; - event.data2 = i < 256 ? Convert[i] : 0; - D_PostEvent (&event); - } - } -} extern int chatmodeon; @@ -377,23 +315,34 @@ static void I_CheckGUICapture () if (wantCapt != GUICapture) { GUICapture = wantCapt; - if (wantCapt) + if (wantCapt && Keyboard != NULL) { - FlushDIKState (); + Keyboard->AllKeysUp(); } } } +bool CallHook(FInputDevice *device, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) +{ + if (device == NULL) + { + return false; + } + *result = 0; + return device->WndProcHook(hWnd, message, wParam, lParam, result); +} + LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (Mouse != NULL) - { - LRESULT result = 0; + LRESULT result; - if (Mouse->WndProcHook(hWnd, message, wParam, lParam, &result)) - { - return result; - } + if (CallHook(Keyboard, hWnd, message, wParam, lParam, &result)) + { + return result; + } + if (CallHook(Mouse, hWnd, message, wParam, lParam, &result)) + { + return result; } event_t event; @@ -410,8 +359,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_HOTKEY: break; - case WM_INPUT: - case WM_PAINT: if (screen != NULL && 0) { @@ -428,19 +375,10 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_KILLFOCUS: - if (g_pKey) g_pKey->Unacquire (); - - FlushDIKState (); - HaveFocus = false; I_CheckNativeMouse (true); // Make sure mouse gets released right away break; case WM_SETFOCUS: - if (g_pKey) - { - g_pKey->Acquire(); - } - HaveFocus = true; I_CheckNativeMouse (false); break; @@ -514,43 +452,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } } } - else - { - if (message == WM_KEYUP) - { - event.type = EV_KeyUp; - } - else - { - if (lParam & 0x40000000) - { - return 0; - } - else - { - event.type = EV_KeyDown; - } - } - - switch (wParam) - { - case VK_PAUSE: - event.data1 = KEY_PAUSE; - break; - case VK_TAB: - event.data1 = DIK_TAB; - event.data2 = '\t'; - break; - case VK_NUMLOCK: - event.data1 = DIK_NUMLOCK; - break; - } - if (event.data1) - { - DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown); - D_PostEvent (&event); - } - } break; case WM_CHAR: @@ -1254,11 +1155,9 @@ bool I_InitInput (void *hwnd) // Free all input resources void I_ShutdownInput () { - if (g_pKey) + if (Keyboard != NULL) { - g_pKey->Unacquire (); - g_pKey->Release (); - g_pKey = NULL; + delete Keyboard; } if (Mouse != NULL) { @@ -1287,120 +1186,6 @@ void I_ShutdownInput () } } -// Initialize the keyboard -static BOOL I_StartupKeyboard (void) -{ - HRESULT hr; - - // Obtain an interface to the system key device. - if (g_pdi3) - { - hr = g_pdi3->CreateDevice (GUID_SysKeyboard, (LPDIRECTINPUTDEVICE*)&g_pKey, NULL); - } - else - { - hr = g_pdi->CreateDevice (GUID_SysKeyboard, &g_pKey, NULL); - } - - if (FAILED(hr)) - { - I_FatalError ("Could not create keyboard device"); - } - - // Set the data format to "keyboard format". - hr = g_pKey->SetDataFormat (&c_dfDIKeyboard); - - if (FAILED(hr)) - { - I_FatalError ("Could not set keyboard data format"); - } - - // Set the cooperative level. - hr = g_pKey->SetCooperativeLevel (Window, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE); - - if (FAILED(hr)) - { - I_FatalError("Could not set keyboard cooperative level"); - } - - g_pKey->Acquire (); - return TRUE; -} - -static void KeyRead () -{ - HRESULT hr; - event_t event; - BYTE *fromState, *toState; - int i; - - if (g_pKey == NULL) - { - return; - } - - memset (&event, 0, sizeof(event)); - fromState = DIKState[ActiveDIKState]; - toState = DIKState[ActiveDIKState ^ 1]; - - hr = g_pKey->GetDeviceState (256, toState); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - hr = g_pKey->Acquire (); - if (hr != DI_OK) - { - return; - } - hr = g_pKey->GetDeviceState (256, toState); - } - if (hr != DI_OK) - { - return; - } - - // Successfully got the buffer - KeysReadCount++; - ActiveDIKState ^= 1; - - // Copy key states not handled here from the old to the new buffer - memcpy (toState + 256, fromState + 256, NUM_KEYS - 256); - toState[DIK_TAB] = fromState[DIK_TAB]; - toState[DIK_NUMLOCK] = fromState[DIK_NUMLOCK]; - - if (k_mergekeys) - { - // "Merge" multiple keys that are considered to be the same. - // Also clear out the alternate versions after merging. - toState[DIK_RETURN] |= toState[DIK_NUMPADENTER]; - toState[DIK_LMENU] |= toState[DIK_RMENU]; - toState[DIK_LCONTROL] |= toState[DIK_RCONTROL]; - toState[DIK_LSHIFT] |= toState[DIK_RSHIFT]; - - toState[DIK_NUMPADENTER] = 0; - toState[DIK_RMENU] = 0; - toState[DIK_RCONTROL] = 0; - toState[DIK_RSHIFT] = 0; - } - - // Now generate events for any keys that differ between the states - if (!GUICapture) - { - for (i = 1; i < 256; i++) - { - if (toState[i] != fromState[i]) - { - event.type = toState[i] ? EV_KeyDown : EV_KeyUp; - event.data1 = i; - event.data2 = Convert[i]; - event.data3 = (toState[DIK_LSHIFT] ? GKM_SHIFT : 0) | - (toState[DIK_LCONTROL] ? GKM_CTRL : 0) | - (toState[DIK_LMENU] ? GKM_ALT : 0); - D_PostEvent (&event); - } - } - } -} - void I_GetEvent () { MSG mess; @@ -1420,8 +1205,10 @@ void I_GetEvent () } } - KeyRead (); - + if (Keyboard != NULL) + { + Keyboard->ProcessInput(); + } if (Mouse != NULL) { Mouse->ProcessInput(); diff --git a/src/win32/i_input.h b/src/win32/i_input.h index 5c797551..c0e88551 100644 --- a/src/win32/i_input.h +++ b/src/win32/i_input.h @@ -84,8 +84,39 @@ protected: WORD ButtonState; // bit mask of current button states (1=down, 0=up) }; +class FKeyboard : public FInputDevice +{ +public: + FKeyboard(); + ~FKeyboard(); + + void AllKeysUp(); + +protected: + BYTE KeyStates[256/8]; + + int CheckKey(int keynum) const + { + return KeyStates[keynum >> 3] & (1 << (keynum & 7)); + } + void SetKey(int keynum, bool down) + { + if (down) + { + KeyStates[keynum >> 3] |= 1 << (keynum & 7); + } + else + { + KeyStates[keynum >> 3] &= ~(1 << (keynum & 7)); + } + } + bool CheckAndSetKey(int keynum, INTBOOL down); + void PostKeyEvent(int keynum, INTBOOL down, bool foreground); +}; + void I_StartupMouse(); void I_CheckNativeMouse(bool prefer_native); +void I_StartupKeyboard(); // USB HID usage page numbers #define HID_GENERIC_DESKTOP_PAGE 0x01 diff --git a/src/win32/i_mouse.cpp b/src/win32/i_mouse.cpp index b4169366..7de6d62c 100644 --- a/src/win32/i_mouse.cpp +++ b/src/win32/i_mouse.cpp @@ -27,6 +27,11 @@ #define DINPUT_BUFFERSIZE 32 +// Compensate for w32api's lack +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) +#endif + // TYPES ------------------------------------------------------------------- class FRawMouse : public FMouse @@ -108,7 +113,6 @@ extern HWND Window; extern LPDIRECTINPUT8 g_pdi; extern LPDIRECTINPUT g_pdi3; extern bool GUICapture; -extern bool HaveFocus; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -175,18 +179,9 @@ static void SetCursorState(bool visible) { HCURSOR usingCursor = visible ? TheArrowCursor : TheInvisibleCursor; SetClassLongPtr(Window, GCLP_HCURSOR, (LONG_PTR)usingCursor); - //if (HaveFocus) + if (GetForegroundWindow() == Window) { SetCursor(usingCursor); - if (visible) - { - ShowCursor(TRUE); - } - else - { - while (ShowCursor(FALSE) >= 0) - { } - } } } @@ -223,18 +218,33 @@ static bool CaptureMode_InGame() void I_CheckNativeMouse(bool preferNative) { - bool wantNative = (GetFocus() != Window) || - ((!screen || !screen->IsFullscreen()) && - (!CaptureMode_InGame() || GUICapture || paused || preferNative || !use_mouse || demoplayback)); + bool windowed = (screen == NULL) || !screen->IsFullscreen(); + bool want_native; + + if (!windowed) + { + want_native = false; + } + else + { + want_native = + (GetForegroundWindow() != Window) || + !CaptureMode_InGame() || + GUICapture || + paused || + preferNative || + !use_mouse || + demoplayback; + } //Printf ("%d %d %d\n", wantNative, preferNative, NativeMouse); - if (wantNative != NativeMouse) + if (want_native != NativeMouse) { if (Mouse != NULL) { - NativeMouse = wantNative; - if (wantNative) + NativeMouse = want_native; + if (want_native) { Mouse->Ungrab(); } @@ -493,6 +503,7 @@ void FRawMouse::ProcessInput() // //========================================================================== +extern BOOL AppActive; void FRawMouse::Grab() { if (!Grabbed) @@ -507,7 +518,8 @@ void FRawMouse::Grab() { GetCursorPos(&UngrabbedPointerPos); Grabbed = true; - SetCursorState(false); + while (ShowCursor(FALSE) >= 0) + { } // By setting the cursor position, we force the pointer image // to change right away instead of having it delayed until // some time in the future. @@ -537,7 +549,7 @@ void FRawMouse::Ungrab() Grabbed = false; ClearButtonState(); } - SetCursorState(true); + ShowCursor(TRUE); SetCursorPos(UngrabbedPointerPos.x, UngrabbedPointerPos.y); } } @@ -589,7 +601,7 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara } if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { - WheelMoved(raw->data.mouse.usButtonData); + WheelMoved((SHORT)raw->data.mouse.usButtonData); } PostMouseMove(m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX<<2, -raw->data.mouse.lLastY); @@ -749,7 +761,6 @@ void FDInputMouse::ProcessInput() DIDEVICEOBJECTDATA od; DWORD dwElements; HRESULT hr; - int count = 0; int dx, dy; dx = 0; @@ -774,8 +785,6 @@ void FDInputMouse::ProcessInput() if (FAILED(hr) || !dwElements) break; - count++; - /* Look at the element to see what happened */ // GCC does not like putting the DIMOFS_ macros in case statements, // so use ifs instead. @@ -1167,6 +1176,5 @@ void I_StartupMouse () MouseMode = new_mousemode; NativeMouse = true; } - HaveFocus = (GetFocus() == Window); } diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 5db058b3..02fc6611 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -294,6 +294,10 @@ ACTOR PowerHighJump : Powerup native { } +ACTOR PowerDoubleFiringSpeed : Powerup native +{ +} + ACTOR PowerMorph : Powerup native { Powerup.Duration -40