- 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)
This commit is contained in:
Randy Heit 2008-01-06 04:03:33 +00:00
parent 935eeb06f1
commit 51461aa010
10 changed files with 452 additions and 127 deletions

View file

@ -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) January 5, 2008 (Changes by Graf Zahl)
- Added: Automap markers are stored in savegames now. Also moved the call - Added: Automap markers are stored in savegames now. Also moved the call
to AM_LevelInit to its proper place in G_DoLoadLevel, right after 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 of these ever, and they can be statically generated, so I simplified it some
more. more.
- Added Blzut3's latest SBARINFO patch: - 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. CPU usage.
* Fixed: Playerclass didn't work in SBARINFO. * Fixed: Playerclass didn't work in SBARINFO.
* Fixed: Artiflash was improperly initialized causing it not to display the * Fixed: Artiflash was improperly initialized causing it not to display the

View file

@ -588,7 +588,7 @@ bool DCajunMaster::LoadBots ()
case BOTCFG_TEAM: case BOTCFG_TEAM:
{ {
char teamstr[16]; char teamstr[16];
unsigned int teamnum; BYTE teamnum;
SC_MustGetString (); SC_MustGetString ();
if (IsNum (sc_String)) if (IsNum (sc_String))

View file

@ -55,7 +55,7 @@ int D_PlayerClassToInt (const char *classname);
struct userinfo_s struct userinfo_s
{ {
char netname[MAXPLAYERNAME+1]; char netname[MAXPLAYERNAME+1];
int team; BYTE team;
int aimdist; int aimdist;
int color; int color;
int skin; int skin;

View file

@ -54,6 +54,7 @@
#include "m_random.h" #include "m_random.h"
#include "teaminfo.h" #include "teaminfo.h"
#include "r_translate.h" #include "r_translate.h"
#include "templates.h"
static FRandom pr_pickteam ("PickRandomTeam"); 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) void D_GetPlayerColor (int player, float *h, float *s, float *v)
{ {
userinfo_t *info = &players[player].userinfo; 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, RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
h, s, v); 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, // 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; int oldteam;
if (team < TEAM_None) if (team < 0)
{ {
team = TEAM_None; team = TEAM_None;
} }

View file

@ -203,6 +203,9 @@ void FBaseStatusBar::SetScaled (bool scale)
ST_X = 0; ST_X = 0;
ST_Y = 200 - RelTop; ST_Y = 200 - RelTop;
::ST_Y = Scale (ST_Y, SCREENHEIGHT, 200); ::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; Displacement = 0;
} }
::ST_X = ST_X; ::ST_X = ST_X;
@ -269,6 +272,16 @@ void FBaseStatusBar::Tick ()
} }
msg = next; 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; fixed_t size;
int w, h; int w, h;
if (CrosshairSize > FRACUNIT)
{
CrosshairSize -= XHAIRSHRINKSIZE;
if (CrosshairSize < FRACUNIT)
{
CrosshairSize = FRACUNIT;
}
}
// Don't draw the crosshair in chasecam mode // Don't draw the crosshair in chasecam mode
if (players[consoleplayer].cheats & CF_CHASECAM) if (players[consoleplayer].cheats & CF_CHASECAM)
return; return;

View file

@ -35,7 +35,7 @@
#ifndef __TEAMINFO_H__ #ifndef __TEAMINFO_H__
#define __TEAMINFO_H__ #define __TEAMINFO_H__
#define TEAM_None -1 #define TEAM_None 255
struct TEAMINFO struct TEAMINFO
{ {

View file

@ -76,6 +76,9 @@
// The number of line endpoints for the line vertex buffer. // The number of line endpoints for the line vertex buffer.
#define NUM_LINE_VERTS 10240 #define NUM_LINE_VERTS 10240
// The number of quads we can batch together.
#define MAX_QUAD_BATCH 1024
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
IMPLEMENT_CLASS(D3DFB) IMPLEMENT_CLASS(D3DFB)
@ -121,6 +124,26 @@ public:
int RoundedPaletteSize; 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 -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -166,6 +189,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
D3DDevice = NULL; D3DDevice = NULL;
LineBuffer = NULL; LineBuffer = NULL;
QuadBuffer = NULL;
FBTexture = NULL; FBTexture = NULL;
TempRenderTexture = NULL; TempRenderTexture = NULL;
InitialWipeScreen = NULL; InitialWipeScreen = NULL;
@ -194,6 +218,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
GatheringWipeScreen = false; GatheringWipeScreen = false;
ScreenWipe = NULL; ScreenWipe = NULL;
InScene = false; InScene = false;
QuadExtra = new BufferedQuad[MAX_QUAD_BATCH];
Gamma = 1.0; Gamma = 1.0;
FlashColor0 = 0; FlashColor0 = 0;
@ -261,6 +286,7 @@ D3DFB::~D3DFB ()
{ {
D3DDevice->Release(); D3DDevice->Release();
} }
delete[] QuadExtra;
} }
// Called after initial device creation and reset, when everything is set // Called after initial device creation and reset, when everything is set
@ -467,6 +493,11 @@ void D3DFB::ReleaseDefaultPoolItems()
InitialWipeScreen->Release(); InitialWipeScreen->Release();
InitialWipeScreen = NULL; InitialWipeScreen = NULL;
} }
if (QuadBuffer != NULL)
{
QuadBuffer->Release();
QuadBuffer = NULL;
}
if (LineBuffer != NULL) if (LineBuffer != NULL)
{ {
LineBuffer->Release(); LineBuffer->Release();
@ -615,6 +646,12 @@ bool D3DFB::CreateVertexes ()
return false; return false;
} }
LineBatchPos = -1; 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; return true;
} }
@ -766,6 +803,7 @@ void D3DFB::Update ()
if (InScene) if (InScene)
{ {
DrawRateStuff(); DrawRateStuff();
EndQuadBatch(); // Make sure all quads are drawn
DoWindowedGamma(); DoWindowedGamma();
D3DDevice->EndScene(); D3DDevice->EndScene();
D3DDevice->Present(NULL, NULL, NULL, NULL); D3DDevice->Present(NULL, NULL, NULL, NULL);
@ -917,7 +955,8 @@ void D3DFB::Draw3DPart(bool copy3d)
} }
SetTexture (0, FBTexture); SetTexture (0, FBTexture);
SetPaletteTexture(PaletteTexture, 256, false); SetPaletteTexture(PaletteTexture, 256);
SetPixelShader(PalTexShader);
D3DDevice->SetFVF (D3DFVF_FBVERTEX); D3DDevice->SetFVF (D3DFVF_FBVERTEX);
memset(Constant, 0, sizeof(Constant)); memset(Constant, 0, sizeof(Constant));
SetAlphaBlend(FALSE); 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); Dim(color, APART(color)/255.f, left, top, right - left, bottom - top);
return; return;
} }
int offs = GatheringWipeScreen ? 0 : LBOffsetI; AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000);
D3DRECT rect = { left, top + offs, right, bottom + offs };
D3DDevice->Clear(1, &rect, D3DCLEAR_TARGET, color | 0xFF000000, 1.f, 0);
} }
//========================================================================== //==========================================================================
@ -1486,27 +1523,11 @@ void D3DFB::Dim (PalEntry color, float amount, int x1, int y1, int w, int h)
{ {
return; return;
} }
if (amount >= 1) if (amount > 1)
{ {
D3DRECT rect = { x1, y1, x1 + w, y1 + h }; amount = 1;
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));
} }
AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24));
} }
//========================================================================== //==========================================================================
@ -1521,6 +1542,7 @@ void D3DFB::BeginLineDrawing()
{ {
return; return;
} }
EndQuadBatch(); // Make sure all quads have been drawn first
LineBuffer->Lock(0, 0, (void **)&LineData, D3DLOCK_DISCARD); LineBuffer->Lock(0, 0, (void **)&LineData, D3DLOCK_DISCARD);
LineBatchPos = 0; LineBatchPos = 0;
} }
@ -1661,6 +1683,8 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
return; return;
} }
CheckQuadBatch();
float xscale = float(parms.destwidth) / parms.texwidth / 65536.f; float xscale = float(parms.destwidth) / parms.texwidth / 65536.f;
float yscale = float(parms.destheight) / parms.texheight / 65536.f; float yscale = float(parms.destheight) / parms.texheight / 65536.f;
float x0 = float(parms.x) / 65536.f - float(parms.left) * xscale; 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; u1 -= float(x1 - parms.rclip) * uscale / xscale;
x1 = float(parms.rclip); 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; float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset;
x0 -= 0.5f; x0 -= 0.5f;
@ -1713,23 +1750,260 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, int x, int y, uint32 tags_fi
x1 -= 0.5f; x1 -= 0.5f;
y1 -= yoffs; y1 -= yoffs;
D3DCOLOR color0, color1; FBVERTEX *vert = &QuadData[QuadBatchPos * 6];
parms.bilinear = false;
if (!SetStyle(tex, parms, color0, color1)) 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; 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 }, return;
{ x1, y0, 0, 1, color0, color1, u1, v0 }, }
{ x1, y1, 0, 1, color0, color1, u1, v1 }, QuadBuffer->Unlock();
{ x0, y1, 0, 1, color0, color1, u0, v1 } 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); // Quads with matching parameters should be done with a single
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &verts, sizeof(FBVERTEX)); // 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(); D3DFORMAT fmt = tex->GetTexFormat();
ERenderStyle style = parms.style; ERenderStyle style = parms.style;
@ -1768,6 +2042,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
} }
stencilling = false; stencilling = false;
quad.Palette = NULL;
switch (style) switch (style)
{ {
@ -1777,12 +2052,10 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
{ {
color0 = 0; color0 = 0;
color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24); color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24);
SetPaletteTexture(ShadedPaletteTexture, 256, parms.bilinear); quad.Flags = BQF_ShadedPalette;
if (parms.bilinear) quad.SrcBlend = D3DBLEND_SRCALPHA;
{ quad.DestBlend = D3DBLEND_INVSRCALPHA;
SetPalTexBilinearConstants(tex); quad.ShaderNum = BQS_PalTex;
}
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
return true; return true;
} }
return false; return false;
@ -1824,24 +2097,24 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
// turning off the alpha blend. // turning off the alpha blend.
if (!parms.masked && style == STYLE_Normal) if (!parms.masked && style == STYLE_Normal)
{ {
SetAlphaBlend(FALSE); quad.SrcBlend = 0;
quad.DestBlend = 0;
SetColorOverlay(parms.colorOverlay, 1, color0, color1); SetColorOverlay(parms.colorOverlay, 1, color0, color1);
if (fmt == D3DFMT_L8 && !tex->IsGray) if (fmt == D3DFMT_L8 && !tex->IsGray)
{ {
SetPaletteTexture(PaletteTexture, 256, parms.bilinear); quad.Flags = BQF_GamePalette;
if (parms.bilinear) quad.ShaderNum = BQS_PalTex;
{
SetPalTexBilinearConstants(tex);
}
} }
else else
{ {
SetPixelShader(PlainShader); quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
} }
} }
else else
{ {
SetAlphaBlend(TRUE, fglevel, bglevel); quad.SrcBlend = fglevel;
quad.DestBlend = bglevel;
if (!stencilling) if (!stencilling)
{ {
@ -1849,29 +2122,25 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
{ {
if (parms.remap != NULL) if (parms.remap != NULL)
{ {
D3DPal *pal = reinterpret_cast<D3DPal *>(parms.remap->GetNative()); quad.Flags = BQF_CustomPalette;
SetPaletteTexture(pal->Tex, pal->RoundedPaletteSize, parms.bilinear); quad.Palette = reinterpret_cast<D3DPal *>(parms.remap->GetNative());
if (parms.bilinear) quad.ShaderNum = BQS_PalTex;
{
SetPalTexBilinearConstants(tex);
}
} }
else if (tex->IsGray) else if (tex->IsGray)
{ {
SetPixelShader(PlainShader); quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
} }
else else
{ {
SetPaletteTexture(PaletteTexture, 256, parms.bilinear); quad.Flags = BQF_GamePalette;
if (parms.bilinear) quad.ShaderNum = BQS_PalTex;
{
SetPalTexBilinearConstants(tex);
}
} }
} }
else else
{ {
SetPixelShader(PlainShader); quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
} }
SetColorOverlay(parms.colorOverlay, alpha, color0, color1); 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); color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24);
if (fmt == D3DFMT_L8) if (fmt == D3DFMT_L8)
{ {
// Doesn't seem to be much point in allowing bilinear with a stencil quad.Flags = BQF_StencilPalette;
SetPaletteTexture(StencilPaletteTexture, 256, false); quad.ShaderNum = BQS_PalTex;
} }
else 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) 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); SetConstant(2, 255 * fcount, 0.5f * fcount, 0, 0);
} }
SetTexture(1, texture); SetTexture(1, texture);
SetPixelShader(!bilinear ? PalTexShader : PalTexBilinearShader);
} }
void D3DFB::SetPalTexBilinearConstants(D3DTex *tex) void D3DFB::SetPalTexBilinearConstants(D3DTex *tex)

View file

@ -108,8 +108,6 @@ const DWORD PalTexShader20Def[] =
#if HLSL_SOURCE_CODE #if HLSL_SOURCE_CODE
sampler2D Image : register(s0); sampler2D Image : register(s0);
sampler2D Palette : register(s1); sampler2D Palette : register(s1);
float4 Flash : register(c0);
float4 InvFlash : register(c1);
float4 PaletteMod : register(c2); float4 PaletteMod : register(c2);
//#define texture_size_x 512.0f //#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 // 0, texel_size_y, texel_size_y, texel_size_x
float4 size_b : register(c4); 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)*/); 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 // 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: // Parameters:
// //
// float4 Flash;
// sampler2D Image; // sampler2D Image;
// float4 InvFlash;
// sampler2D Palette; // sampler2D Palette;
// float4 PaletteMod; // float4 PaletteMod;
// float4 size_a; // float4 size_a;
@ -173,8 +169,6 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR
// //
// Name Reg Size // Name Reg Size
// ------------ ----- ---- // ------------ ----- ----
// Flash c0 1
// InvFlash c1 1
// PaletteMod c2 1 // PaletteMod c2 1
// size_a c3 1 // size_a c3 1
// size_b c4 1 // size_b c4 1
@ -184,6 +178,8 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR
ps_2_0 ps_2_0
dcl t0.xy dcl t0.xy
dcl v0
dcl v1
dcl_2d s0 dcl_2d s0
dcl_2d s1 dcl_2d s1
add r0.xy, t0, c4 add r0.xy, t0, c4
@ -206,8 +202,8 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR
lrp r5, r4.x, r1, r0 lrp r5, r4.x, r1, r0
lrp r0, r4.x, r2, r3 lrp r0, r4.x, r2, r3
lrp r1, r4.y, r5, r0 lrp r1, r4.y, r5, r0
mov r0, c1 mov r0, v1
mad r0, r1, r0, c0 mad r0, r1, r0, v0
mov oC0, r0 mov oC0, r0
// approximately 23 instruction slots used (8 texture, 15 arithmetic) // approximately 23 instruction slots used (8 texture, 15 arithmetic)
@ -215,38 +211,37 @@ float4 main (float2 texCoord : TEXCOORD0) : COLOR
const DWORD PalTexBilinearDef[] = const DWORD PalTexBilinearDef[] =
{ {
0xffff0200, 0x0050fffe, 0x42415443, 0x0000001c, 0x00000109, 0xffff0200, 0xffff0200, 0x0042fffe, 0x42415443, 0x0000001c, 0x000000d1, 0xffff0200,
0x00000007, 0x0000001c, 0x20000100, 0x00000102, 0x000000a8, 0x00000002, 0x00000005, 0x0000001c, 0x20000100, 0x000000ca, 0x00000080, 0x00000003,
0x00020001, 0x000000b0, 0x00000000, 0x000000c0, 0x00000003, 0x00020001, 0x00020001, 0x00000088, 0x00000000, 0x00000098, 0x00010003, 0x00060001,
0x000000c8, 0x00000000, 0x000000d8, 0x00010002, 0x00060001, 0x000000b0, 0x00000088, 0x00000000, 0x000000a0, 0x00020002, 0x000a0001, 0x000000ac,
0x00000000, 0x000000e1, 0x00010003, 0x00060001, 0x000000c8, 0x00000000, 0x00000000, 0x000000bc, 0x00030002, 0x000e0001, 0x000000ac, 0x00000000,
0x000000e9, 0x00020002, 0x000a0001, 0x000000b0, 0x00000000, 0x000000f4, 0x000000c3, 0x00040002, 0x00120001, 0x000000ac, 0x00000000, 0x67616d49,
0x00030002, 0x000e0001, 0x000000b0, 0x00000000, 0x000000fb, 0x00040002, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, 0x656c6150,
0x00120001, 0x000000b0, 0x00000000, 0x73616c46, 0xabab0068, 0x00030001, 0x00657474, 0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001,
0x00040001, 0x00000001, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00000001, 0x00000000, 0x657a6973, 0x7300615f, 0x5f657a69, 0x73700062,
0x00010001, 0x00000001, 0x00000000, 0x46766e49, 0x6873616c, 0x6c615000, 0x305f325f, 0x63694d00, 0x6f736f72, 0x28207466, 0x48202952, 0x204c534c,
0x65747465, 0x6c615000, 0x65747465, 0x00646f4d, 0x657a6973, 0x7300615f, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39312e39, 0x3934392e,
0x5f657a69, 0x73700062, 0x305f325f, 0x63694d00, 0x6f736f72, 0x28207466, 0x3131322e, 0xabab0031, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f,
0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0x900f0001, 0x0200001f,
0x39312e39, 0x3934392e, 0x3131322e, 0xabab0031, 0x0200001f, 0x80000000, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x03000002,
0xb0030000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0x80030000, 0xb0e40000, 0xa0e40004, 0x03000002, 0x80030001, 0xb0e40000,
0xa00f0801, 0x03000002, 0x80030000, 0xb0e40000, 0xa0e40004, 0x03000002, 0xa01b0004, 0x03000002, 0x80030002, 0xb0e40000, 0xa01b0003, 0x03000042,
0x80030001, 0xb0e40000, 0xa01b0004, 0x03000002, 0x80030002, 0xb0e40000, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0x80e40001,
0xa01b0003, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, 0x03000042, 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40800, 0x03000042,
0x800f0001, 0x80e40001, 0xa0e40800, 0x03000042, 0x800f0002, 0x80e40002, 0x800f0003, 0xb0e40000, 0xa0e40800, 0x04000004, 0x80010000, 0x80000000,
0xa0e40800, 0x03000042, 0x800f0003, 0xb0e40000, 0xa0e40800, 0x04000004, 0xa0000002, 0xa0550002, 0x04000004, 0x80010001, 0x80000001, 0xa0000002,
0x80010000, 0x80000000, 0xa0000002, 0xa0550002, 0x04000004, 0x80010001, 0xa0550002, 0x04000004, 0x80010002, 0x80000002, 0xa0000002, 0xa0550002,
0x80000001, 0xa0000002, 0xa0550002, 0x04000004, 0x80010002, 0x80000002, 0x04000004, 0x80010003, 0x80000003, 0xa0000002, 0xa0550002, 0x03000042,
0xa0000002, 0xa0550002, 0x04000004, 0x80010003, 0x80000003, 0xa0000002, 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000042, 0x800f0001, 0x80e40001,
0xa0550002, 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40801, 0x03000042, 0xa0e40801, 0x03000042, 0x800f0002, 0x80e40002, 0xa0e40801, 0x03000042,
0x800f0001, 0x80e40001, 0xa0e40801, 0x03000042, 0x800f0002, 0x80e40002, 0x800f0003, 0x80e40003, 0xa0e40801, 0x03000005, 0x80030004, 0xb0e40000,
0xa0e40801, 0x03000042, 0x800f0003, 0x80e40003, 0xa0e40801, 0x03000005, 0xa0e40003, 0x02000013, 0x80030004, 0x80e40004, 0x04000012, 0x800f0005,
0x80030004, 0xb0e40000, 0xa0e40003, 0x02000013, 0x80030004, 0x80e40004, 0x80000004, 0x80e40001, 0x80e40000, 0x04000012, 0x800f0000, 0x80000004,
0x04000012, 0x800f0005, 0x80000004, 0x80e40001, 0x80e40000, 0x04000012, 0x80e40002, 0x80e40003, 0x04000012, 0x800f0001, 0x80550004, 0x80e40005,
0x800f0000, 0x80000004, 0x80e40002, 0x80e40003, 0x04000012, 0x800f0001, 0x80e40000, 0x02000001, 0x800f0000, 0x90e40001, 0x04000004, 0x800f0000,
0x80550004, 0x80e40005, 0x80e40000, 0x02000001, 0x800f0000, 0xa0e40001, 0x80e40001, 0x80e40000, 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000,
0x04000004, 0x800f0000, 0x80e40001, 0x80e40000, 0xa0e40000, 0x02000001, 0x0000ffff
0x800f0800, 0x80e40000, 0x0000ffff
}; };
// A shader that doesn't look up colors from a palette. --------------------- // A shader that doesn't look up colors from a palette. ---------------------

View file

@ -295,6 +295,8 @@ void D3DFB::WipeEndScreen()
Begin2D(true); Begin2D(true);
} }
EndQuadBatch(); // Make sure all quads have been drawn.
// Don't do anything if there is no ending point. // Don't do anything if there is no ending point.
if (OldRenderTarget == NULL) if (OldRenderTarget == NULL)
{ {

View file

@ -264,6 +264,22 @@ private:
}; };
#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1) #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(); void SetInitialState();
bool CreateResources(); bool CreateResources();
void ReleaseResources(); void ReleaseResources();
@ -282,16 +298,20 @@ private:
void KillNativeTexs(); void KillNativeTexs();
void DrawLetterbox(); void DrawLetterbox();
void Draw3DPart(bool copy3d); 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); static void SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1);
void DoWindowedGamma(); void DoWindowedGamma();
void AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color);
void CheckQuadBatch();
void BeginQuadBatch();
void EndQuadBatch();
// State // State
void SetAlphaBlend(BOOL enabled, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0)); 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 SetConstant(int cnum, float r, float g, float b, float a);
void SetPixelShader(IDirect3DPixelShader9 *shader); void SetPixelShader(IDirect3DPixelShader9 *shader);
void SetTexture(int tnum, IDirect3DTexture9 *texture); void SetTexture(int tnum, IDirect3DTexture9 *texture);
void SetPaletteTexture(IDirect3DTexture9 *texture, int count, INTBOOL bilinear); void SetPaletteTexture(IDirect3DTexture9 *texture, int count);
void SetPalTexBilinearConstants(D3DTex *texture); void SetPalTexBilinearConstants(D3DTex *texture);
BOOL AlphaBlendEnabled; BOOL AlphaBlendEnabled;
@ -332,8 +352,13 @@ private:
IDirect3DTexture9 *ShadedPaletteTexture; IDirect3DTexture9 *ShadedPaletteTexture;
IDirect3DVertexBuffer9 *LineBuffer; IDirect3DVertexBuffer9 *LineBuffer;
int LineBatchPos;
FBVERTEX *LineData; FBVERTEX *LineData;
int LineBatchPos;
IDirect3DVertexBuffer9 *QuadBuffer;
FBVERTEX *QuadData;
BufferedQuad *QuadExtra;
int QuadBatchPos;
IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader; IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader;
IDirect3DPixelShader9 *PlainShader; IDirect3DPixelShader9 *PlainShader;