diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 59ea2fa435..b1fe9e6b15 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 6a9927e0fe..3b58cdb9dd 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 7e4e3b99a7..346c49dda4 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 cda905cde2..6ad2b71e3c 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 b70a08bd2b..b3885680c7 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 3de416cf3d..b5cf247001 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 f284613a1a..61a0d45a30 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 fc4aff161a..8f0725d988 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);