- The mouse is no longer grabbed at all unless you're actually in a level,

since I couldn't think of any reason why it should be grabbed at any other
  time. (This only applies to windowed mode, where it makes sense to let the
  OS have control of the pointer.)


SVN r661 (trunk)
This commit is contained in:
Randy Heit 2008-01-02 05:21:48 +00:00
parent 8be8c48585
commit 59c8faa7df
11 changed files with 607 additions and 515 deletions

View file

@ -1,3 +1,17 @@
January 1, 2008
- The mouse is no longer grabbed at all unless you're actually in a level.
- Moved the view border drawing into the 2D mode part. When using Begin2D()
now, the only part of the software buffer that gets updated to the screen
is the part with the actual 3D scene and only if you tell it to.
- Fixed a D3D memory leak on every frame in windowed mode and the same thing
for the screen wipes. Note to self: If it's an interface, be sure to
Release it, because it will be AddRef'ed before being returned to you.
- Moved the BlendView() call out of FBaseStatusBar::Draw() so that it can be
applied before copying the 3D scene to the screen underneath the 2D parts.
- Restored the console's darkening level to its old table-based amount.
- Fixed D3DFB::SetColorOverlay()'s incorrect calculations.
- Fixed the D3D screen wipes for letterboxed modes.
January 1, 2008 (Changes by Graf Zahl) January 1, 2008 (Changes by Graf Zahl)
- Fixed: A_JumpIfTargetInLOS had inconsistent parameter definitions. - Fixed: A_JumpIfTargetInLOS had inconsistent parameter definitions.

View file

@ -305,7 +305,7 @@ void C_InitConsole (int width, int height, bool ingame)
if (conback <= 0) if (conback <= 0)
{ {
conback = TexMan.GetTexture (gameinfo.titlePage, FTexture::TEX_MiscPatch); conback = TexMan.GetTexture (gameinfo.titlePage, FTexture::TEX_MiscPatch);
conshade = MAKEARGB(120,0,0,0); conshade = MAKEARGB(175,0,0,0);
conline = true; conline = true;
} }
else else

View file

@ -535,7 +535,7 @@ void D_Display ()
{ {
case GS_FULLCONSOLE: case GS_FULLCONSOLE:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(); hw2d = screen->Begin2D(false);
C_DrawConsole (false); C_DrawConsole (false);
M_Drawer (); M_Drawer ();
screen->Update (); screen->Update ();
@ -546,19 +546,13 @@ void D_Display ()
if (!gametic) if (!gametic)
break; break;
if (!menuactive) if (StatusBar != NULL)
{ {
screen->SetBlendingRect(viewwindowx, MAX(ConBottom,viewwindowy), float blend[4] = { 0, 0, 0, 0 };
viewwindowx + realviewwidth, MAX(ConBottom,viewwindowy + realviewheight)); StatusBar->BlendView (blend);
} }
else screen->SetBlendingRect(viewwindowx, viewwindowy,
{ viewwindowx + realviewwidth, viewwindowy + realviewheight);
// Don't chop the blending effect off at the status bar when the menu is
// active. Mostly, this is just to make Strife's dialogs with portrait
// images look okay when a blend is active.
screen->SetBlendingRect(0,0,0,0);
}
R_RefreshViewBorder ();
P_CheckPlayerSprites(); P_CheckPlayerSprites();
R_RenderActorView (players[consoleplayer].mo); R_RenderActorView (players[consoleplayer].mo);
R_DetailDouble (); // [RH] Apply detail mode expansion R_DetailDouble (); // [RH] Apply detail mode expansion
@ -568,11 +562,13 @@ void D_Display ()
{ {
AM_Drawer (); AM_Drawer ();
} }
if ((hw2d = screen->Begin2D())) if ((hw2d = screen->Begin2D(true)))
{ {
// Redraw the status bar every frame when using 2D accel // Redraw everything every frame when using 2D accel
SB_state = screen->GetPageCount(); SB_state = screen->GetPageCount();
BorderNeedRefresh = screen->GetPageCount();
} }
R_RefreshViewBorder ();
if (realviewheight == SCREENHEIGHT && viewactive) if (realviewheight == SCREENHEIGHT && viewactive)
{ {
StatusBar->Draw (DrawFSHUD ? HUD_Fullscreen : HUD_None); StatusBar->Draw (DrawFSHUD ? HUD_Fullscreen : HUD_None);
@ -588,21 +584,21 @@ void D_Display ()
case GS_INTERMISSION: case GS_INTERMISSION:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(); hw2d = screen->Begin2D(false);
WI_Drawer (); WI_Drawer ();
CT_Drawer (); CT_Drawer ();
break; break;
case GS_FINALE: case GS_FINALE:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(); hw2d = screen->Begin2D(false);
F_Drawer (); F_Drawer ();
CT_Drawer (); CT_Drawer ();
break; break;
case GS_DEMOSCREEN: case GS_DEMOSCREEN:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(); hw2d = screen->Begin2D(false);
D_PageDrawer (); D_PageDrawer ();
CT_Drawer (); CT_Drawer ();
break; break;

View file

@ -1095,12 +1095,8 @@ void FBaseStatusBar::DrawMessages (int bottom) const
void FBaseStatusBar::Draw (EHudState state) void FBaseStatusBar::Draw (EHudState state)
{ {
float blend[4];
char line[64+10]; char line[64+10];
blend[0] = blend[1] = blend[2] = blend[3] = 0;
BlendView (blend);
if ((SB_state != 0 || BorderNeedRefresh) && state == HUD_StatusBar) if ((SB_state != 0 || BorderNeedRefresh) && state == HUD_StatusBar)
{ {
RefreshBackground (); RefreshBackground ();

View file

@ -1,229 +1,229 @@
#include <SDL.h> #include <SDL.h>
#include <ctype.h> #include <ctype.h>
#include "doomtype.h" #include "doomtype.h"
#include "c_dispatch.h" #include "c_dispatch.h"
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h" #include "doomstat.h"
#include "m_argv.h" #include "m_argv.h"
#include "i_input.h" #include "i_input.h"
#include "v_video.h" #include "v_video.h"
#include "d_main.h" #include "d_main.h"
#include "d_gui.h" #include "d_gui.h"
#include "c_console.h" #include "c_console.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "i_system.h" #include "i_system.h"
#include "dikeys.h" #include "dikeys.h"
#include "templates.h" #include "templates.h"
#include "s_sound.h" #include "s_sound.h"
static void I_CheckGUICapture (); static void I_CheckGUICapture ();
static void I_CheckNativeMouse (); static void I_CheckNativeMouse ();
static bool GUICapture; static bool GUICapture;
static bool NativeMouse = true; static bool NativeMouse = true;
extern int paused; extern int paused;
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
float JoyAxes[6]; float JoyAxes[6];
//static int JoyActive; //static int JoyActive;
//static BYTE JoyButtons[128]; //static BYTE JoyButtons[128];
//static BYTE JoyPOV[4]; //static BYTE JoyPOV[4];
static BYTE JoyAxisMap[8]; static BYTE JoyAxisMap[8];
static float JoyAxisThresholds[8]; static float JoyAxisThresholds[8];
char *JoyAxisNames[8]; char *JoyAxisNames[8];
static const BYTE POVButtons[9] = { 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09, 0x00 }; static const BYTE POVButtons[9] = { 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09, 0x00 };
TArray<GUIDName> JoystickNames; TArray<GUIDName> JoystickNames;
CVAR (Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, use_joystick, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (GUID, joy_guid, NULL, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) CVAR (GUID, joy_guid, NULL, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
static void MapAxis (FIntCVar &var, int num) static void MapAxis (FIntCVar &var, int num)
{ {
if (var < JOYAXIS_NONE || var > JOYAXIS_UP) if (var < JOYAXIS_NONE || var > JOYAXIS_UP)
{ {
var = JOYAXIS_NONE; var = JOYAXIS_NONE;
} }
else else
{ {
JoyAxisMap[num] = var; JoyAxisMap[num] = var;
} }
} }
CUSTOM_CVAR (Int, joy_xaxis, JOYAXIS_YAW, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_xaxis, JOYAXIS_YAW, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 0); MapAxis (self, 0);
} }
CUSTOM_CVAR (Int, joy_yaxis, JOYAXIS_FORWARD, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_yaxis, JOYAXIS_FORWARD, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 1); MapAxis (self, 1);
} }
CUSTOM_CVAR (Int, joy_zaxis, JOYAXIS_SIDE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_zaxis, JOYAXIS_SIDE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 2); MapAxis (self, 2);
} }
CUSTOM_CVAR (Int, joy_xrot, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_xrot, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 3); MapAxis (self, 3);
} }
CUSTOM_CVAR (Int, joy_yrot, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_yrot, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 4); MapAxis (self, 4);
} }
CUSTOM_CVAR (Int, joy_zrot, JOYAXIS_PITCH, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_zrot, JOYAXIS_PITCH, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 5); MapAxis (self, 5);
} }
CUSTOM_CVAR (Int, joy_slider, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_slider, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 6); MapAxis (self, 6);
} }
CUSTOM_CVAR (Int, joy_dial, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, joy_dial, JOYAXIS_NONE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
MapAxis (self, 7); MapAxis (self, 7);
} }
CUSTOM_CVAR (Float, joy_xthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_xthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[0] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[0] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_ythreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_ythreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[1] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[1] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_zthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_zthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[2] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[2] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_xrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_xrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[3] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[3] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_yrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_yrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[4] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[4] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_zrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_zrotthreshold, 0.15f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[5] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[5] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_sliderthreshold, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_sliderthreshold, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[6] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[6] = clamp (self * 256.f, 0.f, 256.f);
} }
CUSTOM_CVAR (Float, joy_dialthreshold, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, joy_dialthreshold, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
JoyAxisThresholds[7] = clamp (self * 256.f, 0.f, 256.f); JoyAxisThresholds[7] = clamp (self * 256.f, 0.f, 256.f);
} }
CVAR (Float, joy_speedmultiplier,1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_speedmultiplier,1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Float, joy_yawspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_yawspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Float, joy_pitchspeed, -.75f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_pitchspeed, -.75f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Float, joy_forwardspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, joy_forwardspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Float, joy_sidespeed, 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) CVAR (Float, joy_upspeed, -1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
static FBaseCVar * const JoyConfigVars[] = static FBaseCVar * const JoyConfigVars[] =
{ {
&joy_xaxis, &joy_yaxis, &joy_zaxis, &joy_xrot, &joy_yrot, &joy_zrot, &joy_slider, &joy_dial, &joy_xaxis, &joy_yaxis, &joy_zaxis, &joy_xrot, &joy_yrot, &joy_zrot, &joy_slider, &joy_dial,
&joy_xthreshold, &joy_ythreshold, &joy_zthreshold, &joy_xrotthreshold, &joy_yrotthreshold, &joy_zrotthreshold, &joy_sliderthreshold, &joy_dialthreshold, &joy_xthreshold, &joy_ythreshold, &joy_zthreshold, &joy_xrotthreshold, &joy_yrotthreshold, &joy_zrotthreshold, &joy_sliderthreshold, &joy_dialthreshold,
&joy_speedmultiplier, &joy_yawspeed, &joy_pitchspeed, &joy_forwardspeed, &joy_sidespeed, &joy_speedmultiplier, &joy_yawspeed, &joy_pitchspeed, &joy_forwardspeed, &joy_sidespeed,
&joy_upspeed &joy_upspeed
}; };
EXTERN_CVAR (Bool, fullscreen) EXTERN_CVAR (Bool, fullscreen)
extern int WaitingForKey, chatmodeon; extern int WaitingForKey, chatmodeon;
extern constate_e ConsoleState; extern constate_e ConsoleState;
static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST]; static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST];
static WORD DIKToKeySym[256] = static WORD DIKToKeySym[256] =
{ {
0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6', 0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB, '7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', SDLK_RETURN, SDLK_LCTRL, 'a', 's', 'o', 'p', '[', ']', SDLK_RETURN, SDLK_LCTRL, 'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', SDLK_SEMICOLON, 'd', 'f', 'g', 'h', 'j', 'k', 'l', SDLK_SEMICOLON,
'\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v', '\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY, 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY,
SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5,
SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7, SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7,
SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1, SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1,
SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11,
SDLK_F12, 0, 0, 0, 0, 0, 0, 0, SDLK_F12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0, 0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0, 0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0,
0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0, 0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0,
0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0, 0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ, 0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ,
SDLK_RALT, 0, 0, 0, 0, 0, 0, 0, SDLK_RALT, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, SDLK_HOME, 0, 0, 0, 0, 0, 0, 0, SDLK_HOME,
SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END,
SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0,
0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0, 0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, SDLK_PAUSE 0, 0, 0, 0, 0, 0, 0, SDLK_PAUSE
}; };
static void FlushDIKState (int low=0, int high=NUM_KEYS-1) static void FlushDIKState (int low=0, int high=NUM_KEYS-1)
{ {
} }
static void InitKeySymMap () static void InitKeySymMap ()
{ {
for (int i = 0; i < 256; ++i) for (int i = 0; i < 256; ++i)
{ {
KeySymToDIK[DIKToKeySym[i]] = i; KeySymToDIK[DIKToKeySym[i]] = i;
} }
KeySymToDIK[0] = 0; KeySymToDIK[0] = 0;
KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT; KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT;
KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL; KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL;
KeySymToDIK[SDLK_RALT] = DIK_LMENU; KeySymToDIK[SDLK_RALT] = DIK_LMENU;
} }
static void I_CheckGUICapture () static void I_CheckGUICapture ()
{ {
bool wantCapt; bool wantCapt;
if (menuactive == MENU_Off) if (menuactive == MENU_Off)
{ {
wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon; wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon;
} }
else else
{ {
wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause); wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause);
} }
if (wantCapt != GUICapture) if (wantCapt != GUICapture)
{ {
GUICapture = wantCapt; GUICapture = wantCapt;
if (wantCapt) if (wantCapt)
{ {
FlushDIKState (); FlushDIKState ();
memset (DownState, 0, sizeof(DownState)); memset (DownState, 0, sizeof(DownState));
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_EnableUNICODE (1); SDL_EnableUNICODE (1);
} }
else else
{ {
SDL_EnableKeyRepeat (0, 0); SDL_EnableKeyRepeat (0, 0);
SDL_EnableUNICODE (0); SDL_EnableUNICODE (0);
} }
} }
} }
static void CenterMouse () static void CenterMouse ()
{ {
@ -277,194 +277,194 @@ static void MouseRead ()
PostMouseMove (x, -y); PostMouseMove (x, -y);
} }
} }
static void I_CheckNativeMouse () static void I_CheckNativeMouse ()
{ {
bool focus = (SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPACTIVE)) bool focus = (SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPACTIVE))
== (SDL_APPINPUTFOCUS|SDL_APPACTIVE); == (SDL_APPINPUTFOCUS|SDL_APPACTIVE);
bool fs = (SDL_GetVideoSurface ()->flags & SDL_FULLSCREEN) != 0; bool fs = (SDL_GetVideoSurface ()->flags & SDL_FULLSCREEN) != 0;
bool wantNative = !focus || !use_mouse || (!fs && (GUICapture || paused || demoplayback)); bool wantNative = !focus || !use_mouse || (!fs && (GUICapture || paused || demoplayback || gamestate != GS_LEVEL));
if (wantNative != NativeMouse) if (wantNative != NativeMouse)
{ {
NativeMouse = wantNative; NativeMouse = wantNative;
if (wantNative) if (wantNative)
{ {
SDL_ShowCursor (1); SDL_ShowCursor (1);
SDL_WM_GrabInput (SDL_GRAB_OFF); SDL_WM_GrabInput (SDL_GRAB_OFF);
FlushDIKState (KEY_MOUSE1, KEY_MOUSE4); FlushDIKState (KEY_MOUSE1, KEY_MOUSE4);
} }
else else
{ {
SDL_ShowCursor (0); SDL_ShowCursor (0);
SDL_WM_GrabInput (SDL_GRAB_ON); SDL_WM_GrabInput (SDL_GRAB_ON);
CenterMouse (); CenterMouse ();
} }
} }
} }
void MessagePump (const SDL_Event &sev) void MessagePump (const SDL_Event &sev)
{ {
static int lastx = 0, lasty = 0; static int lastx = 0, lasty = 0;
int x, y; int x, y;
event_t event = { 0, }; event_t event = { 0, };
switch (sev.type) switch (sev.type)
{ {
case SDL_QUIT: case SDL_QUIT:
exit (0); exit (0);
case SDL_ACTIVEEVENT: case SDL_ACTIVEEVENT:
if (sev.active.state == SDL_APPINPUTFOCUS) if (sev.active.state == SDL_APPINPUTFOCUS)
{ {
if (sev.active.gain == 0) if (sev.active.gain == 0)
{ // kill focus { // kill focus
FlushDIKState (); FlushDIKState ();
if (!paused) if (!paused)
S_PauseSound (false); S_PauseSound (false);
}
else
{ // set focus
if (!paused)
S_ResumeSound ();
}
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
switch (sev.button.button)
{
case 1: event.data1 = KEY_MOUSE1; break;
case 2: event.data1 = KEY_MOUSE3; break;
case 3: event.data1 = KEY_MOUSE2; break;
case 4: event.data1 = KEY_MWHEELUP; break;
case 5: event.data1 = KEY_MWHEELDOWN; break;
case 6: event.data1 = KEY_MOUSE4; break; /* dunno */
}
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
D_PostEvent (&event);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
if (sev.key.keysym.sym >= SDLK_LAST)
break;
if (!GUICapture)
{
event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp;
event.data1 = KeySymToDIK[sev.key.keysym.sym];
if (event.data1)
{
if (sev.key.keysym.sym < 256)
{
event.data2 = sev.key.keysym.sym;
}
D_PostEvent (&event);
}
}
else
{
event.type = EV_GUI_Event;
event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp;
event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) |
((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0);
if (sev.key.keysym.sym < SDLK_LAST)
{
if (event.subtype == EV_GUI_KeyDown)
{
if (DownState[sev.key.keysym.sym])
{
event.subtype = EV_GUI_KeyRepeat;
}
DownState[sev.key.keysym.sym] = 1;
}
else
{
DownState[sev.key.keysym.sym] = 0;
}
}
switch (sev.key.keysym.sym)
{
case SDLK_KP_ENTER: event.data1 = GK_RETURN; break;
case SDLK_PAGEUP: event.data1 = GK_PGUP; break;
case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break;
case SDLK_END: event.data1 = GK_END; break;
case SDLK_HOME: event.data1 = GK_HOME; break;
case SDLK_LEFT: event.data1 = GK_LEFT; break;
case SDLK_RIGHT: event.data1 = GK_RIGHT; break;
case SDLK_UP: event.data1 = GK_UP; break;
case SDLK_DOWN: event.data1 = GK_DOWN; break;
case SDLK_DELETE: event.data1 = GK_DEL; break;
case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break;
case SDLK_F1: event.data1 = GK_F1; break;
case SDLK_F2: event.data1 = GK_F2; break;
case SDLK_F3: event.data1 = GK_F3; break;
case SDLK_F4: event.data1 = GK_F4; break;
case SDLK_F5: event.data1 = GK_F5; break;
case SDLK_F6: event.data1 = GK_F6; break;
case SDLK_F7: event.data1 = GK_F7; break;
case SDLK_F8: event.data1 = GK_F8; break;
case SDLK_F9: event.data1 = GK_F9; break;
case SDLK_F10: event.data1 = GK_F10; break;
case SDLK_F11: event.data1 = GK_F11; break;
case SDLK_F12: event.data1 = GK_F12; break;
default:
if (sev.key.keysym.sym < 256)
{
event.data1 = sev.key.keysym.sym;
}
break;
}
event.data2 = sev.key.keysym.unicode & 0xff;
if (event.data1 < 128)
{
event.data1 = toupper(event.data1);
D_PostEvent (&event);
} }
if (!iscntrl(event.data2) && event.subtype != EV_GUI_KeyUp) else
{ { // set focus
event.subtype = EV_GUI_Char; if (!paused)
event.data1 = event.data2; S_ResumeSound ();
event.data2 = sev.key.keysym.mod & KMOD_ALT; }
event.data3 = 0; }
D_PostEvent (&event); break;
}
} case SDL_MOUSEBUTTONDOWN:
} case SDL_MOUSEBUTTONUP:
} event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
switch (sev.button.button)
void I_GetEvent () {
{ case 1: event.data1 = KEY_MOUSE1; break;
SDL_Event sev; case 2: event.data1 = KEY_MOUSE3; break;
case 3: event.data1 = KEY_MOUSE2; break;
while (SDL_PollEvent (&sev)) case 4: event.data1 = KEY_MWHEELUP; break;
{ case 5: event.data1 = KEY_MWHEELDOWN; break;
MessagePump (sev); case 6: event.data1 = KEY_MOUSE4; break; /* dunno */
}
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
D_PostEvent (&event);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
if (sev.key.keysym.sym >= SDLK_LAST)
break;
if (!GUICapture)
{
event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp;
event.data1 = KeySymToDIK[sev.key.keysym.sym];
if (event.data1)
{
if (sev.key.keysym.sym < 256)
{
event.data2 = sev.key.keysym.sym;
}
D_PostEvent (&event);
}
}
else
{
event.type = EV_GUI_Event;
event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp;
event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) |
((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0);
if (sev.key.keysym.sym < SDLK_LAST)
{
if (event.subtype == EV_GUI_KeyDown)
{
if (DownState[sev.key.keysym.sym])
{
event.subtype = EV_GUI_KeyRepeat;
}
DownState[sev.key.keysym.sym] = 1;
}
else
{
DownState[sev.key.keysym.sym] = 0;
}
}
switch (sev.key.keysym.sym)
{
case SDLK_KP_ENTER: event.data1 = GK_RETURN; break;
case SDLK_PAGEUP: event.data1 = GK_PGUP; break;
case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break;
case SDLK_END: event.data1 = GK_END; break;
case SDLK_HOME: event.data1 = GK_HOME; break;
case SDLK_LEFT: event.data1 = GK_LEFT; break;
case SDLK_RIGHT: event.data1 = GK_RIGHT; break;
case SDLK_UP: event.data1 = GK_UP; break;
case SDLK_DOWN: event.data1 = GK_DOWN; break;
case SDLK_DELETE: event.data1 = GK_DEL; break;
case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break;
case SDLK_F1: event.data1 = GK_F1; break;
case SDLK_F2: event.data1 = GK_F2; break;
case SDLK_F3: event.data1 = GK_F3; break;
case SDLK_F4: event.data1 = GK_F4; break;
case SDLK_F5: event.data1 = GK_F5; break;
case SDLK_F6: event.data1 = GK_F6; break;
case SDLK_F7: event.data1 = GK_F7; break;
case SDLK_F8: event.data1 = GK_F8; break;
case SDLK_F9: event.data1 = GK_F9; break;
case SDLK_F10: event.data1 = GK_F10; break;
case SDLK_F11: event.data1 = GK_F11; break;
case SDLK_F12: event.data1 = GK_F12; break;
default:
if (sev.key.keysym.sym < 256)
{
event.data1 = sev.key.keysym.sym;
}
break;
}
event.data2 = sev.key.keysym.unicode & 0xff;
if (event.data1 < 128)
{
event.data1 = toupper(event.data1);
D_PostEvent (&event);
}
if (!iscntrl(event.data2) && event.subtype != EV_GUI_KeyUp)
{
event.subtype = EV_GUI_Char;
event.data1 = event.data2;
event.data2 = sev.key.keysym.mod & KMOD_ALT;
event.data3 = 0;
D_PostEvent (&event);
}
}
}
}
void I_GetEvent ()
{
SDL_Event sev;
while (SDL_PollEvent (&sev))
{
MessagePump (sev);
} }
if (use_mouse) if (use_mouse)
{ {
MouseRead (); MouseRead ();
} }
} }
void I_StartTic () void I_StartTic ()
{ {
I_CheckGUICapture (); I_CheckGUICapture ();
I_CheckNativeMouse (); I_CheckNativeMouse ();
I_GetEvent (); I_GetEvent ();
} }
void I_StartFrame () void I_StartFrame ()
{ {
if (KeySymToDIK[SDLK_BACKSPACE] == 0) if (KeySymToDIK[SDLK_BACKSPACE] == 0)
{ {
InitKeySymMap (); InitKeySymMap ();
} }
} }

View file

@ -832,7 +832,7 @@ void DFrameBuffer::SetBlendingRect (int x1, int y1, int x2, int y2)
{ {
} }
bool DFrameBuffer::Begin2D () bool DFrameBuffer::Begin2D (bool copy3d)
{ {
return false; return false;
} }

View file

@ -320,9 +320,11 @@ public:
bool Accel2D; // If true, 2D drawing can be accelerated. bool Accel2D; // If true, 2D drawing can be accelerated.
// Begin 2D drawing operations. This is like Update, but it doesn't end // Begin 2D drawing operations. This is like Update, but it doesn't end
// the scene, and it doesn't present the image yet. Returns true if // the scene, and it doesn't present the image yet. If you are going to
// hardware-accelerated 2D has been entered, false if not. // be covering the entire screen with 2D elements, then pass false to
virtual bool Begin2D(); // avoid copying the software bufferer to the screen.
// Returns true if hardware-accelerated 2D has been entered, false if not.
virtual bool Begin2D(bool copy3d);
// DrawTexture calls after Begin2D use native textures. // DrawTexture calls after Begin2D use native textures.

View file

@ -346,6 +346,7 @@ bool D3DFB::CreateResources ()
return false; return false;
} }
SetGamma (Gamma); SetGamma (Gamma);
OldRenderTarget = NULL;
return true; return true;
} }
@ -586,7 +587,7 @@ bool D3DFB::CreateVertexes ()
bool D3DFB::UploadVertices() bool D3DFB::UploadVertices()
{ {
float top = LBOffset - 0.5f; float top = GatheringWipeScreen ? -0.5f : LBOffset - 0.5f;
float right = float(Width) - 0.5f; float right = float(Width) - 0.5f;
float bot = float(Height) + top; float bot = float(Height) + top;
float texright = float(Width) / float(FBWidth); float texright = float(Width) / float(FBWidth);
@ -753,10 +754,11 @@ void D3DFB::Unlock ()
// When In2D == 0: Copy buffer to screen and present // When In2D == 0: Copy buffer to screen and present
// When In2D == 1: Copy buffer to screen but do not present // When In2D == 1: Copy buffer to screen but do not present
// When In2D == 2: Present and set In2D to 0 // When In2D == 2: Set up for 2D drawing but do not draw anything
// When In2D == 3: Present and set In2D to 0
void D3DFB::Update () void D3DFB::Update ()
{ {
if (In2D == 2) if (In2D == 3)
{ {
DrawRateStuff(); DrawRateStuff();
DoWindowedGamma(); DoWindowedGamma();
@ -814,7 +816,13 @@ void D3DFB::Update ()
clock (BlitCycles); clock (BlitCycles);
LockCount = 0; LockCount = 0;
PaintToWindow (); HRESULT hr = D3DDevice->TestCooperativeLevel();
if (FAILED(hr) && (hr != D3DERR_DEVICENOTRESET || !Reset()))
{
Sleep(1);
return;
}
Draw3DPart(In2D <= 1);
if (In2D == 0) if (In2D == 0)
{ {
DoWindowedGamma(); DoWindowedGamma();
@ -846,49 +854,56 @@ bool D3DFB::PaintToWindow ()
return false; return false;
} }
} }
Draw3DPart(); Draw3DPart(true);
return true; return true;
} }
void D3DFB::Draw3DPart() void D3DFB::Draw3DPart(bool copy3d)
{ {
RECT texrect = { 0, 0, Width, Height }; RECT texrect = { 0, 0, Width, Height };
D3DLOCKED_RECT lockrect; D3DLOCKED_RECT lockrect;
if ((FBWidth == Width && FBHeight == Height && if (copy3d)
SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) ||
SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0)))
{ {
if (lockrect.Pitch == Pitch) if ((FBWidth == Width && FBHeight == Height &&
SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) ||
SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0)))
{ {
memcpy (lockrect.pBits, MemBuffer, Width * Height); if (lockrect.Pitch == Pitch)
}
else
{
BYTE *dest = (BYTE *)lockrect.pBits;
BYTE *src = MemBuffer;
for (int y = 0; y < Height; y++)
{ {
memcpy (dest, src, Width); memcpy (lockrect.pBits, MemBuffer, Width * Height);
dest += lockrect.Pitch;
src += Pitch;
} }
else
{
BYTE *dest = (BYTE *)lockrect.pBits;
BYTE *src = MemBuffer;
for (int y = 0; y < Height; y++)
{
memcpy (dest, src, Width);
dest += lockrect.Pitch;
src += Pitch;
}
}
FBTexture->UnlockRect (0);
} }
FBTexture->UnlockRect (0);
} }
DrawLetterbox(); DrawLetterbox();
D3DDevice->BeginScene(); D3DDevice->BeginScene();
OldRenderTarget = NULL; assert(OldRenderTarget == NULL);
if (TempRenderTexture != NULL && if (TempRenderTexture != NULL &&
((Windowed && GammaFixerShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen)) ((Windowed && GammaFixerShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen))
{ {
IDirect3DSurface9 *targetsurf; IDirect3DSurface9 *targetsurf;
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)) || if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) ||
FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{ {
// Setting the render target failed. if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)))
OldRenderTarget = NULL; {
if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{
// Setting the render target failed.
}
}
targetsurf->Release();
} }
} }
@ -899,25 +914,28 @@ void D3DFB::Draw3DPart()
D3DDevice->SetPixelShaderConstantF (0, FlashConstants[0], 2); D3DDevice->SetPixelShaderConstantF (0, FlashConstants[0], 2);
memcpy(Constant, FlashConstants, sizeof(FlashConstants)); memcpy(Constant, FlashConstants, sizeof(FlashConstants));
SetAlphaBlend(FALSE); SetAlphaBlend(FALSE);
if (!UseBlendingRect || FlashConstants[1][0] == 1) if (copy3d)
{ // The whole screen as a single quad. {
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2); if (!UseBlendingRect || FlashConstants[1][0] == 1)
} { // The whole screen as a single quad.
else D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2);
{ // The screen split up so that only the 3D view is blended. }
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 24, 2); // middle else
{ // The screen split up so that only the 3D view is blended.
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 24, 2); // middle
if (!In2D || 1) if (!In2D)
{ {
// The rest is drawn unblended, so reset the shader constant. // The rest is drawn unblended, so reset the shader constant.
static const float FlashZero[2][4] = { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } }; static const float FlashZero[2][4] = { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
D3DDevice->SetPixelShaderConstantF (0, FlashZero[0], 2); D3DDevice->SetPixelShaderConstantF (0, FlashZero[0], 2);
memcpy(Constant, FlashZero, sizeof(FlashZero)); memcpy(Constant, FlashZero, sizeof(FlashZero));
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 4, 2); // left D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 4, 2); // left
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 8, 2); // right D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 8, 2); // right
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 12, 4); // bottom D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 12, 4); // bottom
D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 18, 4); // top D3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 18, 4); // top
}
} }
} }
} }
@ -933,7 +951,7 @@ void D3DFB::Draw3DPart()
void D3DFB::DrawLetterbox() void D3DFB::DrawLetterbox()
{ {
if (TrueHeight != Height) if (LBOffsetI != 0)
{ {
D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } }; D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } };
D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0); D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0);
@ -960,6 +978,7 @@ void D3DFB::DoWindowedGamma()
SetPixelShader((Windowed && GammaFixerShader != NULL) ? GammaFixerShader : PlainShader); SetPixelShader((Windowed && GammaFixerShader != NULL) ? GammaFixerShader : PlainShader);
SetAlphaBlend(FALSE); SetAlphaBlend(FALSE);
D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
OldRenderTarget->Release();
OldRenderTarget = NULL; OldRenderTarget = NULL;
} }
} }
@ -1380,16 +1399,20 @@ bool D3DPal::Update()
// //
//========================================================================== //==========================================================================
bool D3DFB::Begin2D() bool D3DFB::Begin2D(bool copy3d)
{ {
if (!test2d) return false; copy3d = true;
if (!test2d)
{
return false;
}
if (In2D) if (In2D)
{ {
return true; return true;
} }
In2D = 1; In2D = 2 - copy3d;
Update(); Update();
In2D = 2; In2D = 3;
return true; return true;
} }
@ -1456,7 +1479,8 @@ void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint3
Dim(color, APART(color)/255.f, left, top, right - left, bottom - top); Dim(color, APART(color)/255.f, left, top, right - left, bottom - top);
return; return;
} }
D3DRECT rect = { left, top + LBOffsetI, right, bottom + LBOffsetI }; int offs = GatheringWipeScreen ? 0 : LBOffsetI;
D3DRECT rect = { left, top + offs, right, bottom + offs };
D3DDevice->Clear(1, &rect, D3DCLEAR_TARGET, color | 0xFF000000, 1.f, 0); D3DDevice->Clear(1, &rect, D3DCLEAR_TARGET, color | 0xFF000000, 1.f, 0);
} }
@ -1484,7 +1508,7 @@ void D3DFB::Dim (PalEntry color, float amount, int x1, int y1, int w, int h)
else else
{ {
float x = float(x1) - 0.5f; float x = float(x1) - 0.5f;
float y = float(y1) - 0.5f + LBOffset; float y = float(y1) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset);
FBVERTEX verts[4] = FBVERTEX verts[4] =
{ {
{ x, y, 0.5f, 1, 0, 0 }, { x, y, 0.5f, 1, 0, 0 },
@ -1577,10 +1601,11 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
x1 = float(parms.rclip); x1 = float(parms.rclip);
} }
float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset;
x0 -= 0.5f; x0 -= 0.5f;
y0 -= 0.5f - LBOffset; y0 -= yoffs;
x1 -= 0.5f; x1 -= 0.5f;
y1 -= 0.5f - LBOffset; y1 -= yoffs;
FBVERTEX verts[4] = FBVERTEX verts[4] =
{ {
@ -1751,12 +1776,12 @@ void D3DFB::SetColorOverlay(DWORD color, float alpha)
{ {
if (APART(color) != 0) if (APART(color) != 0)
{ {
float a = 255.f / APART(color); float a = APART(color) / (255.f * 255.f);
float r = RPART(color) * a; float r = RPART(color) * a;
float g = GPART(color) * a; float g = GPART(color) * a;
float b = BPART(color) * a; float b = BPART(color) * a;
SetConstant(0, r, g, b, 0); SetConstant(0, r, g, b, 0);
a = 1 - 1 / a; a = 1 - a * 255;
SetConstant(1, a, a, a, alpha); SetConstant(1, a, a, a, alpha);
} }
else else

View file

@ -165,16 +165,32 @@ bool D3DFB::WipeStartScreen(int type)
{ {
// The InitialWipeScreen must have the same pixel format as // The InitialWipeScreen must have the same pixel format as
// the TempRenderTexture. // the TempRenderTexture.
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) || if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
FAILED(tsurf->GetDesc(&desc))) {
if (FAILED(tsurf->GetDesc(&desc)))
{
tsurf->Release();
return false;
}
tsurf->Release();
}
else
{ {
return false; return false;
} }
} }
else else
{ {
if (FAILED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &tsurf)) || if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &tsurf)))
FAILED(tsurf->GetDesc(&desc))) {
if (FAILED(tsurf->GetDesc(&desc)))
{
tsurf->Release();
return false;
}
tsurf->Release();
}
else
{ {
return false; return false;
} }
@ -198,6 +214,7 @@ bool D3DFB::WipeStartScreen(int type)
{ {
if (FAILED(D3DDevice->GetFrontBufferData(0, surf))) if (FAILED(D3DDevice->GetFrontBufferData(0, surf)))
{ {
surf->Release();
InitialWipeScreen->Release(); InitialWipeScreen->Release();
InitialWipeScreen = NULL; InitialWipeScreen = NULL;
return false; return false;
@ -206,8 +223,17 @@ bool D3DFB::WipeStartScreen(int type)
} }
else else
{ {
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) || if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
FAILED(D3DDevice->GetRenderTargetData(tsurf, surf))) {
if (FAILED(D3DDevice->GetRenderTargetData(tsurf, surf)))
{
tsurf->Release();
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
return false;
}
}
else
{ {
InitialWipeScreen->Release(); InitialWipeScreen->Release();
InitialWipeScreen = NULL; InitialWipeScreen = NULL;
@ -230,10 +256,13 @@ bool D3DFB::WipeStartScreen(int type)
{ {
FinalWipeScreen = TempRenderTexture; FinalWipeScreen = TempRenderTexture;
} }
tsurf->Release();
} }
surf->Release();
// Even fullscreen will render to the TempRenderTexture, so we can have // Even fullscreen will render to the TempRenderTexture, so we can have
// a copy of the new screen readily available. // a copy of the new screen readily available.
GatheringWipeScreen = true; GatheringWipeScreen = true;
UploadVertices();
return true; return true;
} }
@ -264,7 +293,7 @@ void D3DFB::WipeEndScreen()
// video memory now. // video memory now.
if (!In2D) if (!In2D)
{ {
Begin2D(); Begin2D(true);
} }
// Don't do anything if there is no ending point. // Don't do anything if there is no ending point.
@ -309,6 +338,7 @@ bool D3DFB::WipeDo(int ticks)
if (GatheringWipeScreen) if (GatheringWipeScreen)
{ // This is the first time we've been called for this wipe. { // This is the first time we've been called for this wipe.
GatheringWipeScreen = false; GatheringWipeScreen = false;
UploadVertices();
if (OldRenderTarget == NULL) if (OldRenderTarget == NULL)
{ {
@ -320,20 +350,28 @@ bool D3DFB::WipeDo(int ticks)
{ // This is the second or later time we've been called for this wipe. { // This is the second or later time we've been called for this wipe.
D3DDevice->BeginScene(); D3DDevice->BeginScene();
} }
OldRenderTarget = NULL; if (OldRenderTarget != NULL)
{
OldRenderTarget->Release();
OldRenderTarget = NULL;
}
if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen && if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen &&
((Windowed && GammaFixerShader) || GatheringWipeScreen)) (Windowed && GammaFixerShader))
{ {
IDirect3DSurface9 *targetsurf; IDirect3DSurface9 *targetsurf;
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)) || if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) ||
FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{ {
// Setting the render target failed. if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)))
OldRenderTarget = NULL; {
if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{
// Setting the render target failed.
}
}
targetsurf->Release();
} }
} }
In2D = 2; In2D = 3;
bool done = ScreenWipe->Run(ticks, this); bool done = ScreenWipe->Run(ticks, this);
DrawLetterbox(); DrawLetterbox();
@ -409,12 +447,17 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
Clock += ticks; Clock += ticks;
// Put the initial screen back to the buffer, presumably with DMA. // Put the initial screen back to the buffer, presumably with DMA.
IDirect3DSurface9 *source, *target; IDirect3DSurface9 *source = NULL, *target = NULL;
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) && if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target))) SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
{ {
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL); fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
target->Release();
}
if (source != NULL)
{
source->Release();
} }
// Draw the new screen on top of it. // Draw the new screen on top of it.
@ -431,6 +474,8 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
return Clock >= 32; return Clock >= 32;
} }
// WIPE: MELT --------------------------------------------------------------
//========================================================================== //==========================================================================
// //
// D3DFB :: Wiper_Melt Constructor // D3DFB :: Wiper_Melt Constructor
@ -461,12 +506,16 @@ D3DFB::Wiper_Melt::Wiper_Melt()
bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb) bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
{ {
IDirect3DSurface9 *source, *target; IDirect3DSurface9 *source = NULL, *target;
if (FAILED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) || if (FAILED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) ||
FAILED(fb->D3DDevice->GetRenderTarget(0, &target))) FAILED(fb->D3DDevice->GetRenderTarget(0, &target)))
{ {
// A fat lot of good we can do if we can't get these two surfaces. // A fat lot of good we can do if we can't get these two surfaces.
if (source != NULL)
{
source->Release();
}
return true; return true;
} }
@ -508,9 +557,10 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
dpt.x = i * fb->Width / WIDTH; dpt.x = i * fb->Width / WIDTH;
dpt.y = MAX(0, y[i] * fb->Height / HEIGHT); dpt.y = MAX(0, y[i] * fb->Height / HEIGHT);
rect.left = dpt.x; rect.left = dpt.x;
rect.top = 0; rect.top = fb->LBOffsetI;
rect.right = (i + 1) * fb->Width / WIDTH; rect.right = (i + 1) * fb->Width / WIDTH;
rect.bottom = fb->Height - dpt.y; rect.bottom = fb->Height - dpt.y + fb->LBOffsetI;
dpt.y += fb->LBOffsetI;
if (rect.bottom > rect.top) if (rect.bottom > rect.top)
{ {
fb->D3DDevice->UpdateSurface(source, &rect, target, &dpt); fb->D3DDevice->UpdateSurface(source, &rect, target, &dpt);
@ -518,9 +568,13 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
} }
} }
} }
target->Release();
source->Release();
return done; return done;
} }
// WIPE: BURN --------------------------------------------------------------
//========================================================================== //==========================================================================
// //
// D3DFB :: Wiper_Burn Constructor // D3DFB :: Wiper_Burn Constructor
@ -593,12 +647,17 @@ bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
} }
// Put the initial screen back to the buffer. // Put the initial screen back to the buffer.
IDirect3DSurface9 *source, *target; IDirect3DSurface9 *source = NULL, *target;
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) && if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target))) SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
{ {
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL); fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
target->Release();
}
if (source != NULL)
{
source->Release();
} }
// Burn the new screen on top of it. // Burn the new screen on top of it.

View file

@ -418,7 +418,7 @@ static void I_CheckGUICapture ()
void I_CheckNativeMouse (bool preferNative) void I_CheckNativeMouse (bool preferNative)
{ {
bool wantNative = !HaveFocus || bool wantNative = !HaveFocus ||
((!screen || !screen->IsFullscreen()) && (GUICapture || paused || preferNative || !use_mouse || demoplayback)); ((!screen || !screen->IsFullscreen()) && (gamestate != GS_LEVEL || GUICapture || paused || preferNative || !use_mouse || demoplayback));
//Printf ("%d %d %d %d\n", HaveFocus, GetFocus() == Window, AppActive, GetForegroundWindow() == Window); //Printf ("%d %d %d %d\n", HaveFocus, GetFocus() == Window, AppActive, GetForegroundWindow() == Window);

View file

@ -236,7 +236,7 @@ public:
bool PaintToWindow (); bool PaintToWindow ();
void SetVSync (bool vsync); void SetVSync (bool vsync);
void SetBlendingRect (int x1, int y1, int x2, int y2); void SetBlendingRect (int x1, int y1, int x2, int y2);
bool Begin2D (); bool Begin2D (bool copy3d);
FNativeTexture *CreateTexture (FTexture *gametex); FNativeTexture *CreateTexture (FTexture *gametex);
FNativeTexture *CreatePalette (FRemapTable *remap); FNativeTexture *CreatePalette (FRemapTable *remap);
void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags); void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags);
@ -268,7 +268,7 @@ private:
void KillNativePals(); void KillNativePals();
void KillNativeTexs(); void KillNativeTexs();
void DrawLetterbox(); void DrawLetterbox();
void Draw3DPart(); void Draw3DPart(bool copy3d);
bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms); bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms);
void SetColorOverlay(DWORD color, float alpha); void SetColorOverlay(DWORD color, float alpha);
void DoWindowedGamma(); void DoWindowedGamma();