- added some code that prevents overlapping monsters from getting stuck in

each other. PIT_CheckThing will return true under the following contitions 
  now:
  * It was called from P_Move
  * The actor that is blocking the move already overlaps with the monster
    that is being moved.
  * the move will take the 2 actors further apart.  


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@651 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-12-06 22:12:34 +00:00
parent 8bff9666e4
commit 0b978c341b
7 changed files with 285 additions and 180 deletions

View file

@ -507,6 +507,8 @@ bool P_Move (AActor *actor)
} }
FCheckPosition tm; FCheckPosition tm;
tm.FromPMove = true;
try_ok = true; try_ok = true;
for(int i=1; i < steps; i++) for(int i=1; i < steps; i++)
{ {
@ -518,7 +520,7 @@ bool P_Move (AActor *actor)
if (try_ok) try_ok = P_TryMove (actor, tryx, tryy, dropoff, false, tm); if (try_ok) try_ok = P_TryMove (actor, tryx, tryy, dropoff, false, tm);
// [GrafZahl] Interpolating monster movement as it is done here just looks bad // [GrafZahl] Interpolating monster movement as it is done here just looks bad
// so make it switchable! // so make it switchable
if (nomonsterinterpolation) if (nomonsterinterpolation)
{ {
actor->PrevX = actor->x; actor->PrevX = actor->x;

View file

@ -31,7 +31,7 @@
#include <stdlib.h> #include <stdlib.h>
#define STEEPSLOPE 46341 // [RH] Minimum floorplane.c value for walking #define STEEPSLOPE 46342 // [RH] Minimum floorplane.c value for walking
#define BONUSADD 6 #define BONUSADD 6
@ -346,6 +346,7 @@ struct FCheckPosition
sector_t *ceilingsector; sector_t *ceilingsector;
bool touchmidtex; bool touchmidtex;
bool floatok; bool floatok;
bool FromPMove;
line_t *ceilingline; line_t *ceilingline;
AActor *stepthing; AActor *stepthing;
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply // [RH] These are used by PIT_CheckThing and P_XYMovement to apply
@ -359,6 +360,7 @@ struct FCheckPosition
DoRipping = rip; DoRipping = rip;
LastRipped = NULL; LastRipped = NULL;
PushTime = 0; PushTime = 0;
FromPMove = false;
} }
}; };

View file

@ -831,13 +831,32 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
} }
} }
} }
// Both things overlap in x or y direction
bool unblocking = false;
if (tm.FromPMove)
{
fixed_t newdist = P_AproxDistance(thing->x - tm.x, thing->y - tm.y);
fixed_t olddist = P_AproxDistance(thing->x - tm.thing->x, thing->y - tm.thing->y);
// Both actors already overlap. To prevent them from remaining stuck allow the move if it
// takes them further apart.
if (newdist > olddist)
{
// ... but not if they did not overlap in z-direction before but would after the move.
unblocking = !((tm.thing->x >= thing->x + thing->height && tm.x < thing->x + thing->height) ||
(tm.thing->x + tm.thing->height <= thing->x && tm.x + tm.thing->height > thing->x));
}
}
// [RH] If the other thing is a bridge, then treat the moving thing as if it had MF2_PASSMOBJ, so // [RH] If the other thing is a bridge, then treat the moving thing as if it had MF2_PASSMOBJ, so
// you can use a scrolling floor to move scenery items underneath a bridge. // you can use a scrolling floor to move scenery items underneath a bridge.
if ((tm.thing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ)) if ((tm.thing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
{ // check if a mobj passed over/under another object { // check if a mobj passed over/under another object
if (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP) if (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP)
{ // Some things prefer not to overlap each other, if possible { // Some things prefer not to overlap each other, if possible
return false; return unblocking;
} }
if ((tm.thing->z >= topz) || (tm.thing->z + tm.thing->height <= thing->z)) if ((tm.thing->z >= topz) || (tm.thing->z + tm.thing->height <= thing->z))
{ {
@ -1145,7 +1164,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
// despite another solid thing being in the way. // despite another solid thing being in the way.
// killough 4/11/98: Treat no-clipping things as not blocking // killough 4/11/98: Treat no-clipping things as not blocking
return !solid; return !solid || unblocking;
// return !(thing->flags & MF_SOLID); // old code -- killough // return !(thing->flags & MF_SOLID); // old code -- killough
} }

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the // This file was automatically generated by the
// updaterevision tool. Do not edit by hand. // updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "2010" #define ZD_SVN_REVISION_STRING "2018"
#define ZD_SVN_REVISION_NUMBER 2010 #define ZD_SVN_REVISION_NUMBER 2018

View file

@ -162,30 +162,6 @@ public:
int RoundedPaletteSize; int RoundedPaletteSize;
}; };
// Flags for a buffered quad
enum
{
BQF_GamePalette = 1,
BQF_CustomPalette = 7,
BQF_Paletted = 7,
BQF_Bilinear = 8,
BQF_WrapUV = 16,
BQF_InvertSource = 32,
BQF_DisableAlphaTest= 64,
BQF_Desaturated = 128,
};
// Shaders for a buffered quad
enum
{
BQS_PalTex,
BQS_Plain,
BQS_RedToAlpha,
BQS_ColorOnly,
BQS_SpecialColormap,
BQS_InGameColormap,
};
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -271,12 +247,15 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
IndexBuffer = NULL; IndexBuffer = NULL;
FBTexture = NULL; FBTexture = NULL;
TempRenderTexture = NULL; TempRenderTexture = NULL;
RenderTexture[0] = NULL;
RenderTexture[1] = NULL;
InitialWipeScreen = NULL; InitialWipeScreen = NULL;
ScreenshotTexture = NULL; ScreenshotTexture = NULL;
ScreenshotSurface = NULL; ScreenshotSurface = NULL;
FinalWipeScreen = NULL; FinalWipeScreen = NULL;
PaletteTexture = NULL; PaletteTexture = NULL;
GammaTexture = NULL; GammaTexture = NULL;
FrontCopySurface = NULL;
for (int i = 0; i < NUM_SHADERS; ++i) for (int i = 0; i < NUM_SHADERS; ++i)
{ {
Shaders[i] = NULL; Shaders[i] = NULL;
@ -300,6 +279,8 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
Packs = NULL; Packs = NULL;
PixelDoubling = 0; PixelDoubling = 0;
SkipAt = -1; SkipAt = -1;
CurrRenderTexture = 0;
RenderTextureToggle = 0;
Gamma = 1.0; Gamma = 1.0;
FlashColor0 = 0; FlashColor0 = 0;
@ -647,20 +628,15 @@ void D3DFB::ReleaseResources ()
void D3DFB::ReleaseDefaultPoolItems() void D3DFB::ReleaseDefaultPoolItems()
{ {
SAFE_RELEASE( FBTexture ); SAFE_RELEASE( FBTexture );
if (FinalWipeScreen != NULL) SAFE_RELEASE( FinalWipeScreen );
{ SAFE_RELEASE( RenderTexture[0] );
if (FinalWipeScreen != TempRenderTexture) SAFE_RELEASE( RenderTexture[1] );
{
FinalWipeScreen->Release();
}
FinalWipeScreen = NULL;
}
SAFE_RELEASE( TempRenderTexture );
SAFE_RELEASE( InitialWipeScreen ); SAFE_RELEASE( InitialWipeScreen );
SAFE_RELEASE( VertexBuffer ); SAFE_RELEASE( VertexBuffer );
SAFE_RELEASE( IndexBuffer ); SAFE_RELEASE( IndexBuffer );
SAFE_RELEASE( BlockSurface[0] ); SAFE_RELEASE( BlockSurface[0] );
SAFE_RELEASE( BlockSurface[1] ); SAFE_RELEASE( BlockSurface[1] );
SAFE_RELEASE( FrontCopySurface );
} }
//========================================================================== //==========================================================================
@ -772,14 +748,14 @@ void D3DFB::KillNativeTexs()
bool D3DFB::CreateFBTexture () bool D3DFB::CreateFBTexture ()
{ {
if (FAILED(D3DDevice->CreateTexture (Width, Height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL))) if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
{ {
int pow2width, pow2height, i; int pow2width, pow2height, i;
for (i = 1; i < Width; i <<= 1) {} pow2width = i; for (i = 1; i < Width; i <<= 1) {} pow2width = i;
for (i = 1; i < Height; i <<= 1) {} pow2height = i; for (i = 1; i < Height; i <<= 1) {} pow2height = i;
if (FAILED(D3DDevice->CreateTexture (pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL))) if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL)))
{ {
return false; return false;
} }
@ -794,20 +770,42 @@ bool D3DFB::CreateFBTexture ()
FBWidth = Width; FBWidth = Width;
FBHeight = Height; FBHeight = Height;
} }
if (FAILED(D3DDevice->CreateTexture (FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TempRenderTexture, NULL))) RenderTextureToggle = 0;
RenderTexture[0] = NULL;
RenderTexture[1] = NULL;
if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[0], NULL)))
{ {
TempRenderTexture = NULL; return false;
}
if (Windowed || PixelDoubling)
{
// Windowed or pixel doubling: Create another render texture so we can flip between them.
RenderTextureToggle = 1;
if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[1], NULL)))
{
return false;
}
} }
else else
{ {
// Initialize the TempRenderTexture to black. // Fullscreen and not pixel doubling: Create a render target to have the back buffer copied to.
if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL)))
{
return false;
}
}
// Initialize the TempRenderTextures to black.
for (int i = 0; i <= RenderTextureToggle; ++i)
{
IDirect3DSurface9 *surf; IDirect3DSurface9 *surf;
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &surf))) if (SUCCEEDED(RenderTexture[i]->GetSurfaceLevel(0, &surf)))
{ {
D3DDevice->ColorFill(surf, NULL, D3DCOLOR_XRGB(0,0,0)); D3DDevice->ColorFill(surf, NULL, D3DCOLOR_XRGB(0,0,0));
surf->Release(); surf->Release();
} }
} }
TempRenderTexture = RenderTexture[0];
CurrRenderTexture = 0;
return true; return true;
} }
@ -1180,6 +1178,8 @@ void D3DFB::Flip()
DoWindowedGamma(); DoWindowedGamma();
D3DDevice->EndScene(); D3DDevice->EndScene();
CopyNextFrontBuffer();
// Attempt to counter input lag. // Attempt to counter input lag.
if (d3d_antilag && BlockSurface[0] != NULL) if (d3d_antilag && BlockSurface[0] != NULL)
{ {
@ -1195,6 +1195,49 @@ void D3DFB::Flip()
} }
D3DDevice->Present(NULL, NULL, NULL, NULL); D3DDevice->Present(NULL, NULL, NULL, NULL);
InScene = false; InScene = false;
if (RenderTextureToggle)
{
// Flip the TempRenderTexture to the other one now.
CurrRenderTexture ^= RenderTextureToggle;
TempRenderTexture = RenderTexture[CurrRenderTexture];
}
}
//==========================================================================
//
// D3DFB :: CopyNextFrontBuffer
//
// Duplicates the contents of the back buffer that will become the front
// buffer upon Present into FrontCopySurface so that we can get the
// contents of the display without wasting time in GetFrontBufferData().
//
//==========================================================================
void D3DFB::CopyNextFrontBuffer()
{
IDirect3DSurface9 *backbuff;
if (Windowed || PixelDoubling)
{
// Windowed mode or pixel doubling: TempRenderTexture has what we want
SAFE_RELEASE( FrontCopySurface );
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &backbuff)))
{
FrontCopySurface = backbuff;
}
}
else
{
// Fullscreen, not pixel doubled: The back buffer has what we want,
// but it might be letter boxed.
if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuff)))
{
RECT srcrect = { 0, LBOffsetI, Width, LBOffsetI + Height };
D3DDevice->StretchRect(backbuff, &srcrect, FrontCopySurface, NULL, D3DTEXF_NONE);
backbuff->Release();
}
}
} }
//========================================================================== //==========================================================================
@ -1709,51 +1752,28 @@ void D3DFB::ReleaseScreenshotBuffer()
// //
//========================================================================== //==========================================================================
IDirect3DTexture9 *D3DFB::GetCurrentScreen() IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
{ {
IDirect3DTexture9 *tex; IDirect3DTexture9 *tex;
IDirect3DSurface9 *tsurf, *surf; IDirect3DSurface9 *surf;
D3DSURFACE_DESC desc; D3DSURFACE_DESC desc;
HRESULT hr;
if (Windowed || PixelDoubling) assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
if (FAILED(FrontCopySurface->GetDesc(&desc)))
{ {
// The texture we read into must have the same pixel format as return NULL;
// the TempRenderTexture. }
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf))) if (pool == D3DPOOL_SYSTEMMEM)
{ {
if (FAILED(tsurf->GetDesc(&desc))) hr = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL);
{
tsurf->Release();
return NULL;
}
tsurf->Release();
}
else
{
return NULL;
}
} }
else else
{ {
if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &tsurf))) hr = D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &tex, NULL);
{
if (FAILED(tsurf->GetDesc(&desc)))
{
tsurf->Release();
return NULL;
}
tsurf->Release();
}
else
{
return NULL;
}
// GetFrontBufferData works only with this format
desc.Format = D3DFMT_A8R8G8B8;
} }
if (FAILED(hr))
if (FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0,
desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL)))
{ {
return NULL; return NULL;
} }
@ -1762,35 +1782,23 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen()
tex->Release(); tex->Release();
return NULL; return NULL;
} }
if (pool == D3DPOOL_SYSTEMMEM)
if (!Windowed && !PixelDoubling)
{ {
if (FAILED(D3DDevice->GetFrontBufferData(0, surf))) // Video -> System memory : use GetRenderTargetData
{ hr = D3DDevice->GetRenderTargetData(FrontCopySurface, surf);
surf->Release();
tex->Release();
return NULL;
}
} }
else else
{ {
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf))) // Video -> Video memory : use StretchRect
{ RECT destrect = { 0, 0, Width, Height };
if (FAILED(D3DDevice->GetRenderTargetData(tsurf, surf))) hr = D3DDevice->StretchRect(FrontCopySurface, NULL, surf, &destrect, D3DTEXF_POINT);
{
tsurf->Release();
tex->Release();
return NULL;
}
tsurf->Release();
}
else
{
tex->Release();
return NULL;
}
} }
surf->Release(); surf->Release();
if (FAILED(hr))
{
tex->Release();
return NULL;
}
return tex; return tex;
} }
@ -1861,7 +1869,7 @@ void D3DFB::DrawPackedTextures(int packnum)
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
} }
quad->Palette = NULL; quad->Palette = NULL;
quad->Texture = pack; quad->Texture = pack->Tex;
float x0 = float(x) - 0.5f; float x0 = float(x) - 0.5f;
float y0 = float(y) - 0.5f; float y0 = float(y) - 0.5f;
@ -3007,7 +3015,7 @@ void STACK_ARGS D3DFB::DrawTextureV (FTexture *img, double x, double y, uint32 t
return; return;
} }
QuadExtra[QuadBatchPos].Texture = tex->Box->Owner; QuadExtra[QuadBatchPos].Texture = tex->Box->Owner->Tex;
if (parms.bilinear) if (parms.bilinear)
{ {
QuadExtra[QuadBatchPos].Flags |= BQF_Bilinear; QuadExtra[QuadBatchPos].Flags |= BQF_Bilinear;
@ -3148,7 +3156,7 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
} }
quad->Palette = NULL; quad->Palette = NULL;
quad->Texture = tex->Box->Owner; quad->Texture = tex->Box->Owner->Tex;
vert[0].x = x0; vert[0].x = x0;
vert[0].y = y0; vert[0].y = y0;
@ -3380,11 +3388,13 @@ void D3DFB::EndQuadBatch()
{ {
SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor); SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor);
} }
#if 0
// Set paletted bilinear filtering (IF IT WORKED RIGHT!) // Set paletted bilinear filtering (IF IT WORKED RIGHT!)
if ((quad->Flags & (BQF_Paletted | BQF_Bilinear)) == (BQF_Paletted | BQF_Bilinear)) if ((quad->Flags & (BQF_Paletted | BQF_Bilinear)) == (BQF_Paletted | BQF_Bilinear))
{ {
SetPalTexBilinearConstants(quad->Texture); SetPalTexBilinearConstants(quad->Texture);
} }
#endif
// Set the alpha blending // Set the alpha blending
SetAlphaBlend(D3DBLENDOP(quad->BlendOp), D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend)); SetAlphaBlend(D3DBLENDOP(quad->BlendOp), D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend));
@ -3442,7 +3452,7 @@ void D3DFB::EndQuadBatch()
// Set the texture // Set the texture
if (quad->Texture != NULL) if (quad->Texture != NULL)
{ {
SetTexture(0, quad->Texture->Tex); SetTexture(0, quad->Texture);
} }
// Draw the quad // Draw the quad

View file

@ -159,7 +159,7 @@ bool D3DFB::WipeStartScreen(int type)
return false; return false;
} }
InitialWipeScreen = GetCurrentScreen(); InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT);
// Create another texture to copy the final wipe screen to so // Create another texture to copy the final wipe screen to so
// we can still gamma correct the wipe. Since this is just for // we can still gamma correct the wipe. Since this is just for
@ -173,14 +173,14 @@ bool D3DFB::WipeStartScreen(int type)
1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT,
&FinalWipeScreen, NULL))) &FinalWipeScreen, NULL)))
{ {
FinalWipeScreen = TempRenderTexture; (FinalWipeScreen = TempRenderTexture)->AddRef();
} }
tsurf->Release(); tsurf->Release();
} }
} }
else else
{ {
FinalWipeScreen = TempRenderTexture; (FinalWipeScreen = TempRenderTexture)->AddRef();
} }
// Make even fullscreen model render to the TempRenderTexture, so // Make even fullscreen model render to the TempRenderTexture, so
@ -229,7 +229,11 @@ void D3DFB::WipeEndScreen()
// If these are different, reverse their roles so we don't need to // If these are different, reverse their roles so we don't need to
// waste time copying from TempRenderTexture to FinalWipeScreen. // waste time copying from TempRenderTexture to FinalWipeScreen.
swap(FinalWipeScreen, TempRenderTexture); if (FinalWipeScreen != TempRenderTexture)
{
swap(RenderTexture[CurrRenderTexture], FinalWipeScreen);
TempRenderTexture = RenderTexture[CurrRenderTexture];
}
// At this point, InitialWipeScreen holds the screen we are wiping from. // At this point, InitialWipeScreen holds the screen we are wiping from.
// FinalWipeScreen holds the screen we are wiping to, which may be the // FinalWipeScreen holds the screen we are wiping to, which may be the
@ -315,11 +319,7 @@ void D3DFB::WipeCleanup()
ScreenWipe = NULL; ScreenWipe = NULL;
} }
SAFE_RELEASE( InitialWipeScreen ); SAFE_RELEASE( InitialWipeScreen );
if (FinalWipeScreen != NULL && FinalWipeScreen != TempRenderTexture) SAFE_RELEASE( FinalWipeScreen );
{
FinalWipeScreen->Release();
}
FinalWipeScreen = NULL;
GatheringWipeScreen = false; GatheringWipeScreen = false;
if (!Accel2D) if (!Accel2D)
{ {
@ -338,6 +338,27 @@ D3DFB::Wiper::~Wiper()
{ {
} }
//==========================================================================
//
// D3DFB :: Wiper :: DrawScreen
//
// Draw either the initial or target screen completely to the screen.
//
//==========================================================================
void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1)
{
FBVERTEX verts[4];
fb->CalcFullscreenCoords(verts, false, false, color0, color1);
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
fb->SetTexture(0, tex);
fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
}
// WIPE: CROSSFADE --------------------------------------------------------- // WIPE: CROSSFADE ---------------------------------------------------------
//========================================================================== //==========================================================================
@ -363,29 +384,12 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
{ {
Clock += ticks; Clock += ticks;
// Put the initial screen back to the buffer, presumably with DMA. // Put the initial screen back to the buffer.
IDirect3DSurface9 *source = NULL, *target = NULL; DrawScreen(fb, fb->InitialWipeScreen);
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
{
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
target->Release();
}
if (source != NULL)
{
source->Release();
}
// Draw the new screen on top of it. // Draw the new screen on top of it.
FBVERTEX verts[4]; DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD,
D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
fb->CalcFullscreenCoords(verts, false, false, D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
fb->SetTexture(0, fb->FinalWipeScreen);
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
return Clock >= 32; return Clock >= 32;
} }
@ -422,28 +426,8 @@ D3DFB::Wiper_Melt::Wiper_Melt()
bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb) bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
{ {
IDirect3DSurface9 *source = NULL, *target;
if (FAILED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) ||
FAILED(fb->D3DDevice->GetRenderTarget(0, &target)))
{
// A fat lot of good we can do if we can't get these two surfaces.
if (source != NULL)
{
source->Release();
}
return true;
}
// Draw the new screen on the bottom. // Draw the new screen on the bottom.
FBVERTEX verts[4]; DrawScreen(fb, fb->FinalWipeScreen);
fb->CalcFullscreenCoords(verts, false, false, 0, 0xFFFFFFFF);
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
fb->SetTexture(0, fb->FinalWipeScreen);
fb->SetAlphaBlend(D3DBLENDOP(0));
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
int i, dy; int i, dy;
int fbwidth = fb->Width; int fbwidth = fb->Width;
@ -475,19 +459,87 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
dpt.x = i * fbwidth / WIDTH; dpt.x = i * fbwidth / WIDTH;
dpt.y = MAX(0, y[i] * fbheight / HEIGHT); dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
rect.left = dpt.x; rect.left = dpt.x;
rect.top = fb->LBOffsetI; rect.top = 0;
rect.right = (i + 1) * fbwidth / WIDTH; rect.right = (i + 1) * fbwidth / WIDTH;
rect.bottom = fbheight - dpt.y + fb->LBOffsetI; rect.bottom = fbheight - dpt.y;
dpt.y += fb->LBOffsetI;
if (rect.bottom > rect.top) if (rect.bottom > rect.top)
{ {
fb->D3DDevice->UpdateSurface(source, &rect, target, &dpt); fb->CheckQuadBatch();
BufferedQuad *quad = &fb->QuadExtra[fb->QuadBatchPos];
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
WORD *index = &fb->IndexData[fb->IndexPos];
quad->Group1 = 0;
quad->Flags = BQF_DisableAlphaTest;
quad->ShaderNum = BQS_Plain;
quad->Palette = NULL;
quad->Texture = fb->InitialWipeScreen;
// Fill the vertex buffer.
float u0 = rect.left / float(fb->FBWidth);
float v0 = 0;
float u1 = rect.right / float(fb->FBWidth);
float v1 = (rect.bottom - rect.top) / float(fb->FBHeight);
float x0 = float(rect.left) - 0.5f;
float x1 = float(rect.right) - 0.5f;
float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f;
float y1 = float(fbheight + fb->LBOffsetI) - 0.5f;
vert[0].x = x0;
vert[0].y = y0;
vert[0].z = 0;
vert[0].rhw = 1;
vert[0].color0 = 0;
vert[0].color1 = 0xFFFFFFF;
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 = 0xFFFFFFF;
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 = 0xFFFFFFF;
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 = 0xFFFFFFF;
vert[3].tu = u0;
vert[3].tv = v1;
// Fill the vertex index buffer.
index[0] = fb->VertexPos;
index[1] = fb->VertexPos + 1;
index[2] = fb->VertexPos + 2;
index[3] = fb->VertexPos;
index[4] = fb->VertexPos + 2;
index[5] = fb->VertexPos + 3;
// Batch the quad.
fb->QuadBatchPos++;
fb->VertexPos += 4;
fb->IndexPos += 6;
} }
} }
} }
} }
target->Release(); fb->EndQuadBatch();
source->Release();
return done; return done;
} }
@ -561,18 +613,7 @@ bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
} }
// Put the initial screen back to the buffer. // Put the initial screen back to the buffer.
IDirect3DSurface9 *source = NULL, *target; DrawScreen(fb, fb->InitialWipeScreen);
if (SUCCEEDED(fb->InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
SUCCEEDED(fb->D3DDevice->GetRenderTarget(0, &target)))
{
fb->D3DDevice->UpdateSurface(source, NULL, target, NULL);
target->Release();
}
if (source != NULL)
{
source->Release();
}
// Burn the new screen on top of it. // Burn the new screen on top of it.
float top = fb->LBOffset - 0.5f; float top = fb->LBOffset - 0.5f;

View file

@ -289,7 +289,7 @@ private:
DWORD Group1; DWORD Group1;
}; };
D3DPal *Palette; D3DPal *Palette;
PackingTexture *Texture; IDirect3DTexture9 *Texture;
}; };
enum enum
@ -344,7 +344,7 @@ private:
void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync); void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync);
void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const; void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const;
bool Reset(); bool Reset();
IDirect3DTexture9 *GetCurrentScreen(); IDirect3DTexture9 *GetCurrentScreen(D3DPOOL pool=D3DPOOL_SYSTEMMEM);
void ReleaseDefaultPoolItems(); void ReleaseDefaultPoolItems();
void KillNativePals(); void KillNativePals();
void KillNativeTexs(); void KillNativeTexs();
@ -363,6 +363,7 @@ private:
void BeginLineBatch(); void BeginLineBatch();
void EndLineBatch(); void EndLineBatch();
void EndBatch(); void EndBatch();
void CopyNextFrontBuffer();
D3DCAPS9 DeviceCaps; D3DCAPS9 DeviceCaps;
@ -394,6 +395,8 @@ private:
int PixelDoubling; int PixelDoubling;
int SkipAt; int SkipAt;
int LBOffsetI; int LBOffsetI;
int RenderTextureToggle;
int CurrRenderTexture;
float LBOffset; float LBOffset;
float Gamma; float Gamma;
bool UpdatePending; bool UpdatePending;
@ -414,11 +417,12 @@ private:
IDirect3DDevice9 *D3DDevice; IDirect3DDevice9 *D3DDevice;
IDirect3DTexture9 *FBTexture; IDirect3DTexture9 *FBTexture;
IDirect3DTexture9 *TempRenderTexture; IDirect3DTexture9 *TempRenderTexture, *RenderTexture[2];
IDirect3DTexture9 *PaletteTexture; IDirect3DTexture9 *PaletteTexture;
IDirect3DTexture9 *GammaTexture; IDirect3DTexture9 *GammaTexture;
IDirect3DTexture9 *ScreenshotTexture; IDirect3DTexture9 *ScreenshotTexture;
IDirect3DSurface9 *ScreenshotSurface; IDirect3DSurface9 *ScreenshotSurface;
IDirect3DSurface9 *FrontCopySurface;
IDirect3DVertexBuffer9 *VertexBuffer; IDirect3DVertexBuffer9 *VertexBuffer;
FBVERTEX *VertexData; FBVERTEX *VertexData;
@ -444,6 +448,9 @@ private:
public: public:
virtual ~Wiper(); virtual ~Wiper();
virtual bool Run(int ticks, D3DFB *fb) = 0; virtual bool Run(int ticks, D3DFB *fb) = 0;
void DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
D3DBLENDOP blendop=D3DBLENDOP(0), D3DCOLOR color0=0, D3DCOLOR color1=0xFFFFFFF);
}; };
class Wiper_Melt; friend class Wiper_Melt; class Wiper_Melt; friend class Wiper_Melt;
@ -453,6 +460,30 @@ private:
Wiper *ScreenWipe; Wiper *ScreenWipe;
}; };
// Flags for a buffered quad
enum
{
BQF_GamePalette = 1,
BQF_CustomPalette = 7,
BQF_Paletted = 7,
BQF_Bilinear = 8,
BQF_WrapUV = 16,
BQF_InvertSource = 32,
BQF_DisableAlphaTest= 64,
BQF_Desaturated = 128,
};
// Shaders for a buffered quad
enum
{
BQS_PalTex,
BQS_Plain,
BQS_RedToAlpha,
BQS_ColorOnly,
BQS_SpecialColormap,
BQS_InGameColormap,
};
#if 0 #if 0
#define STARTLOG do { if (!dbg) dbg = fopen ("k:/vid.log", "w"); } while(0) #define STARTLOG do { if (!dbg) dbg = fopen ("k:/vid.log", "w"); } while(0)
#define STOPLOG do { if (dbg) { fclose (dbg); dbg=NULL; } } while(0) #define STOPLOG do { if (dbg) { fclose (dbg); dbg=NULL; } } while(0)