- Started writing Direct3D-friendly wipe code. It's just a Q&D crossfade for

now. More to come later.
- What is it about updaterevision.vcproj that makes it keep changing?

SVN r658 (trunk)
This commit is contained in:
Randy Heit 2007-12-30 04:18:39 +00:00
parent 68e2134f70
commit db54c43175
9 changed files with 498 additions and 193 deletions

View file

@ -1,3 +1,7 @@
December 29, 2007
- Started writing Direct3D-friendly wipe code. It's just a Q&D crossfade for
now.
December 29, 2007 (Changes by Graf Zahl) December 29, 2007 (Changes by Graf Zahl)
- Changed the FStatusBarTexture for Doom so that it can create a true color - Changed the FStatusBarTexture for Doom so that it can create a true color
image. image.

View file

@ -509,11 +509,11 @@ void D_Display (bool screenshot)
wipe = true; wipe = true;
if (wipegamestate != GS_FORCEWIPEFADE) if (wipegamestate != GS_FORCEWIPEFADE)
{ {
wipe_StartScreen (wipetype); wipe = screen->WipeStartScreen (wipetype);
} }
else else
{ {
wipe_StartScreen (wipe_Fade); wipe = screen->WipeStartScreen (wipe_Fade);
} }
wipegamestate = gamestate; wipegamestate = gamestate;
} }
@ -573,7 +573,7 @@ void D_Display (bool screenshot)
{ {
AM_Drawer (); AM_Drawer ();
} }
if (!screenshot && (!wipe || NoWipe)) if (!screenshot)
{ {
if ((hw2d = screen->Begin2D())) if ((hw2d = screen->Begin2D()))
{ {
@ -596,7 +596,7 @@ void D_Display (bool screenshot)
case GS_INTERMISSION: case GS_INTERMISSION:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
if (!screenshot && (!wipe || NoWipe)) if (!screenshot)
{ {
screen->Begin2D(); screen->Begin2D();
} }
@ -606,7 +606,7 @@ void D_Display (bool screenshot)
case GS_FINALE: case GS_FINALE:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
if (!screenshot && (!wipe || NoWipe)) if (!screenshot)
{ {
screen->Begin2D(); screen->Begin2D();
} }
@ -616,7 +616,7 @@ void D_Display (bool screenshot)
case GS_DEMOSCREEN: case GS_DEMOSCREEN:
screen->SetBlendingRect(0,0,0,0); screen->SetBlendingRect(0,0,0,0);
if (!screenshot && (!wipe || NoWipe)) if (!screenshot)
{ {
screen->Begin2D(); screen->Begin2D();
} }
@ -673,8 +673,7 @@ void D_Display (bool screenshot)
int wipestart, nowtime, tics; int wipestart, nowtime, tics;
bool done; bool done;
wipe_EndScreen (); screen->WipeEndScreen ();
screen->Unlock ();
wipestart = I_GetTime (false); wipestart = I_GetTime (false);
@ -686,13 +685,13 @@ void D_Display (bool screenshot)
nowtime = I_WaitForTic (wipestart); nowtime = I_WaitForTic (wipestart);
tics = nowtime - wipestart; tics = nowtime - wipestart;
wipestart = nowtime; wipestart = nowtime;
screen->Lock (true); done = screen->WipeDo (tics);
done = wipe_ScreenWipe (tics); C_DrawConsole (hw2d); // console and
C_DrawConsole (hw2d); M_Drawer (); // menu are drawn even on top of wipes
M_Drawer (); // menu is drawn even on top of wipes
screen->Update (); // page flip or blit buffer screen->Update (); // page flip or blit buffer
NetUpdate (); NetUpdate ();
} while (!done); } while (!done);
screen->WipeCleanup();
Net_WriteByte (DEM_WIPEOFF); Net_WriteByte (DEM_WIPEOFF);
} }

View file

@ -28,6 +28,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "f_wipe.h" #include "f_wipe.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "templates.h"
// //
// SCREEN WIPE PACKAGE // SCREEN WIPE PACKAGE
@ -69,7 +70,7 @@ void wipe_shittyColMajorXform (short *array)
delete[] dest; delete[] dest;
} }
int wipe_initMelt (int ticks) bool wipe_initMelt (int ticks)
{ {
int i, r; int i, r;
@ -96,7 +97,7 @@ int wipe_initMelt (int ticks)
return 0; return 0;
} }
int wipe_doMelt (int ticks) bool wipe_doMelt (int ticks)
{ {
int i; int i;
int j; int j;
@ -147,20 +148,17 @@ int wipe_doMelt (int ticks)
} }
return done; return done;
} }
int wipe_exitMelt (int ticks) bool wipe_exitMelt (int ticks)
{ {
delete[] wipe_scr_start;
delete[] wipe_scr_end;
delete[] y; delete[] y;
return 0; return 0;
} }
// Burn ------------------------------------------------------------- // Burn -------------------------------------------------------------
int wipe_initBurn (int ticks) bool wipe_initBurn (int ticks)
{ {
burnarray = new BYTE[FIREWIDTH * (FIREHEIGHT+5)]; burnarray = new BYTE[FIREWIDTH * (FIREHEIGHT+5)];
memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+5)); memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+5));
@ -169,7 +167,7 @@ int wipe_initBurn (int ticks)
return 0; return 0;
} }
int wipe_doBurn (int ticks) bool wipe_doBurn (int ticks)
{ {
static int voop; static int voop;
bool done; bool done;
@ -304,29 +302,27 @@ int wipe_doBurn (int ticks)
return done || (burntime > 40); return done || (burntime > 40);
} }
int wipe_exitBurn (int ticks) bool wipe_exitBurn (int ticks)
{ {
delete[] wipe_scr_start;
delete[] wipe_scr_end;
delete[] burnarray; delete[] burnarray;
return 0; return 0;
} }
// Crossfade -------------------------------------------------------- // Crossfade --------------------------------------------------------
int wipe_initFade (int ticks) bool wipe_initFade (int ticks)
{ {
fade = 0; fade = 0;
return 0; return 0;
} }
int wipe_doFade (int ticks) bool wipe_doFade (int ticks)
{ {
fade += ticks; fade += ticks;
if (fade > 64) if (fade > 64)
{ {
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end); screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end);
return 1; return true;
} }
else else
{ {
@ -353,78 +349,79 @@ int wipe_doFade (int ticks)
} }
} }
fade++; fade++;
return 0; return false;
} }
int wipe_exitFade (int ticks) bool wipe_exitFade (int ticks)
{ {
return 0; return 0;
} }
// General Wipe Functions ------------------------------------------- // General Wipe Functions -------------------------------------------
int wipe_StartScreen (int type) static bool (*wipes[])(int) =
{ {
CurrentWipeType = type; wipe_initMelt, wipe_doMelt, wipe_exitMelt,
if (CurrentWipeType < 0) wipe_initBurn, wipe_doBurn, wipe_exitBurn,
CurrentWipeType = 0; wipe_initFade, wipe_doFade, wipe_exitFade
else if (CurrentWipeType >= wipe_NUMWIPES) };
CurrentWipeType = wipe_NUMWIPES-1;
// Returns true if the wipe should be performed.
bool wipe_StartScreen (int type)
{
CurrentWipeType = clamp(type, 0, wipe_NUMWIPES - 1);
if (CurrentWipeType) if (CurrentWipeType)
{ {
wipe_scr_start = new short[SCREENWIDTH * SCREENHEIGHT / 2]; wipe_scr_start = new short[SCREENWIDTH * SCREENHEIGHT / 2];
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start);
return true;
} }
return false;
return 0;
} }
int wipe_EndScreen (void) void wipe_EndScreen (void)
{ {
if (CurrentWipeType) if (CurrentWipeType)
{ {
wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2]; wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2];
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end); screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end);
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); // restore start scr. screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); // restore start scr.
// Initialize the wipe
(*wipes[(CurrentWipeType-1)*3])(0);
} }
return 0;
} }
// Returns true if the wipe is done.
bool wipe_ScreenWipe (int ticks) bool wipe_ScreenWipe (int ticks)
{ {
static bool go = 0; // when zero, stop the wipe bool rc;
static int (*wipes[])(int) =
{
wipe_initMelt, wipe_doMelt, wipe_exitMelt,
wipe_initBurn, wipe_doBurn, wipe_exitBurn,
wipe_initFade, wipe_doFade, wipe_exitFade
};
int rc;
if (CurrentWipeType == wipe_None) if (CurrentWipeType == wipe_None)
return true; return true;
// initial stuff
if (!go)
{
go = 1;
(*wipes[(CurrentWipeType-1)*3])(ticks);
}
// do a piece of wipe-in // do a piece of wipe-in
V_MarkRect(0, 0, SCREENWIDTH, SCREENHEIGHT); V_MarkRect(0, 0, SCREENWIDTH, SCREENHEIGHT);
rc = (*wipes[(CurrentWipeType-1)*3+1])(ticks); rc = (*wipes[(CurrentWipeType-1)*3+1])(ticks);
// final stuff return rc;
if (rc)
{
go = 0;
(*wipes[(CurrentWipeType-1)*3+2])(ticks);
}
return !go;
} }
// Final things for the wipe
void wipe_Cleanup()
{
if (wipe_scr_start != NULL)
{
delete[] wipe_scr_start;
wipe_scr_start = NULL;
}
if (wipe_scr_end != NULL)
{
delete[] wipe_scr_end;
wipe_scr_end = NULL;
}
if (CurrentWipeType > 0)
{
(*wipes[(CurrentWipeType-1)*3+2])(0);
}
}

View file

@ -27,9 +27,10 @@
// SCREEN WIPE PACKAGE // SCREEN WIPE PACKAGE
// //
int wipe_StartScreen (int type); bool wipe_StartScreen (int type);
int wipe_EndScreen (void); void wipe_EndScreen (void);
bool wipe_ScreenWipe (int ticks); bool wipe_ScreenWipe (int ticks);
void wipe_Cleanup ();
enum enum
{ {

View file

@ -60,6 +60,7 @@
#include "sbar.h" #include "sbar.h"
#include "hardware.h" #include "hardware.h"
#include "r_translate.h" #include "r_translate.h"
#include "f_wipe.h"
IMPLEMENT_ABSTRACT_CLASS (DCanvas) IMPLEMENT_ABSTRACT_CLASS (DCanvas)
IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer) IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer)
@ -846,6 +847,28 @@ FNativeTexture *DFrameBuffer::CreatePalette(FRemapTable *remap)
return NULL; return NULL;
} }
bool DFrameBuffer::WipeStartScreen(int type)
{
return wipe_StartScreen(type);
}
void DFrameBuffer::WipeEndScreen()
{
wipe_EndScreen();
Unlock();
}
bool DFrameBuffer::WipeDo(int ticks)
{
Lock(true);
return wipe_ScreenWipe(ticks);
}
void DFrameBuffer::WipeCleanup()
{
wipe_Cleanup();
}
//=========================================================================== //===========================================================================
// //
// multi-format pixel copy with colormap application // multi-format pixel copy with colormap application

View file

@ -341,6 +341,11 @@ public:
const BYTE *patch, int pix_width, int pix_height, const BYTE *patch, int pix_width, int pix_height,
int step_x, int step_y, PalEntry * palette); int step_x, int step_y, PalEntry * palette);
// Screen wiping
virtual bool WipeStartScreen(int type);
virtual void WipeEndScreen();
virtual bool WipeDo(int ticks);
virtual void WipeCleanup();
#ifdef _WIN32 #ifdef _WIN32
virtual void PaletteChanged () = 0; virtual void PaletteChanged () = 0;

View file

@ -62,7 +62,8 @@
#include "doomerrors.h" #include "doomerrors.h"
#include "r_draw.h" #include "r_draw.h"
#include "r_translate.h" #include "r_translate.h"
#include "f_wipe.h"
#include "st_stuff.h"
#include "win32iface.h" #include "win32iface.h"
#include <mmsystem.h> #include <mmsystem.h>
@ -156,6 +157,11 @@ extern cycle_t BlitCycles;
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
CUSTOM_CVAR(Bool, test2d, true, CVAR_NOINITCALL)
{
BorderNeedRefresh = SB_state = screen->GetPageCount();
}
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
D3DFB::D3DFB (int width, int height, bool fullscreen) D3DFB::D3DFB (int width, int height, bool fullscreen)
@ -166,7 +172,9 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
D3DDevice = NULL; D3DDevice = NULL;
VertexBuffer = NULL; VertexBuffer = NULL;
FBTexture = NULL; FBTexture = NULL;
WindowedRenderTexture = NULL; TempRenderTexture = NULL;
InitialWipeScreen = NULL;
FinalWipeScreen = NULL;
PaletteTexture = NULL; PaletteTexture = NULL;
StencilPaletteTexture = NULL; StencilPaletteTexture = NULL;
ShadedPaletteTexture = NULL; ShadedPaletteTexture = NULL;
@ -187,6 +195,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
Palettes = NULL; Palettes = NULL;
Textures = NULL; Textures = NULL;
Accel2D = true; Accel2D = true;
GatheringWipeScreen = false;
Gamma = 1.0; Gamma = 1.0;
FlashConstants[0][3] = FlashConstants[0][2] = FlashConstants[0][1] = FlashConstants[0][0] = 0; FlashConstants[0][3] = FlashConstants[0][2] = FlashConstants[0][1] = FlashConstants[0][0] = 0;
@ -270,7 +279,7 @@ void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, b
pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
pp->BackBufferWidth = Width; pp->BackBufferWidth = Width;
pp->BackBufferHeight = TrueHeight; pp->BackBufferHeight = TrueHeight;
pp->BackBufferFormat = fullscreen ? D3DFMT_X8R8G8B8 : D3DFMT_UNKNOWN; pp->BackBufferFormat = fullscreen ? D3DFMT_A8R8G8B8 : D3DFMT_UNKNOWN;
pp->hDeviceWindow = Window; pp->hDeviceWindow = Window;
pp->PresentationInterval = vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; pp->PresentationInterval = vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
} }
@ -352,10 +361,23 @@ void D3DFB::ReleaseResources ()
FBTexture->Release(); FBTexture->Release();
FBTexture = NULL; FBTexture = NULL;
} }
if (WindowedRenderTexture != NULL) if (FinalWipeScreen != NULL)
{ {
WindowedRenderTexture->Release(); if (FinalWipeScreen != TempRenderTexture)
WindowedRenderTexture = NULL; {
FinalWipeScreen->Release();
}
FinalWipeScreen = NULL;
}
if (TempRenderTexture != NULL)
{
TempRenderTexture->Release();
TempRenderTexture = NULL;
}
if (InitialWipeScreen != NULL)
{
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
} }
if (VertexBuffer != NULL) if (VertexBuffer != NULL)
{ {
@ -414,10 +436,10 @@ bool D3DFB::Reset ()
FBTexture->Release(); FBTexture->Release();
FBTexture = NULL; FBTexture = NULL;
} }
if (WindowedRenderTexture != NULL) if (TempRenderTexture != NULL)
{ {
WindowedRenderTexture->Release(); TempRenderTexture->Release();
WindowedRenderTexture = NULL; TempRenderTexture = NULL;
} }
if (VertexBuffer != NULL) if (VertexBuffer != NULL)
{ {
@ -468,29 +490,6 @@ void D3DFB::KillNativeTexs()
} }
} }
//==========================================================================
//
// D3DFB :: KillNativeNonPalettedTexs
//
// Frees all native textures that aren't paletted.
//
//==========================================================================
void D3DFB::KillNativeNonPalettedTexs()
{
D3DTex *tex;
D3DTex *next;
for (tex = Textures; tex != NULL; tex = next)
{
next = tex->Next;
if (tex->GetTexFormat() != D3DFMT_L8)
{
delete tex;
}
}
}
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)))
@ -515,12 +514,9 @@ bool D3DFB::CreateFBTexture ()
FBWidth = Width; FBWidth = Width;
FBHeight = Height; FBHeight = Height;
} }
if (Windowed && GammaFixerShader) if (FAILED(D3DDevice->CreateTexture (FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TempRenderTexture, NULL)))
{ {
if (FAILED(D3DDevice->CreateTexture (FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &WindowedRenderTexture, NULL))) TempRenderTexture = NULL;
{
WindowedRenderTexture = false;
}
} }
return true; return true;
} }
@ -879,18 +875,14 @@ void D3DFB::Draw3DPart()
} }
FBTexture->UnlockRect (0); FBTexture->UnlockRect (0);
} }
if (TrueHeight != Height) DrawLetterbox();
{
// Letterbox! Draw black top and bottom borders.
D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } };
D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0);
}
D3DDevice->BeginScene(); D3DDevice->BeginScene();
OldRenderTarget = NULL; OldRenderTarget = NULL;
if (WindowedRenderTexture != NULL) if (TempRenderTexture != NULL &&
((Windowed && GammaFixerShader && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen))
{ {
IDirect3DSurface9 *targetsurf; IDirect3DSurface9 *targetsurf;
if (FAILED(WindowedRenderTexture->GetSurfaceLevel(0, &targetsurf)) || if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)) ||
FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) || FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) ||
FAILED(D3DDevice->SetRenderTarget(0, targetsurf))) FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{ {
@ -929,6 +921,24 @@ void D3DFB::Draw3DPart()
} }
} }
//==========================================================================
//
// D3DFB :: DrawLetterbox
//
// Draws the black bars at the top and bottom of the screen for letterboxed
// modes.
//
//==========================================================================
void D3DFB::DrawLetterbox()
{
if (TrueHeight != Height)
{
D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } };
D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0);
}
}
//========================================================================== //==========================================================================
// //
// D3DFB :: DoWindowedGamma // D3DFB :: DoWindowedGamma
@ -945,8 +955,8 @@ void D3DFB::DoWindowedGamma()
D3DDevice->SetRenderTarget(0, OldRenderTarget); D3DDevice->SetRenderTarget(0, OldRenderTarget);
D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX));
D3DDevice->SetFVF(D3DFVF_FBVERTEX); D3DDevice->SetFVF(D3DFVF_FBVERTEX);
SetTexture(0, WindowedRenderTexture); SetTexture(0, TempRenderTexture);
SetPixelShader(GammaFixerShader); SetPixelShader((Windowed && GammaFixerShader != NULL) ? GammaFixerShader : PlainShader);
SetAlphaBlend(FALSE); SetAlphaBlend(FALSE);
D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
OldRenderTarget = NULL; OldRenderTarget = NULL;
@ -1062,6 +1072,265 @@ void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2)
/* 2D Stuff */ /* 2D Stuff */
/**************************************************************************/ /**************************************************************************/
//==========================================================================
//
// D3DFB :: WipeStartScreen
//
// Called before the current screen has started rendering. This needs to
// save what was drawn the previous frame so that it can be animated into
// what gets drawn this frame.
//
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
// is visible on screen right now.
//
// In windowed mode, we can't do that because we'll get the whole desktop.
// Instead, we can conveniently use the TempRenderTexture, which is normally
// used for gamma-correcting copying the image to the back buffer.
//
//==========================================================================
bool D3DFB::WipeStartScreen(int type)
{
IDirect3DSurface9 *surf, *tsurf;
D3DSURFACE_DESC desc;
if (!test2d)
{
return Super::WipeStartScreen(type);
}
if (type != wipe_Fade)
{
return false;
}
if (Windowed)
{
// The InitialWipeScreen must have the same pixel format as
// the TempRenderTexture.
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) ||
FAILED(tsurf->GetDesc(&desc)))
{
return false;
}
}
else
{
// GetFrontBufferData works only with this format
desc.Format = D3DFMT_A8R8G8B8;
}
if (FAILED(D3DDevice->CreateTexture(Width, TrueHeight, 1, 0,
desc.Format, D3DPOOL_SYSTEMMEM, &InitialWipeScreen, NULL)))
{
InitialWipeScreen = NULL;
return false;
}
if (FAILED(InitialWipeScreen->GetSurfaceLevel(0, &surf)))
{
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
return false;
}
if (!Windowed)
{
if (FAILED(D3DDevice->GetFrontBufferData(0, surf)))
{
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
return false;
}
FinalWipeScreen = TempRenderTexture;
}
else
{
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) ||
FAILED(D3DDevice->GetRenderTargetData(tsurf, surf)))
{
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
return false;
}
// Create another texture to copy the final wipe screen to so
// we can still gamma correct the wipe. Since this is just for
// gamma correction, it's okay to fail (though not desirable.)
if (GammaFixerShader != NULL && Gamma != 1)
{
if (FAILED(tsurf->GetDesc(&desc)) ||
FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height,
1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT,
&FinalWipeScreen, NULL)))
{
FinalWipeScreen = TempRenderTexture;
}
}
else
{
FinalWipeScreen = TempRenderTexture;
}
}
// Even fullscreen will render to the TempRenderTexture, so we can have
// a copy of the new screen readily available.
GatheringWipeScreen = true;
return true;
}
//==========================================================================
//
// D3DFB :: WipeEndScreen
//
// The screen we want to animate to has just been drawn. This function is
// called in place of Update(), so it has not been Presented yet.
//
//==========================================================================
void D3DFB::WipeEndScreen()
{
if (!test2d)
{
Super::WipeEndScreen();
return;
}
WipeTime = 0;
// Don't do anything if there is no starting point.
if (InitialWipeScreen == NULL)
{
return;
}
// If the whole screen was drawn without 2D accel, get it in to
// video memory now.
if (!In2D)
{
Begin2D();
}
// Don't do anything if there is no ending point.
if (OldRenderTarget == NULL)
{
return;
}
// If these are different, reverse their roles so we don't need to
// waste time copying from TempRenderTexture to FinalWipeScreen.
swap(FinalWipeScreen, TempRenderTexture);
// At this point, InitialWipeScreen holds the screen we are wiping from.
// FinalWipeScreen holds the screen we are wiping to, which may be the
// same texture as TempRenderTexture.
}
//==========================================================================
//
// D3DFB :: WipeDo
//
// Perform the actual wipe animation. The number of tics since the last
// time this function was called is passed in. Returns true when the wipe
// is over. The first time this function has been called, the screen is
// still locked from before and EndScene() still has not been called.
// Successive times need to call BeginScene().
//
//==========================================================================
bool D3DFB::WipeDo(int ticks)
{
if (!test2d)
{
return Super::WipeDo(ticks);
}
WipeTime += ticks;
// Sanity checks.
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
{
return true;
}
if (GatheringWipeScreen)
{ // This is the first time we've been called for this wipe.
GatheringWipeScreen = false;
if (OldRenderTarget == NULL)
{
return true;
}
D3DDevice->SetRenderTarget(0, OldRenderTarget);
}
else
{ // This is the second or later time we've been called for this wipe.
D3DDevice->BeginScene();
}
OldRenderTarget = NULL;
if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen &&
((Windowed && GammaFixerShader) || GatheringWipeScreen))
{
IDirect3DSurface9 *targetsurf;
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)) ||
FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) ||
FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
{
// Setting the render target failed.
OldRenderTarget = NULL;
}
}
In2D = 2;
D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX));
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
/* Crossfade only for testing purposes, because it's the simplest.
* More to come later.
*/
// Put the initial screen back to the buffer, presumably with DMA.
IDirect3DSurface9 *source, *target;
if (SUCCEEDED(InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
SUCCEEDED(D3DDevice->GetRenderTarget(0, &target)))
{
D3DDevice->UpdateSurface(source, NULL, target, NULL);
}
// Draw the new screen on top of it.
SetTexture(0, FinalWipeScreen);
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
SetConstant(0, 0, 0, 0, clamp(WipeTime / 32.f, 0.f, 1.f));
SetConstant(1, 1, 1, 1, 0);
SetPixelShader(PlainShader);
// FIXME: The FinalWipeScreen gets junk at the top in letterbox modes.
D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
DrawLetterbox();
return WipeTime >= 32;
}
//==========================================================================
//
// D3DFB :: WipeCleanup
//
// Release any resources that were specifically created for the wipe.
//
//==========================================================================
void D3DFB::WipeCleanup()
{
if (!test2d)
{
Super::WipeCleanup();
return;
}
if (InitialWipeScreen != NULL)
{
InitialWipeScreen->Release();
InitialWipeScreen = NULL;
}
if (FinalWipeScreen != NULL && FinalWipeScreen != TempRenderTexture)
{
FinalWipeScreen->Release();
}
FinalWipeScreen = NULL;
GatheringWipeScreen = false;
}
//========================================================================== //==========================================================================
// //
// D3DTex Constructor // D3DTex Constructor
@ -1369,7 +1638,6 @@ bool D3DPal::Update()
// //
//========================================================================== //==========================================================================
CVAR(Bool,test2d,true,0)
bool D3DFB::Begin2D() bool D3DFB::Begin2D()
{ {
if (!test2d) return false; if (!test2d) return false;

View file

@ -242,6 +242,10 @@ public:
void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags); void STACK_ARGS DrawTextureV (FTexture *img, int x, int y, uint32 tag, va_list tags);
void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color); void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color);
void Dim (PalEntry color, float amount, int x1, int y1, int w, int h); void Dim (PalEntry color, float amount, int x1, int y1, int w, int h);
bool WipeStartScreen(int type);
void WipeEndScreen();
bool WipeDo(int ticks);
void WipeCleanup();
HRESULT GetHR (); HRESULT GetHR ();
private: private:
@ -262,7 +266,7 @@ private:
bool Reset(); bool Reset();
void KillNativePals(); void KillNativePals();
void KillNativeTexs(); void KillNativeTexs();
void KillNativeNonPalettedTexs(); void DrawLetterbox();
void Draw3DPart(); void Draw3DPart();
bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms); bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms);
void SetColorOverlay(DWORD color, float alpha); void SetColorOverlay(DWORD color, float alpha);
@ -301,13 +305,16 @@ private:
bool UseBlendingRect; bool UseBlendingRect;
int In2D; int In2D;
bool SM14; bool SM14;
bool GatheringWipeScreen;
D3DPal *Palettes; D3DPal *Palettes;
D3DTex *Textures; D3DTex *Textures;
int WipeTime;
IDirect3DDevice9 *D3DDevice; IDirect3DDevice9 *D3DDevice;
IDirect3DVertexBuffer9 *VertexBuffer; IDirect3DVertexBuffer9 *VertexBuffer;
IDirect3DTexture9 *FBTexture; IDirect3DTexture9 *FBTexture;
IDirect3DTexture9 *WindowedRenderTexture; IDirect3DTexture9 *TempRenderTexture;
IDirect3DTexture9 *PaletteTexture; IDirect3DTexture9 *PaletteTexture;
IDirect3DTexture9 *StencilPaletteTexture; IDirect3DTexture9 *StencilPaletteTexture;
IDirect3DTexture9 *ShadedPaletteTexture; IDirect3DTexture9 *ShadedPaletteTexture;
@ -317,6 +324,7 @@ private:
IDirect3DPixelShader9 *DimShader; IDirect3DPixelShader9 *DimShader;
IDirect3DPixelShader9 *GammaFixerShader; IDirect3DPixelShader9 *GammaFixerShader;
IDirect3DSurface9 *OldRenderTarget; IDirect3DSurface9 *OldRenderTarget;
IDirect3DTexture9 *InitialWipeScreen, *FinalWipeScreen;
D3DFB() {} D3DFB() {}
}; };

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="8,00" Version="8.00"
Name="updaterevision" Name="updaterevision"
ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}" ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}"
RootNamespace="updaterevision" RootNamespace="updaterevision"
@ -95,6 +95,82 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(ConfigurationName)"
@ -172,82 +248,6 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|x64" Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"