From 51461aa010d9f1478008fed4eaac2dc170437293 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 6 Jan 2008 04:03:33 +0000 Subject: [PATCH] - Added back the code to allow some variation to the players' shades when players are on teams. - Set TEAM_None back to 255. Since a player's team has already been accessible through ACS, needlessly redefining this is a bad thing to do, since it can break existing maps. 255 different teams should still be more than enough. - Fixed: At certain resolutions, there was a one pixel row between the status bar and the rest of the screen, thanks to rounding error. - Added automatic batching of quads to D3DFB. Screens with a lot of text are ever-so-slightly faster now, though still only about half the speed of sofware-only text. I suppose the only way to see a marked improvement is going to be by stuffing multiple glyphs in a single texture. - Fixed: Crosshairgrow's animation was not framerate-independent. SVN r668 (trunk) --- docs/rh-log.txt | 16 +- src/b_game.cpp | 2 +- src/d_netinf.h | 2 +- src/d_netinfo.cpp | 20 +- src/g_shared/shared_sbar.cpp | 22 +- src/teaminfo.h | 2 +- src/win32/fb_d3d9.cpp | 403 +++++++++++++++++++++++++++++------ src/win32/fb_d3d9_shaders.h | 79 ++++--- src/win32/fb_d3d9_wipe.cpp | 2 + src/win32/win32iface.h | 31 ++- 10 files changed, 452 insertions(+), 127 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 1358f434a..acd7b1157 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,17 @@ +January 6, 2008 +- Added back the code to allow some variation to the players' shades when + players are on teams. +- Set TEAM_None back to 255. Since a player's team has already been accessible + through ACS, needlessly redefining this is a bad thing to do, since it can + break existing maps. 255 different teams should still be more than enough. +- Fixed: At certain resolutions, there was a one pixel row between the status + bar and the rest of the screen, thanks to rounding error. +- Added automatic batching of quads to D3DFB. Screens with a lot of text are + ever-so-slightly faster now, though still only about half the speed of + sofware-only text. I suppose the only way to see a marked improvement is + going to be by stuffing multiple glyphs in a single texture. +- Fixed: Crosshairgrow's animation was not framerate-independent. + January 5, 2008 (Changes by Graf Zahl) - Added: Automap markers are stored in savegames now. Also moved the call to AM_LevelInit to its proper place in G_DoLoadLevel, right after @@ -19,7 +33,7 @@ January 4, 2008 of these ever, and they can be statically generated, so I simplified it some more. - Added Blzut3's latest SBARINFO patch: - * Fixed a massive memory leak in SBARINFO. The leak also lead to progressive + * Fixed a massive memory leak in SBARINFO. The leak also lead to progressive CPU usage. * Fixed: Playerclass didn't work in SBARINFO. * Fixed: Artiflash was improperly initialized causing it not to display the diff --git a/src/b_game.cpp b/src/b_game.cpp index 8f02ce692..4746f8737 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -588,7 +588,7 @@ bool DCajunMaster::LoadBots () case BOTCFG_TEAM: { char teamstr[16]; - unsigned int teamnum; + BYTE teamnum; SC_MustGetString (); if (IsNum (sc_String)) diff --git a/src/d_netinf.h b/src/d_netinf.h index 4e8cac104..beb9e789e 100644 --- a/src/d_netinf.h +++ b/src/d_netinf.h @@ -55,7 +55,7 @@ int D_PlayerClassToInt (const char *classname); struct userinfo_s { char netname[MAXPLAYERNAME+1]; - int team; + BYTE team; int aimdist; int color; int skin; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 1948056b9..7f519df22 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -54,6 +54,7 @@ #include "m_random.h" #include "teaminfo.h" #include "r_translate.h" +#include "templates.h" static FRandom pr_pickteam ("PickRandomTeam"); @@ -185,10 +186,25 @@ int D_PlayerClassToInt (const char *classname) void D_GetPlayerColor (int player, float *h, float *s, float *v) { userinfo_t *info = &players[player].userinfo; - int color = teamplay ? teams[info->team].playercolor : info->color; + int color = info->color; RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, h, s, v); + + if (teamplay && TEAMINFO_IsValidTeam(info->team)) + { + // In team play, force the player to use the team's hue + // and adjust the saturation and value so that the team + // hue is visible in the final color. + float ts, tv; + int tcolor = teams[info->team].playercolor; + + RGBtoHSV (RPART(tcolor)/255.f, GPART(tcolor)/255.f, BPART(tcolor)/255.f, + h, &ts, &tv); + + *s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f); + *v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f); + } } // Find out which teams are present. If there is only one, @@ -284,7 +300,7 @@ static void UpdateTeam (int pnum, int team, bool update) int oldteam; - if (team < TEAM_None) + if (team < 0) { team = TEAM_None; } diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 032f3d530..99833823e 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -203,6 +203,9 @@ void FBaseStatusBar::SetScaled (bool scale) ST_X = 0; ST_Y = 200 - RelTop; ::ST_Y = Scale (ST_Y, SCREENHEIGHT, 200); + // If this is odd, add one to make it even and close the gap between the + // status bar and the rest of the screen + ::ST_Y += (::ST_Y & 1); Displacement = 0; } ::ST_X = ST_X; @@ -269,6 +272,16 @@ void FBaseStatusBar::Tick () } msg = next; } + + // If the crosshair has been enlarged, shrink it. + if (CrosshairSize > FRACUNIT) + { + CrosshairSize -= XHAIRSHRINKSIZE; + if (CrosshairSize < FRACUNIT) + { + CrosshairSize = FRACUNIT; + } + } } //--------------------------------------------------------------------------- @@ -974,15 +987,6 @@ void FBaseStatusBar::DrawCrosshair () fixed_t size; int w, h; - if (CrosshairSize > FRACUNIT) - { - CrosshairSize -= XHAIRSHRINKSIZE; - if (CrosshairSize < FRACUNIT) - { - CrosshairSize = FRACUNIT; - } - } - // Don't draw the crosshair in chasecam mode if (players[consoleplayer].cheats & CF_CHASECAM) return; diff --git a/src/teaminfo.h b/src/teaminfo.h index 3059a3378..bd169e641 100644 --- a/src/teaminfo.h +++ b/src/teaminfo.h @@ -35,7 +35,7 @@ #ifndef __TEAMINFO_H__ #define __TEAMINFO_H__ -#define TEAM_None -1 +#define TEAM_None 255 struct TEAMINFO { diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 65d9cf36d..11240a0aa 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -76,6 +76,9 @@ // The number of line endpoints for the line vertex buffer. #define NUM_LINE_VERTS 10240 +// The number of quads we can batch together. +#define MAX_QUAD_BATCH 1024 + // TYPES ------------------------------------------------------------------- IMPLEMENT_CLASS(D3DFB) @@ -121,6 +124,26 @@ public: int RoundedPaletteSize; }; +// Flags for a buffered quad +enum +{ + BQF_GamePalette = 1, + BQF_ShadedPalette = 2, + BQF_CustomPalette = 3, + BQF_StencilPalette = 4, + BQF_Paletted = 7, + BQF_Bilinear = 8, +}; + +// Shaders for a buffered quad +enum +{ + BQS_PalTex, + BQS_Plain, + BQS_PlainStencil, + BQS_ColorOnly +}; + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -166,6 +189,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) D3DDevice = NULL; LineBuffer = NULL; + QuadBuffer = NULL; FBTexture = NULL; TempRenderTexture = NULL; InitialWipeScreen = NULL; @@ -194,6 +218,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) GatheringWipeScreen = false; ScreenWipe = NULL; InScene = false; + QuadExtra = new BufferedQuad[MAX_QUAD_BATCH]; Gamma = 1.0; FlashColor0 = 0; @@ -261,6 +286,7 @@ D3DFB::~D3DFB () { D3DDevice->Release(); } + delete[] QuadExtra; } // Called after initial device creation and reset, when everything is set @@ -467,6 +493,11 @@ void D3DFB::ReleaseDefaultPoolItems() InitialWipeScreen->Release(); InitialWipeScreen = NULL; } + if (QuadBuffer != NULL) + { + QuadBuffer->Release(); + QuadBuffer = NULL; + } if (LineBuffer != NULL) { LineBuffer->Release(); @@ -615,6 +646,12 @@ bool D3DFB::CreateVertexes () return false; } LineBatchPos = -1; + if (FAILED(D3DDevice->CreateVertexBuffer(sizeof(FBVERTEX)*MAX_QUAD_BATCH*6, + D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_FBVERTEX, D3DPOOL_DEFAULT, &QuadBuffer, NULL))) + { + return false; + } + QuadBatchPos = -1; return true; } @@ -766,6 +803,7 @@ void D3DFB::Update () if (InScene) { DrawRateStuff(); + EndQuadBatch(); // Make sure all quads are drawn DoWindowedGamma(); D3DDevice->EndScene(); D3DDevice->Present(NULL, NULL, NULL, NULL); @@ -917,7 +955,8 @@ void D3DFB::Draw3DPart(bool copy3d) } SetTexture (0, FBTexture); - SetPaletteTexture(PaletteTexture, 256, false); + SetPaletteTexture(PaletteTexture, 256); + SetPixelShader(PalTexShader); D3DDevice->SetFVF (D3DFVF_FBVERTEX); memset(Constant, 0, sizeof(Constant)); SetAlphaBlend(FALSE); @@ -1460,9 +1499,7 @@ 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); return; } - int offs = GatheringWipeScreen ? 0 : LBOffsetI; - D3DRECT rect = { left, top + offs, right, bottom + offs }; - D3DDevice->Clear(1, &rect, D3DCLEAR_TARGET, color | 0xFF000000, 1.f, 0); + AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); } //========================================================================== @@ -1486,27 +1523,11 @@ void D3DFB::Dim (PalEntry color, float amount, int x1, int y1, int w, int h) { return; } - if (amount >= 1) + if (amount > 1) { - D3DRECT rect = { x1, y1, x1 + w, y1 + h }; - D3DDevice->Clear(1, &rect, D3DCLEAR_TARGET, color | 0xFF000000, 1.f, 0); - } - else - { - float x = float(x1) - 0.5f; - float y = float(y1) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset); - D3DCOLOR d3dcolor = color | (int(amount * 255) << 24); - FBVERTEX verts[4] = - { - { x, y, 0, 1, d3dcolor }, - { x+w, y, 0, 1, d3dcolor }, - { x+w, y+h, 0, 1, d3dcolor }, - { x, y+h, 0, 1, d3dcolor } - }; - SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - SetPixelShader(ColorOnlyShader); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &verts, sizeof(FBVERTEX)); + amount = 1; } + AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); } //========================================================================== @@ -1521,6 +1542,7 @@ void D3DFB::BeginLineDrawing() { return; } + EndQuadBatch(); // Make sure all quads have been drawn first LineBuffer->Lock(0, 0, (void **)&LineData, D3DLOCK_DISCARD); LineBatchPos = 0; } @@ -1661,6 +1683,8 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi return; } + CheckQuadBatch(); + float xscale = float(parms.destwidth) / parms.texwidth / 65536.f; float yscale = float(parms.destheight) / parms.texheight / 65536.f; float x0 = float(parms.x) / 65536.f - float(parms.left) * xscale; @@ -1706,6 +1730,19 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi u1 -= float(x1 - parms.rclip) * uscale / xscale; x1 = float(parms.rclip); } + parms.bilinear = false; + + D3DCOLOR color0, color1; + if (!SetStyle(tex, parms, color0, color1, QuadExtra[QuadBatchPos])) + { + return; + } + + QuadExtra[QuadBatchPos].Texture = tex; + if (parms.bilinear) + { + QuadExtra[QuadBatchPos].Flags |= BQF_Bilinear; + } float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; x0 -= 0.5f; @@ -1713,23 +1750,260 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi x1 -= 0.5f; y1 -= yoffs; - D3DCOLOR color0, color1; - parms.bilinear = false; - if (!SetStyle(tex, parms, color0, color1)) + FBVERTEX *vert = &QuadData[QuadBatchPos * 6]; + + vert[3].x = vert[0].x = x0; + vert[3].y = vert[0].y = y0; + vert[3].z = vert[0].z = 0; + vert[3].rhw = vert[0].rhw = 1; + vert[3].color0 = vert[0].color0 = color0; + vert[3].color1 = vert[0].color1 = color1; + vert[3].tu = vert[0].tu = u0; + vert[3].tv = vert[0].tv = v0; + + vert[1].x = x1; + vert[1].y = y0; + vert[1].z = 0; + vert[1].rhw = 1; + vert[1].color0 = color0; + vert[1].color1 = color1; + vert[1].tu = u1; + vert[1].tv = v0; + + vert[4].x = vert[2].x = x1; + vert[4].y = vert[2].y = y1; + vert[4].z = vert[2].z = 0; + vert[4].rhw = vert[2].rhw = 1; + vert[4].color0 = vert[2].color0 = color0; + vert[4].color1 = vert[2].color1 = color1; + vert[4].tu = vert[2].tu = u1; + vert[4].tv = vert[2].tv = v1; + + vert[5].x = x0; + vert[5].y = y1; + vert[5].z = 0; + vert[5].rhw = 1; + vert[5].color0 = color0; + vert[5].color1 = color1; + vert[5].tu = u0; + vert[5].tv = v1; + + QuadBatchPos++; +} + +//========================================================================== +// +// D3DFB :: AddColorOnlyQuad +// +// Adds a single-color, untextured quad to the batch. +// +//========================================================================== + +void D3DFB::AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color) +{ + BufferedQuad *quad; + FBVERTEX *verts; + + CheckQuadBatch(); + quad = &QuadExtra[QuadBatchPos]; + verts = &QuadData[QuadBatchPos * 6]; + + float x = float(left) - 0.5f; + float y = float(top) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset); + + quad->Flags = 0; + quad->ShaderNum = BQS_ColorOnly; + if ((color & 0xFF000000) == 0xFF000000) + { + quad->SrcBlend = 0; + quad->DestBlend = 0; + } + else + { + quad->SrcBlend = D3DBLEND_SRCALPHA; + quad->DestBlend = D3DBLEND_INVSRCALPHA; + } + quad->Palette = NULL; + quad->Texture = NULL; + + verts[3].x = verts[0].x = x; + verts[3].y = verts[0].y = y; + verts[3].z = verts[0].z = 0; + verts[3].rhw = verts[0].rhw = 1; + verts[3].color0 = verts[0].color0 = color; + verts[3].color1 = verts[0].color1 = 0; + verts[3].tu = verts[0].tu = 0; + verts[3].tv = verts[0].tv = 0; + + verts[1].x = x + width; + verts[1].y = y; + verts[1].z = 0; + verts[1].rhw = 1; + verts[1].color0 = color; + verts[1].color1 = 0; + verts[1].tu = 0; + verts[1].tv = 0; + + verts[4].x = verts[2].x = x + width; + verts[4].y = verts[2].y = y + height; + verts[4].z = verts[2].z = 0; + verts[4].rhw = verts[2].rhw = 1; + verts[4].color0 = verts[2].color0 = color; + verts[4].color1 = verts[2].color1 = 0; + verts[4].tu = verts[2].tu = 0; + verts[4].tv = verts[2].tv = 0; + + verts[5].x = x; + verts[5].y = y + height; + verts[5].z = 0; + verts[5].rhw = 1; + verts[5].color0 = color; + verts[5].color1 = 0; + verts[5].tu = 0; + verts[5].tv = 0; + + QuadBatchPos++; +} + +//========================================================================== +// +// D3DFB :: CheckQuadBatch +// +// Make sure there's enough room in the batch for one more quad. +// +//========================================================================== + +void D3DFB::CheckQuadBatch() +{ + if (QuadBatchPos == MAX_QUAD_BATCH) + { + EndQuadBatch(); + } + if (QuadBatchPos < 0) + { + BeginQuadBatch(); + } +} + +//========================================================================== +// +// D3DFB :: BeginQuadBatch +// +// Locks the vertex buffer for quads and sets the cursor to 0. +// +//========================================================================== + +void D3DFB::BeginQuadBatch() +{ + if (In2D < 2 || !InScene || QuadBatchPos >= 0) { return; } + QuadBuffer->Lock(0, 0, (void **)&QuadData, D3DLOCK_DISCARD); + QuadBatchPos = 0; +} - FBVERTEX verts[4] = +//========================================================================== +// +// D3DFB :: EndQuadBatch +// +// Draws all the quads that have been batched up. +// +//========================================================================== + +void D3DFB::EndQuadBatch() +{ + if (In2D < 2 || !InScene || QuadBatchPos < 0) { - { x0, y0, 0, 1, color0, color1, u0, v0 }, - { x1, y0, 0, 1, color0, color1, u1, v0 }, - { x1, y1, 0, 1, color0, color1, u1, v1 }, - { x0, y1, 0, 1, color0, color1, u0, v1 } - }; + return; + } + QuadBuffer->Unlock(); + if (QuadBatchPos == 0) + { + QuadBatchPos = -1; + return; + } + D3DDevice->SetStreamSource(0, QuadBuffer, 0, sizeof(FBVERTEX)); + for (int i = 0; i < QuadBatchPos; ) + { + const BufferedQuad *quad = &QuadExtra[i]; + int j; - SetTexture(0, tex->Tex); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &verts, sizeof(FBVERTEX)); + // Quads with matching parameters should be done with a single + // DrawPrimitive call. + for (j = i + 1; j < QuadBatchPos; ++j) + { + const BufferedQuad *q2 = &QuadExtra[j]; + if (quad->Texture != q2->Texture || + quad->Group1 != q2->Group1 || + quad->Palette != q2->Palette) + { + break; + } + } + + // Set the palette (if one) + if ((quad->Flags & BQF_Paletted) == BQF_GamePalette) + { + SetPaletteTexture(PaletteTexture, 256); + } + else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette) + { + SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize); + } + else if ((quad->Flags & BQF_Paletted) == BQF_ShadedPalette) + { + SetPaletteTexture(ShadedPaletteTexture, 256); + } + else if ((quad->Flags & BQF_Paletted) == BQF_StencilPalette) + { + SetPaletteTexture(StencilPaletteTexture, 256); + } + // Set paletted bilinear filtering (IF IT WORKED RIGHT!) + if (quad->Flags & (BQF_Paletted | BQF_Bilinear)) + { + SetPalTexBilinearConstants(quad->Texture); + } + + // Set the alpha blending + if (quad->SrcBlend != 0) + { + SetAlphaBlend(TRUE, D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend)); + } + else + { + SetAlphaBlend(FALSE); + } + + // Set the pixel shader + if (quad->ShaderNum == BQS_PalTex) + { + SetPixelShader(!(quad->Flags & BQF_Bilinear) ? PalTexShader : PalTexBilinearShader); + } + else if (quad->ShaderNum == BQS_Plain) + { + SetPixelShader(PlainShader); + } + else if (quad->ShaderNum == BQS_PlainStencil) + { + SetPixelShader(PlainStencilShader); + } + else if (quad->ShaderNum == BQS_ColorOnly) + { + SetPixelShader(ColorOnlyShader); + } + + // Set the texture + if (quad->Texture != NULL) + { + SetTexture(0, quad->Texture->Tex); + } + + // Draw the quad + D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, i * 6, 2 * (j - i)); + i = j; + } + QuadBatchPos = -1; } //========================================================================== @@ -1740,7 +2014,7 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi // //========================================================================== -bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1) +bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedQuad &quad) { D3DFORMAT fmt = tex->GetTexFormat(); ERenderStyle style = parms.style; @@ -1768,6 +2042,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & } stencilling = false; + quad.Palette = NULL; switch (style) { @@ -1777,12 +2052,10 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & { color0 = 0; color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24); - SetPaletteTexture(ShadedPaletteTexture, 256, parms.bilinear); - if (parms.bilinear) - { - SetPalTexBilinearConstants(tex); - } - SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); + quad.Flags = BQF_ShadedPalette; + quad.SrcBlend = D3DBLEND_SRCALPHA; + quad.DestBlend = D3DBLEND_INVSRCALPHA; + quad.ShaderNum = BQS_PalTex; return true; } return false; @@ -1824,24 +2097,24 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & // turning off the alpha blend. if (!parms.masked && style == STYLE_Normal) { - SetAlphaBlend(FALSE); + quad.SrcBlend = 0; + quad.DestBlend = 0; SetColorOverlay(parms.colorOverlay, 1, color0, color1); if (fmt == D3DFMT_L8 && !tex->IsGray) { - SetPaletteTexture(PaletteTexture, 256, parms.bilinear); - if (parms.bilinear) - { - SetPalTexBilinearConstants(tex); - } + quad.Flags = BQF_GamePalette; + quad.ShaderNum = BQS_PalTex; } else { - SetPixelShader(PlainShader); + quad.Flags = 0; + quad.ShaderNum = BQS_Plain; } } else { - SetAlphaBlend(TRUE, fglevel, bglevel); + quad.SrcBlend = fglevel; + quad.DestBlend = bglevel; if (!stencilling) { @@ -1849,29 +2122,25 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & { if (parms.remap != NULL) { - D3DPal *pal = reinterpret_cast(parms.remap->GetNative()); - SetPaletteTexture(pal->Tex, pal->RoundedPaletteSize, parms.bilinear); - if (parms.bilinear) - { - SetPalTexBilinearConstants(tex); - } + quad.Flags = BQF_CustomPalette; + quad.Palette = reinterpret_cast(parms.remap->GetNative()); + quad.ShaderNum = BQS_PalTex; } else if (tex->IsGray) { - SetPixelShader(PlainShader); + quad.Flags = 0; + quad.ShaderNum = BQS_Plain; } else { - SetPaletteTexture(PaletteTexture, 256, parms.bilinear); - if (parms.bilinear) - { - SetPalTexBilinearConstants(tex); - } + quad.Flags = BQF_GamePalette; + quad.ShaderNum = BQS_PalTex; } } else { - SetPixelShader(PlainShader); + quad.Flags = 0; + quad.ShaderNum = BQS_Plain; } SetColorOverlay(parms.colorOverlay, alpha, color0, color1); } @@ -1881,12 +2150,13 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24); if (fmt == D3DFMT_L8) { - // Doesn't seem to be much point in allowing bilinear with a stencil - SetPaletteTexture(StencilPaletteTexture, 256, false); + quad.Flags = BQF_StencilPalette; + quad.ShaderNum = BQS_PalTex; } else { - SetPixelShader(PlainStencilShader); + quad.Flags = 0; + quad.ShaderNum = BQS_PlainStencil; } } } @@ -1979,7 +2249,7 @@ void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture) } } -void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, INTBOOL bilinear) +void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count) { if (count == 256 || SM14) { @@ -2003,7 +2273,6 @@ void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, INTBOOL bil SetConstant(2, 255 * fcount, 0.5f * fcount, 0, 0); } SetTexture(1, texture); - SetPixelShader(!bilinear ? PalTexShader : PalTexBilinearShader); } void D3DFB::SetPalTexBilinearConstants(D3DTex *tex) diff --git a/src/win32/fb_d3d9_shaders.h b/src/win32/fb_d3d9_shaders.h index cc4135d00..9ad4e5ee7 100644 --- a/src/win32/fb_d3d9_shaders.h +++ b/src/win32/fb_d3d9_shaders.h @@ -108,8 +108,6 @@ const DWORD PalTexShader20Def[] = #if HLSL_SOURCE_CODE sampler2D Image : register(s0); sampler2D Palette : register(s1); -float4 Flash : register(c0); -float4 InvFlash : register(c1); float4 PaletteMod : register(c2); //#define texture_size_x 512.0f @@ -123,7 +121,7 @@ float4 size_a : register(c3); // 0, texel_size_y, texel_size_y, texel_size_x float4 size_b : register(c4); -float4 main (float2 texCoord : TEXCOORD0) : COLOR +float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR { float2 f = frac (texCoord.xy * size_a/*float2(texture_size_x, texture_size_y)*/); @@ -155,14 +153,12 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR // // Generated by Microsoft (R) HLSL Shader Compiler 9.19.949.2111 // -// fxc paltex_bilinear.ps /Tps_2_0 /VnPalTexBilinearDef /Fhpaltex_bilinea +// fxc paltex_bilinear.ps /Tps_2_0 /VnPalTexBilinearDef /Fhpaltex_bilinear.h // // // Parameters: // -// float4 Flash; // sampler2D Image; -// float4 InvFlash; // sampler2D Palette; // float4 PaletteMod; // float4 size_a; @@ -173,8 +169,6 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR // // Name Reg Size // ------------ ----- ---- -// Flash c0 1 -// InvFlash c1 1 // PaletteMod c2 1 // size_a c3 1 // size_b c4 1 @@ -184,6 +178,8 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR ps_2_0 dcl t0.xy + dcl v0 + dcl v1 dcl_2d s0 dcl_2d s1 add r0.xy, t0, c4 @@ -206,8 +202,8 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR lrp r5, r4.x, r1, r0 lrp r0, r4.x, r2, r3 lrp r1, r4.y, r5, r0 - mov r0, c1 - mad r0, r1, r0, c0 + mov r0, v1 + mad r0, r1, r0, v0 mov oC0, r0 // approximately 23 instruction slots used (8 texture, 15 arithmetic) @@ -215,38 +211,37 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR const DWORD PalTexBilinearDef[] = { - 0xffff0200, 0x0050fffe, 0x42415443, 0x0000001c, 0x00000109, 0xffff0200, - 0x00000007, 0x0000001c, 0x20000100, 0x00000102, 0x000000a8, 0x00000002, - 0x00020001, 0x000000b0, 0x00000000, 0x000000c0, 0x00000003, 0x00020001, - 0x000000c8, 0x00000000, 0x000000d8, 0x00010002, 0x00060001, 0x000000b0, - 0x00000000, 0x000000e1, 0x00010003, 0x00060001, 0x000000c8, 0x00000000, - 0x000000e9, 0x00020002, 0x000a0001, 0x000000b0, 0x00000000, 0x000000f4, - 0x00030002, 0x000e0001, 0x000000b0, 0x00000000, 0x000000fb, 0x00040002, - 0x00120001, 0x000000b0, 0x00000000, 0x73616c46, 0xabab0068, 0x00030001, - 0x00040001, 0x00000001, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, - 0x00010001, 0x00000001, 0x00000000, 0x46766e49, 0x6873616c, 0x6c615000, - 0x65747465, 0x6c615000, 0x65747465, 0x00646f4d, 0x657a6973, 0x7300615f, - 0x5f657a69, 0x73700062, 0x305f325f, 0x63694d00, 0x6f736f72, 0x28207466, - 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, - 0x39312e39, 0x3934392e, 0x3131322e, 0xabab0031, 0x0200001f, 0x80000000, - 0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, - 0xa00f0801, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40004, 0x03000002, - 0x80030001, 0xb0e40000, 0xa01b0004, 0x03000002, 0x80030002, 0xb0e40000, - 0xa01b0003, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, - 0x800f0001, 0x80e40001, 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, - 0xa0e40800, 0x03000042, 0x800f0003, 0xb0e40000, 0xa0e40800, 0x04000004, - 0x80010000, 0x80000000, 0xa0000002, 0xa0550002, 0x04000004, 0x80010001, - 0x80000001, 0xa0000002, 0xa0550002, 0x04000004, 0x80010002, 0x80000002, - 0xa0000002, 0xa0550002, 0x04000004, 0x80010003, 0x80000003, 0xa0000002, - 0xa0550002, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000042, - 0x800f0001, 0x80e40001, 0xa0e40801, 0x03000042, 0x800f0002, 0x80e40002, - 0xa0e40801, 0x03000042, 0x800f0003, 0x80e40003, 0xa0e40801, 0x03000005, - 0x80030004, 0xb0e40000, 0xa0e40003, 0x02000013, 0x80030004, 0x80e40004, - 0x04000012, 0x800f0005, 0x80000004, 0x80e40001, 0x80e40000, 0x04000012, - 0x800f0000, 0x80000004, 0x80e40002, 0x80e40003, 0x04000012, 0x800f0001, - 0x80550004, 0x80e40005, 0x80e40000, 0x02000001, 0x800f0000, 0xa0e40001, - 0x04000004, 0x800f0000, 0x80e40001, 0x80e40000, 0xa0e40000, 0x02000001, - 0x800f0800, 0x80e40000, 0x0000ffff + 0xffff0200, 0x0042fffe, 0x42415443, 0x0000001c, 0x000000d1, 0xffff0200, + 0x00000005, 0x0000001c, 0x20000100, 0x000000ca, 0x00000080, 0x00000003, + 0x00020001, 0x00000088, 0x00000000, 0x00000098, 0x00010003, 0x00060001, + 0x00000088, 0x00000000, 0x000000a0, 0x00020002, 0x000a0001, 0x000000ac, + 0x00000000, 0x000000bc, 0x00030002, 0x000e0001, 0x000000ac, 0x00000000, + 0x000000c3, 0x00040002, 0x00120001, 0x000000ac, 0x00000000, 0x67616d49, + 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, 0x656c6150, + 0x00657474, 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, + 0x00000001, 0x00000000, 0x657a6973, 0x7300615f, 0x5f657a69, 0x73700062, + 0x305f325f, 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c, + 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39312e39, 0x3934392e, + 0x3131322e, 0xabab0031, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, + 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0x900f0001, 0x0200001f, + 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x03000002, + 0x80030000, 0xb0e40000, 0xa0e40004, 0x03000002, 0x80030001, 0xb0e40000, + 0xa01b0004, 0x03000002, 0x80030002, 0xb0e40000, 0xa01b0003, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001, + 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042, + 0x800f0003, 0xb0e40000, 0xa0e40800, 0x04000004, 0x80010000, 0x80000000, + 0xa0000002, 0xa0550002, 0x04000004, 0x80010001, 0x80000001, 0xa0000002, + 0xa0550002, 0x04000004, 0x80010002, 0x80000002, 0xa0000002, 0xa0550002, + 0x04000004, 0x80010003, 0x80000003, 0xa0000002, 0xa0550002, 0x03000042, + 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000042, 0x800f0001, 0x80e40001, + 0xa0e40801, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40801, 0x03000042, + 0x800f0003, 0x80e40003, 0xa0e40801, 0x03000005, 0x80030004, 0xb0e40000, + 0xa0e40003, 0x02000013, 0x80030004, 0x80e40004, 0x04000012, 0x800f0005, + 0x80000004, 0x80e40001, 0x80e40000, 0x04000012, 0x800f0000, 0x80000004, + 0x80e40002, 0x80e40003, 0x04000012, 0x800f0001, 0x80550004, 0x80e40005, + 0x80e40000, 0x02000001, 0x800f0000, 0x90e40001, 0x04000004, 0x800f0000, + 0x80e40001, 0x80e40000, 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, + 0x0000ffff }; // A shader that doesn't look up colors from a palette. --------------------- diff --git a/src/win32/fb_d3d9_wipe.cpp b/src/win32/fb_d3d9_wipe.cpp index 61ea53647..db0d4b7f6 100644 --- a/src/win32/fb_d3d9_wipe.cpp +++ b/src/win32/fb_d3d9_wipe.cpp @@ -295,6 +295,8 @@ void D3DFB::WipeEndScreen() Begin2D(true); } + EndQuadBatch(); // Make sure all quads have been drawn. + // Don't do anything if there is no ending point. if (OldRenderTarget == NULL) { diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index e4fb3bac1..2c9530200 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -264,6 +264,22 @@ private: }; #define D3DFVF_FBVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1) + struct BufferedQuad + { + union + { + struct + { + BYTE Flags; + BYTE ShaderNum; + BYTE SrcBlend, DestBlend; + }; + DWORD Group1; + }; + D3DPal *Palette; + D3DTex *Texture; + }; + void SetInitialState(); bool CreateResources(); void ReleaseResources(); @@ -282,16 +298,20 @@ private: void KillNativeTexs(); void DrawLetterbox(); void Draw3DPart(bool copy3d); - bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1); + bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedQuad &quad); static void SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1); void DoWindowedGamma(); + void AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color); + void CheckQuadBatch(); + void BeginQuadBatch(); + void EndQuadBatch(); // State void SetAlphaBlend(BOOL enabled, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0)); void SetConstant(int cnum, float r, float g, float b, float a); void SetPixelShader(IDirect3DPixelShader9 *shader); void SetTexture(int tnum, IDirect3DTexture9 *texture); - void SetPaletteTexture(IDirect3DTexture9 *texture, int count, INTBOOL bilinear); + void SetPaletteTexture(IDirect3DTexture9 *texture, int count); void SetPalTexBilinearConstants(D3DTex *texture); BOOL AlphaBlendEnabled; @@ -332,8 +352,13 @@ private: IDirect3DTexture9 *ShadedPaletteTexture; IDirect3DVertexBuffer9 *LineBuffer; - int LineBatchPos; FBVERTEX *LineData; + int LineBatchPos; + + IDirect3DVertexBuffer9 *QuadBuffer; + FBVERTEX *QuadData; + BufferedQuad *QuadExtra; + int QuadBatchPos; IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader; IDirect3DPixelShader9 *PlainShader;