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