From 9839cbfc82c2596cac5b7511ec794f53f3d73168 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 9 Jan 2008 23:04:49 +0000 Subject: [PATCH] - Fixed: The mouse was being grabbed in windowed mode again. - Modified M_DrawFrame() and R_DrawTopBorder() so that they call FlatFill() to draw the edges of the frames. This at least seems a bit faster for hardware 2D. - Implemented FlatFill() for D3DFB. It seems to be exactly as fast as the default implementation that just calls DrawTexture() to tile the pieces onto the screen, so I'm not sure it was worth the bother. SVN r686 (trunk) --- docs/rh-log.txt | 9 ++- src/m_menu.cpp | 32 ++++------ src/r_draw.cpp | 34 +++++------ src/v_video.cpp | 23 ++++--- src/v_video.h | 2 +- src/win32/fb_d3d9.cpp | 132 ++++++++++++++++++++++++++++++++++++++++- src/win32/i_input.cpp | 16 +++-- src/win32/win32iface.h | 1 + 8 files changed, 190 insertions(+), 59 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 59ea2fa43..b1fe9e6b1 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,11 @@ January 9, 2008 +- Fixed: The mouse was being grabbed in windowed mode again. +- Modified M_DrawFrame() and R_DrawTopBorder() so that they call FlatFill() to + draw the edges of the frames. This at least seems a bit faster for hardware + 2D. +- Implemented FlatFill() for D3DFB. It seems to be exactly as fast as the + default implementation that just calls DrawTexture() to tile the pieces onto + the screen, so I'm not sure it was worth the bother. - Merged the separate line and quad vertex buffers in D3DFB back into a single vertex buffer, made line batching automatic, and added an index buffer for use when batching quads. The index buffer actually offered more of a @@ -16,7 +23,7 @@ January 8, 2008 because it used gametic for timing. - Added DoubleAmmoFactor as a skill property for the DF2_YES_DOUBLEAMMO flag. - Renumbered the dmflags2 entries to match Skulltag's again. -- Added Karate Chris's infinite ammo patch. +- Added Karate Chris's infinite inventory patch. January 7, 2008 - Added support for user-defined crosshairs in the Display Options menu. See diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 6a9927e0f..3b58cdb9d 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -1241,33 +1241,23 @@ static void M_DrawSaveLoadCommon () // frame graphics. The border is drawn outside the area, not in it. void M_DrawFrame (int left, int top, int width, int height) { - FTexture *p1, *p2; + FTexture *p; const gameborder_t *border = gameinfo.border; int offset = border->offset; - int size = border->size; - int x, y; + int right = left + width; + int bottom = top + height; // Draw top and bottom sides. - p1 = TexMan[border->t]; - p2 = TexMan[border->b]; - for (x = left; x < left + width; x += size) - { - if (x + size > left + width) - x = left + width - size; - screen->DrawTexture (p1, x, top - offset, TAG_DONE); - screen->DrawTexture (p2, x, top + height, TAG_DONE); - } + p = TexMan[border->t]; + screen->FlatFill(left, top - p->GetHeight(), right, top, p, true); + p = TexMan[border->b]; + screen->FlatFill(left, bottom, right, bottom + p->GetHeight(), p, true); // Draw left and right sides. - p1 = TexMan[border->l]; - p2 = TexMan[border->r]; - for (y = top; y < top + height; y += size) - { - if (y + size > top + height) - y = top + height - size; - screen->DrawTexture (p1, left - offset, y, TAG_DONE); - screen->DrawTexture (p2, left + width, y, TAG_DONE); - } + p = TexMan[border->l]; + screen->FlatFill(left - p->GetWidth(), top, left, bottom, p, true); + p = TexMan[border->r]; + screen->FlatFill(right, top, right + p->GetWidth(), bottom, p, true); // Draw beveled corners. screen->DrawTexture (TexMan[border->tl], left-offset, top-offset, TAG_DONE); diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 7e4e3b99a..346c49dda 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -1481,41 +1481,35 @@ int BorderTopRefresh; void R_DrawTopBorder () { - FTexture *p1, *p2; - int x, y; + FTexture *p; int offset; - int size; if (realviewwidth == SCREENWIDTH) return; offset = gameinfo.border->offset; - size = gameinfo.border->size; if (viewwindowy < 34) { R_DrawBorder (0, 0, viewwindowx, 34); R_DrawBorder (viewwindowx, 0, viewwindowx+realviewwidth, viewwindowy); R_DrawBorder (viewwindowx+realviewwidth, 0, SCREENWIDTH, 34); - p1 = TexMan(gameinfo.border->t); - for (x = viewwindowx; x < viewwindowx + realviewwidth; x += size) - { - screen->DrawTexture (p1, x, viewwindowy - offset, TAG_DONE); - } + p = TexMan(gameinfo.border->t); + screen->FlatFill(viewwindowx, viewwindowy - p->GetHeight(), + viewwindowx + realviewwidth, viewwindowy, p, true); - p1 = TexMan(gameinfo.border->l); - p2 = TexMan(gameinfo.border->r); - for (y = viewwindowy; y < 35; y += size) - { - screen->DrawTexture (p1, viewwindowx - offset, y, TAG_DONE); - screen->DrawTexture (p2, viewwindowx + realviewwidth, y, TAG_DONE); - } + p = TexMan(gameinfo.border->l); + screen->FlatFill(viewwindowx - p->GetWidth(), viewwindowy, + viewwindowx, 35, p, true); + p = TexMan(gameinfo.border->r); + screen->FlatFill(viewwindowx + realviewwidth, viewwindowy, + viewwindowx + realviewwidth + p->GetWidth(), 35, p, true); - p1 = TexMan(gameinfo.border->tl); - screen->DrawTexture (p1, viewwindowx-offset, viewwindowy - offset, TAG_DONE); + p = TexMan(gameinfo.border->tl); + screen->DrawTexture (p, viewwindowx-offset, viewwindowy - offset, TAG_DONE); - p1 = TexMan(gameinfo.border->tr); - screen->DrawTexture (p1, viewwindowx+realviewwidth, viewwindowy - offset, TAG_DONE); + p = TexMan(gameinfo.border->tr); + screen->DrawTexture (p, viewwindowx+realviewwidth, viewwindowy - offset, TAG_DONE); } else { diff --git a/src/v_video.cpp b/src/v_video.cpp index cda905cde..6ad2b71e3 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -224,25 +224,32 @@ bool DCanvas::IsValid () return false; } -// [RH] Fill an area with a 64x64 flat texture -// right and bottom are one pixel *past* the boundaries they describe. -void DCanvas::FlatFill (int left, int top, int right, int bottom, FTexture *src) +//========================================================================== +// +// DCanvas :: FlatFill +// +// Fill an area with a texture. If local_origin is false, then the origin +// used for the wrapping is (0,0). Otherwise, (left,right) is used. +// +//========================================================================== + +void DCanvas::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin) { int w = src->GetWidth(); int h = src->GetHeight(); - // Repeatedly draw the texture, left-to-right, top-to-bottom. The - // texture is positioned so that no matter what coordinates you pass - // to FlatFill, the origin of the repeating pattern is always (0,0). - for (int y = top / h * h; y < bottom; y += h) + // Repeatedly draw the texture, left-to-right, top-to-bottom. + for (int y = local_origin ? top : (top / h * h); y < bottom; y += h) { - for (int x = left / w * w; x < right; x += w) + for (int x = local_origin ? left : (left / w * w); x < right; x += w) { DrawTexture (src, x, y, DTA_ClipLeft, left, DTA_ClipRight, right, DTA_ClipTop, top, DTA_ClipBottom, bottom, + DTA_TopOffset, 0, + DTA_LeftOffset, 0, TAG_DONE); } } diff --git a/src/v_video.h b/src/v_video.h index b70a08bd2..b3885680c 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -161,7 +161,7 @@ public: virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h); // Fill an area with a texture - virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src); + virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false); // Set an area to a specified color virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 3de416cf3..b5cf24700 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -133,6 +133,7 @@ enum BQF_StencilPalette = 4, BQF_Paletted = 7, BQF_Bilinear = 8, + BQF_WrapUV = 16, }; // Shaders for a buffered quad @@ -300,8 +301,8 @@ void D3DFB::SetInitialState() Texture[0] = NULL; Texture[1] = NULL; - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); @@ -1727,6 +1728,115 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi IndexPos += 6; } +//========================================================================== +// +// D3DFB :: FlatFill +// +// Fills an area with a repeating copy of the texture. +// +//========================================================================== + +void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) +{ + if (In2D < 2) + { + Super::FlatFill(left, top, right, bottom, src, local_origin); + return; + } + if (!InScene) + { + return; + } + D3DTex *tex = static_cast(src->GetNative()); + if (tex == NULL) + { + return; + } + float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; + float x0 = float(left); + float y0 = float(top); + float x1 = float(right); + float y1 = float(bottom); + float itw = 1.f / float(src->GetWidth()); + float ith = 1.f / float(src->GetHeight()); + float xo = local_origin ? x0 : 0; + float yo = local_origin ? y0 : 0; + float u0 = (x0 - xo) * itw; + float v0 = (y0 - yo) * ith; + float u1 = (x1 - xo) * itw; + float v1 = (y1 - yo) * ith; + x0 -= 0.5f; + y0 -= yoffs; + x1 -= 0.5f; + y1 -= yoffs; + + CheckQuadBatch(); + + BufferedQuad *quad = &QuadExtra[QuadBatchPos]; + FBVERTEX *vert = &VertexData[VertexPos]; + + if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray) + { + quad->Flags = BQF_WrapUV | BQF_GamePalette; + quad->ShaderNum = BQS_PalTex; + } + else + { + quad->Flags = BQF_WrapUV; + quad->ShaderNum = BQS_Plain; + } + quad->SrcBlend = 0; + quad->DestBlend = 0; + quad->Palette = NULL; + quad->Texture = tex; + + vert[0].x = x0; + vert[0].y = y0; + vert[0].z = 0; + vert[0].rhw = 1; + vert[0].color0 = 0; + vert[0].color1 = 0xFFFFFFFF; + vert[0].tu = u0; + vert[0].tv = v0; + + vert[1].x = x1; + vert[1].y = y0; + vert[1].z = 0; + vert[1].rhw = 1; + vert[1].color0 = 0; + vert[1].color1 = 0xFFFFFFFF; + vert[1].tu = u1; + vert[1].tv = v0; + + vert[2].x = x1; + vert[2].y = y1; + vert[2].z = 0; + vert[2].rhw = 1; + vert[2].color0 = 0; + vert[2].color1 = 0xFFFFFFFF; + vert[2].tu = u1; + vert[2].tv = v1; + + vert[3].x = x0; + vert[3].y = y1; + vert[3].z = 0; + vert[3].rhw = 1; + vert[3].color0 = 0; + vert[3].color1 = 0xFFFFFFFF; + vert[3].tu = u0; + vert[3].tv = v1; + + IndexData[IndexPos ] = VertexPos; + IndexData[IndexPos + 1] = VertexPos + 1; + IndexData[IndexPos + 2] = VertexPos + 2; + IndexData[IndexPos + 3] = VertexPos; + IndexData[IndexPos + 4] = VertexPos + 2; + IndexData[IndexPos + 5] = VertexPos + 3; + + QuadBatchPos++; + VertexPos += 4; + IndexPos += 6;} + //========================================================================== // // D3DFB :: AddColorOnlyQuad @@ -1883,6 +1993,9 @@ void D3DFB::EndQuadBatch() } D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); D3DDevice->SetIndices(IndexBuffer); + bool uv_wrapped = false; + bool uv_should_wrap; + for (int i = 0; i < QuadBatchPos; ) { const BufferedQuad *quad = &QuadExtra[i]; @@ -1952,6 +2065,16 @@ void D3DFB::EndQuadBatch() SetPixelShader(ColorOnlyShader); } + // Set the texture clamp addressing mode + uv_should_wrap = !!(quad->Flags & BQF_WrapUV); + if (uv_wrapped != uv_should_wrap) + { + DWORD mode = uv_should_wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_BORDER; + uv_wrapped = uv_should_wrap; + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mode); + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mode); + } + // Set the texture if (quad->Texture != NULL) { @@ -1962,6 +2085,11 @@ void D3DFB::EndQuadBatch() D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4 * i, 4 * (j - i), 6 * i, 2 * (j - i)); i = j; } + if (uv_wrapped) + { + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + } QuadBatchPos = -1; VertexPos = -1; IndexPos = -1; diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index f284613a1..61a0d45a3 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -132,7 +132,7 @@ static void SetCursorState (int visible); static HRESULT InitJoystick (); static bool GUICapture; -static bool NativeMouse; +static int NativeMouse; static bool MakeMouseEvents; static POINT UngrabbedPointerPos; @@ -420,11 +420,10 @@ void I_CheckNativeMouse (bool preferNative) bool wantNative = !HaveFocus || ((!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\n", wantNative, preferNative, NativeMouse); - if (wantNative != NativeMouse) + if (int(wantNative) != NativeMouse) { - NativeMouse = wantNative; if (wantNative) { if (mousemode == dinput) @@ -442,7 +441,10 @@ void I_CheckNativeMouse (bool preferNative) { if (mousemode == win32) { - GetCursorPos (&UngrabbedPointerPos); + if (NativeMouse >= 0) + { + GetCursorPos (&UngrabbedPointerPos); + } GrabMouse_Win32 (); } else @@ -450,6 +452,7 @@ void I_CheckNativeMouse (bool preferNative) DI_Acquire (g_pMouse); } } + NativeMouse = wantNative; } } @@ -1397,7 +1400,8 @@ bool I_InitInput (void *hwnd) Printf ("I_InitInput\n"); atterm (I_ShutdownInput); - NativeMouse = true; + NativeMouse = -1; + GetCursorPos (&UngrabbedPointerPos); noidle = !!Args.CheckParm ("-noidle"); g_pdi = NULL; diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index fc4aff161..8f0725d98 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -244,6 +244,7 @@ public: void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags); void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color); void Dim (PalEntry color, float amount, int x1, int y1, int w, int h); + void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin); void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32 realcolor); void DrawPixel(int x, int y, int palcolor, uint32 rgbcolor); bool WipeStartScreen(int type);