From 5bfcaab25c20b0cb843db50216a45956044801bd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 7 Jul 2011 15:37:47 +0000 Subject: [PATCH] - separation of software renderer from the rest of the code complete. All external access to the renderer is routed through the FRenderer interface class now, with two exceptions (2D texture drawing to a canvas and polymost testing code) that are handled by #defines. SVN r3263 (trunk) --- src/CMakeLists.txt | 2 + src/am_map.cpp | 5 +- src/d_main.cpp | 42 +- src/dobject.h | 3 + src/dobjgc.cpp | 6 + src/g_game.cpp | 3 +- src/g_level.cpp | 5 +- src/p_mobj.cpp | 5 +- src/p_user.cpp | 5 +- src/r_data/colormaps.cpp | 5 +- src/r_data/colormaps.h | 2 +- src/r_main.cpp | 989 +---------------------------- src/r_main.h | 13 +- src/r_polymost.cpp | 1 - src/r_polymost.h | 2 - src/r_renderer.h | 68 ++ src/r_sky.cpp | 2 +- src/r_sky.h | 1 + src/r_swrenderer.cpp | 298 +++++++++ src/r_swrenderer.h | 41 ++ src/r_utility.cpp | 1050 +++++++++++++++++++++++++++++++ src/r_utility.h | 21 + src/sdl/hardware.cpp | 15 + src/sdl/hardware.h | 1 + src/sdl/sdlvideo.cpp | 2 + src/textures/canvastexture.cpp | 41 +- src/textures/texturemanager.cpp | 3 +- src/textures/textures.h | 14 +- src/v_draw.cpp | 9 +- src/v_video.cpp | 152 +---- src/v_video.h | 24 - src/win32/hardware.cpp | 16 + src/win32/hardware.h | 1 + src/win32/i_main.cpp | 3 +- src/win32/win32iface.h | 1 + src/win32/win32video.cpp | 2 +- zdoom.vcproj | 48 +- 37 files changed, 1677 insertions(+), 1224 deletions(-) create mode 100644 src/r_renderer.h create mode 100644 src/r_swrenderer.cpp create mode 100644 src/r_swrenderer.h create mode 100644 src/r_utility.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d1d1724aa..dfba4e9592 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -722,6 +722,8 @@ add_executable( zdoom WIN32 p_xlat.cpp parsecontext.cpp po_man.cpp + r_swrenderer.cpp + r_utility.cpp r_3dfloors.cpp r_bsp.cpp r_draw.cpp diff --git a/src/am_map.cpp b/src/am_map.cpp index 026fec2e83..a6b03446fe 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -36,10 +36,10 @@ #include "r_data/r_translate.h" #include "d_event.h" #include "gi.h" -#include "r_bsp.h" #include "p_setup.h" #include "c_bind.h" #include "farchive.h" +#include "r_renderer.h" #include "m_cheat.h" #include "i_system.h" @@ -1634,8 +1634,7 @@ void AM_drawSubsectors() points[j].Y = f_y + (f_h - (pt.y - m_y) * scale / float(1 << 24)); } // For lighting and texture determination - sector_t *sec = R_FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight, - &ceilinglight, false); + sector_t *sec = Renderer->FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight, false); // Find texture origin. mpoint_t originpt = { -sec->GetXOffset(sector_t::floor) >> FRACTOMAPBITS, sec->GetYOffset(sector_t::floor) >> FRACTOMAPBITS }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 070fc91674..efc33b5f46 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -73,7 +73,7 @@ #include "st_stuff.h" #include "am_map.h" #include "p_setup.h" -#include "r_local.h" +#include "r_utility.h" #include "r_sky.h" #include "d_main.h" #include "d_dehacked.h" @@ -87,7 +87,6 @@ #include "gameconfigfile.h" #include "sbar.h" #include "decallib.h" -#include "r_polymost.h" #include "version.h" #include "v_text.h" #include "st_start.h" @@ -106,7 +105,11 @@ #include "sc_man.h" #include "po_man.h" #include "resourcefiles/resourcefile.h" -#include "r_3dfloors.h" +#include "r_renderer.h" + +#ifdef USE_POLYMOST +#include "r_polymost.h" +#endif EXTERN_CVAR(Bool, hud_althud) void DrawHUD(); @@ -184,6 +187,9 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO) } } +#ifdef USE_POLYMOST +CVAR(Bool, testpolymost, false, 0) +#endif CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO); CVAR (Int, wipetype, 1, CVAR_ARCHIVE); CVAR (Int, snd_drawoutput, 0, 0); @@ -276,8 +282,10 @@ void D_ProcessEvents (void) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event - if (testpolymost) - Polymost_Responder (ev); + #ifdef USE_POLYMOST + if (testpolymost) + Polymost_Responder (ev); + #endif G_Responder (ev); } } @@ -298,8 +306,11 @@ void D_PostEvent (const event_t *ev) return; } events[eventhead] = *ev; - if (ev->type == EV_Mouse && !testpolymost && !paused && menuactive == MENU_Off && - ConsoleState != c_down && ConsoleState != c_falling) + if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling +#ifdef USE_POLYMOST + && !testpolymost +#endif + ) { if (Button_Mlook.bDown || freelook) { @@ -710,6 +721,7 @@ void D_Display () hw2d = false; +#ifdef USE_POLYMOST if (testpolymost) { drawpolymosttest(); @@ -717,6 +729,7 @@ void D_Display () M_Drawer(); } else +#endif { unsigned int nowtime = I_FPSTime(); TexMan.UpdateAnimations(nowtime); @@ -744,14 +757,14 @@ void D_Display () screen->SetBlendingRect(viewwindowx, viewwindowy, viewwindowx + viewwidth, viewwindowy + viewheight); P_CheckPlayerSprites(); - screen->RenderView(&players[consoleplayer]); + Renderer->RenderView(&players[consoleplayer]); if ((hw2d = screen->Begin2D(viewactive))) { // Redraw everything every frame when using 2D accel SB_state = screen->GetPageCount(); BorderNeedRefresh = screen->GetPageCount(); } - screen->DrawRemainingPlayerSprites(); + Renderer->DrawRemainingPlayerSprites(); screen->DrawBlendingRect(); if (automapactive) { @@ -915,15 +928,7 @@ void D_ErrorCleanup () menuactive = MENU_Off; } insave = false; - fakeActive = 0; - fake3D = 0; - while (CurrentSkybox) - { - R_3D_DeleteHeights(); - R_3D_LeaveSkybox(); - } - R_3D_ResetClip(); - R_3D_DeleteHeights(); + Renderer->ErrorCleanup(); } //========================================================================== @@ -2109,6 +2114,7 @@ void D_DoomMain (void) { Printf ("I_Init: Setting up machine state.\n"); I_Init (); + I_CreateRenderer(); } Printf ("V_Init: allocate screen.\n"); diff --git a/src/dobject.h b/src/dobject.h index a2354aa808..2ae5493c6d 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -314,6 +314,9 @@ namespace GC // is NULLed instead. void Mark(DObject **obj); + // For cleanup + void DelSoftRootHead(); + // Soft-roots an object. void AddSoftRoot(DObject *obj); diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 1bc05269e2..6fae559c30 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -529,6 +529,12 @@ void Barrier(DObject *pointing, DObject *pointed) } } +void DelSoftRootHead() +{ + if (SoftRoots != NULL) delete SoftRoots; + SoftRoots = NULL; +} + //========================================================================== // // AddSoftRoot diff --git a/src/g_game.cpp b/src/g_game.cpp index 1acab7a148..9ff2d42256 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -78,6 +78,7 @@ #include "p_acs.h" #include "m_joy.h" #include "farchive.h" +#include "r_renderer.h" #include "r_data/colormaps.h" #include @@ -2034,7 +2035,7 @@ static void PutSavePic (FILE *file, int width, int height) else { P_CheckPlayerSprites(); - screen->WriteSavePic(&players[consoleplayer], file, width, height); + Renderer->WriteSavePic(&players[consoleplayer], file, width, height); } } diff --git a/src/g_level.cpp b/src/g_level.cpp index 4a6287be8e..0b89dafa87 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -80,6 +80,7 @@ #include "a_strifeglobal.h" #include "r_data/colormaps.h" #include "farchive.h" +#include "r_renderer.h" #include "gi.h" @@ -1349,7 +1350,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) { int i = level.totaltime; - screen->StartSerialize(arc); + Renderer->StartSerialize(arc); arc << level.flags << level.flags2 @@ -1468,7 +1469,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } } } - screen->EndSerialize(arc); + Renderer->EndSerialize(arc); } //========================================================================== diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index eb22dc6c0d..36339ffeea 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -63,6 +63,7 @@ #include "gstrings.h" #include "farchive.h" #include "r_data/colormaps.h" +#include "r_renderer.h" // MACROS ------------------------------------------------------------------ @@ -523,7 +524,7 @@ bool AActor::SetState (FState *newstate, bool nofunction) if (screen != NULL) { - screen->StateChanged(this); + Renderer->StateChanged(this); } return true; } @@ -3607,7 +3608,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t } if (screen != NULL) { - screen->StateChanged(actor); + Renderer->StateChanged(actor); } return actor; } diff --git a/src/p_user.cpp b/src/p_user.cpp index bbf4be3a58..df8d88725d 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -53,6 +53,7 @@ #include "d_net.h" #include "gstrings.h" #include "farchive.h" +#include "r_renderer.h" static FRandom pr_skullpop ("SkullPop"); @@ -2196,11 +2197,11 @@ void P_PlayerThink (player_t *player) player->mo->pitch -= look; if (look > 0) { // look up - player->mo->pitch = MAX(player->mo->pitch, screen->GetMaxViewPitch(false)); + player->mo->pitch = MAX(player->mo->pitch, Renderer->GetMaxViewPitch(false)); } else { // look down - player->mo->pitch = MIN(player->mo->pitch, screen->GetMaxViewPitch(true)); + player->mo->pitch = MIN(player->mo->pitch, Renderer->GetMaxViewPitch(true)); } } } diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index 7ab9bb1769..b78d87256f 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -52,6 +52,7 @@ #include "v_video.h" #include "templates.h" #include "r_utility.h" +#include "r_renderer.h" static bool R_CheckForFixedLights(const BYTE *colormaps); @@ -205,7 +206,7 @@ FDynamicColormap *GetSpecialLights (PalEntry color, PalEntry fade, int desaturat colormap->Desaturate = desaturate; NormalLight.Next = colormap; - if (screen->UsesColormap()) + if (Renderer->UsesColormap()) { colormap->Maps = new BYTE[NUMCOLORMAPS*256]; colormap->BuildLights (); @@ -365,7 +366,7 @@ void FDynamicColormap::ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor) void FDynamicColormap::RebuildAllLights() { - if (screen->UsesColormap()) + if (Renderer->UsesColormap()) { FDynamicColormap *cm; diff --git a/src/r_data/colormaps.h b/src/r_data/colormaps.h index ba55410a82..81f9080e0c 100644 --- a/src/r_data/colormaps.h +++ b/src/r_data/colormaps.h @@ -6,7 +6,7 @@ void R_DeinitColormaps (); DWORD R_ColormapNumForName(const char *name); // killough 4/4/98 void R_SetDefaultColormap (const char *name); // [RH] change normal fadetable -DWORD R_BlendForColormap (DWORD map); // [RH] return calculated blend for a colormap +DWORD R_BlendForColormap (DWORD map); // [RH] return calculated blend for a colormap extern BYTE *realcolormaps; // [RH] make the colormaps externally visible extern size_t numfakecmaps; diff --git a/src/r_main.cpp b/src/r_main.cpp index 3a9fce10a2..5a0bd4b825 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -36,6 +36,9 @@ #include "m_bbox.h" #include "p_local.h" #include "r_local.h" +#include "r_plane.h" +#include "r_bsp.h" +#include "r_3dfloors.h" #include "r_sky.h" #include "st_stuff.h" #include "c_cvars.h" @@ -48,9 +51,6 @@ #include "r_data/r_translate.h" #include "p_3dmidtex.h" #include "r_data/r_interpolate.h" -#include "r_bsp.h" -#include "r_plane.h" -#include "r_3dfloors.h" #include "v_palette.h" #include "po_man.h" #include "p_effect.h" @@ -70,16 +70,6 @@ // TYPES ------------------------------------------------------------------- -struct InterpolationViewer -{ - AActor *ViewActor; - int otic; - fixed_t oviewx, oviewy, oviewz; - fixed_t nviewx, nviewy, nviewz; - int oviewpitch, nviewpitch; - angle_t oviewangle, nviewangle; -}; - // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- void R_SpanInitData (); @@ -90,34 +80,28 @@ bool RP_SetupFrame (bool backside); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void R_Shutdown(); +static void R_ShutdownRenderer(); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -extern bool DrawFSHUD; // [RH] Defined in d_main.cpp extern short *openings; extern bool r_fakingunderwater; extern "C" int fuzzviewheight; -EXTERN_CVAR (Bool, cl_capfps) + // PRIVATE DATA DECLARATIONS ----------------------------------------------- static float CurrentVisibility = 8.f; static fixed_t MaxVisForWall; static fixed_t MaxVisForFloor; -static FRandom pr_torchflicker ("TorchFlicker"); -static FRandom pr_hom; -static TArray PastViewers; static bool polyclipped; -static bool r_showviewer; +extern bool r_showviewer; bool r_dontmaplines; // PUBLIC DATA DEFINITIONS ------------------------------------------------- CVAR (String, r_viewsize, "", CVAR_NOSET) CVAR (Int, r_polymost, 0, 0) -CVAR (Bool, r_deathcamera, false, CVAR_ARCHIVE) -CVAR (Int, r_clearbuffer, 0, 0) CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE) fixed_t r_BaseVisibility; @@ -128,17 +112,6 @@ fixed_t r_SpriteVisibility; fixed_t r_ParticleVisibility; fixed_t r_SkyVisibility; -fixed_t r_TicFrac; // [RH] Fractional tic to render -DWORD r_FrameTime; // [RH] Time this frame started drawing (in ms) -bool r_NoInterpolate; - -angle_t LocalViewAngle; -int LocalViewPitch; -bool LocalKeyboardTurner; - -float LastFOV; -int WidescreenRatio; - fixed_t GlobVis; fixed_t viewingrangerecip; fixed_t FocalTangent; @@ -161,7 +134,6 @@ int centerxwide; } -DCanvas *RenderTarget; // [RH] canvas to render to bool bRenderingToCanvas; // [RH] True if rendering to a special canvas fixed_t globaluclip, globaldclip; fixed_t centerxfrac; @@ -172,24 +144,9 @@ float iyaspectmulfloat; fixed_t InvZtoScale; // just for profiling purposes -int framecount; int linecount; int loopcount; -fixed_t viewx; -fixed_t viewy; -fixed_t viewz; -int viewpitch; -int otic; - -angle_t viewangle; -sector_t *viewsector; - -fixed_t viewcos, viewtancos; -fixed_t viewsin, viewtansin; - -AActor *camera; // [RH] camera to draw from. doesn't have to be a player - int r_Yaspect = 200; // Why did I make this a variable? It's never set anywhere. // @@ -202,16 +159,11 @@ int FieldOfView = 2048; // Fineangles in the SCREENWIDTH wide window // from clipangle to -clipangle. angle_t xtoviewangle[MAXWIDTH+1]; -int extralight; // bumped light from gun blasts bool foggy; // [RH] ignore extralight and fullbright? int r_actualextralight; bool setsizeneeded; -int setblocks; -fixed_t freelookviewheight; - -unsigned int R_OldBlend = ~0; void (*colfunc) (void); void (*basecolfunc) (void); @@ -231,206 +183,9 @@ FCanvasTextureInfo *FCanvasTextureInfo::List; // PRIVATE DATA DEFINITIONS ------------------------------------------------ static int lastcenteryfrac; -static bool NoInterpolateView; // CODE -------------------------------------------------------------------- -//========================================================================== -// -// SlopeDiv -// -// Utility function, called by R_PointToAngle. -// -//========================================================================== - -angle_t SlopeDiv (unsigned int num, unsigned den) -{ - unsigned int ans; - - if (den < 512) - return (ANG45 - 1); //tantoangle[SLOPERANGE] - - ans = (num << 3) / (den >> 8); - - return ans <= SLOPERANGE ? tantoangle[ans] : (ANG45 - 1); -} - - -//========================================================================== -// -// R_PointToAngle -// -// To get a global angle from cartesian coordinates, the coordinates are -// flipped until they are in the first octant of the coordinate system, -// then the y (<=x) is scaled and divided by x to get a tangent (slope) -// value which is looked up in the tantoangle[] table. -// -//========================================================================== - -angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y) -{ - x -= x1; - y -= y1; - - if ((x | y) == 0) - { - return 0; - } - - // We need to be aware of overflows here. If the values get larger than INT_MAX/4 - // this code won't work anymore. - - if (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4) - { - if (x >= 0) - { - if (y >= 0) - { - if (x > y) - { // octant 0 - return SlopeDiv(y, x); - } - else - { // octant 1 - return ANG90 - 1 - SlopeDiv(x, y); - } - } - else // y < 0 - { - y = -y; - if (x > y) - { // octant 8 - return 0 - SlopeDiv(y, x); - } - else - { // octant 7 - return ANG270 + SlopeDiv(x, y); - } - } - } - else // x < 0 - { - x = -x; - if (y >= 0) - { - if (x > y) - { // octant 3 - return ANG180 - 1 - SlopeDiv(y, x); - } - else - { // octant 2 - return ANG90 + SlopeDiv(x, y); - } - } - else // y < 0 - { - y = -y; - if (x > y) - { // octant 4 - return ANG180 + SlopeDiv(y, x); - } - else - { // octant 5 - return ANG270 - 1 - SlopeDiv(x, y); - } - } - } - } - else - { - // we have to use the slower but more precise floating point atan2 function here. - return xs_RoundToUInt(atan2(double(y), double(x)) * (ANGLE_180/M_PI)); - } -} - -//========================================================================== -// -// R_InitPointToAngle -// -//========================================================================== - -void R_InitPointToAngle (void) -{ - double f; - int i; -// -// slope (tangent) to angle lookup -// - for (i = 0; i <= SLOPERANGE; i++) - { - f = atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); - tantoangle[i] = (angle_t)(0xffffffff*f); - } -} - -//========================================================================== -// -// R_PointToDist2 -// -// Returns the distance from (0,0) to some other point. In a -// floating point environment, we'd probably be better off using the -// Pythagorean Theorem to determine the result. -// -// killough 5/2/98: simplified -// [RH] Simplified further [sin (t + 90 deg) == cos (t)] -// Not used. Should it go away? -// -//========================================================================== - -fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy) -{ - dx = abs (dx); - dy = abs (dy); - - if ((dx | dy) == 0) - { - return 0; - } - - if (dy > dx) - { - swapvalues (dx, dy); - } - - return FixedDiv (dx, finecosine[tantoangle[FixedDiv (dy, dx) >> DBITS] >> ANGLETOFINESHIFT]); -} - -//========================================================================== -// -// R_InitTables -// -//========================================================================== - -void R_InitTables (void) -{ - int i; - const double pimul = PI*2/FINEANGLES; - - // viewangle tangent table - finetangent[0] = (fixed_t)(FRACUNIT*tan ((0.5-FINEANGLES/4)*pimul)+0.5); - for (i = 1; i < FINEANGLES/2; i++) - { - finetangent[i] = (fixed_t)(FRACUNIT*tan ((i-FINEANGLES/4)*pimul)+0.5); - } - - // finesine table - for (i = 0; i < FINEANGLES/4; i++) - { - finesine[i] = (fixed_t)(FRACUNIT * sin (i*pimul)); - } - for (i = 0; i < FINEANGLES/4; i++) - { - finesine[i+FINEANGLES/4] = finesine[FINEANGLES/4-1-i]; - } - for (i = 0; i < FINEANGLES/2; i++) - { - finesine[i+FINEANGLES/2] = -finesine[i]; - } - finesine[FINEANGLES/4] = FRACUNIT; - finesine[FINEANGLES*3/4] = -FRACUNIT; - memcpy (&finesine[FINEANGLES], &finesine[0], sizeof(angle_t)*FINEANGLES/4); -} - //========================================================================== // // viewangletox @@ -528,41 +283,6 @@ void R_InitTextureMapping () } } -//========================================================================== -// -// R_SetFOV -// -// Changes the field of view in degrees -// -//========================================================================== - -void R_SetFOV (float fov) -{ - if (fov < 5.f) - fov = 5.f; - else if (fov > 170.f) - fov = 170.f; - if (fov != LastFOV) - { - LastFOV = fov; - FieldOfView = (int)(fov * (float)FINEANGLES / 360.f); - setsizeneeded = true; - } -} - -//========================================================================== -// -// R_GetFOV -// -// Returns the current field of view in degrees -// -//========================================================================== - -float R_GetFOV () -{ - return LastFOV; -} - //========================================================================== // // R_SetVisibility @@ -652,56 +372,15 @@ CCMD (r_visibility) } } -//========================================================================== -// -// R_SetViewSize -// -// Do not really change anything here, because it might be in the middle -// of a refresh. The change will take effect next refresh. -// -//========================================================================== - -void R_SetViewSize (int blocks) -{ - setsizeneeded = true; - setblocks = blocks; -} - //========================================================================== // // R_SetWindow // //========================================================================== -void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) +void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) { - int virtheight, virtwidth, trueratio, virtwidth2, virtheight2; - - if (windowSize >= 11) - { - viewwidth = fullWidth; - freelookviewheight = viewheight = fullHeight; - } - else if (windowSize == 10) - { - viewwidth = fullWidth; - viewheight = stHeight; - freelookviewheight = fullHeight; - } - else - { - viewwidth = ((setblocks*fullWidth)/10) & (~15); - viewheight = ((setblocks*stHeight)/10)&~7; - freelookviewheight = ((setblocks*fullHeight)/10)&~7; - } - - // If the screen is approximately 16:9 or 16:10, consider it widescreen. - WidescreenRatio = CheckRatio (fullWidth, fullHeight, &trueratio); - - DrawFSHUD = (windowSize == 11); - - fuzzviewheight = viewheight - 2; // Maximum row the fuzzer can draw to - halfviewwidth = (viewwidth >> 1) - 1; + int virtheight, virtwidth, virtwidth2, virtheight2; if (!bRenderingToCanvas) { // Set r_viewsize cvar to reflect the current view size @@ -713,6 +392,9 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) r_viewsize.ForceSet (value, CVAR_String); } + fuzzviewheight = viewheight - 2; // Maximum row the fuzzer can draw to + halfviewwidth = (viewwidth >> 1) - 1; + lastcenteryfrac = 1<<30; centery = viewheight/2; centerx = viewwidth/2; @@ -758,9 +440,6 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) // thing clipping clearbufshort (screenheightarray, viewwidth, (short)viewheight); - // [RH] Sky height fix for screens not 200 (or 240) pixels tall - R_InitSkyMap (); - R_InitTextureMapping (); MaxVisForWall = FixedMul (Scale (InvZtoScale, SCREENWIDTH*r_Yaspect, @@ -772,44 +451,6 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) R_SetVisibility (R_GetVisibility ()); } -//========================================================================== -// -// R_ExecuteSetViewSize -// -//========================================================================== - -void R_ExecuteSetViewSize () -{ - setsizeneeded = false; - BorderNeedRefresh = screen->GetPageCount (); - - R_SetWindow (setblocks, SCREENWIDTH, SCREENHEIGHT, ST_Y); - - // Handle resize, e.g. smaller view windows with border and/or status bar. - viewwindowx = (screen->GetWidth() - viewwidth) >> 1; - - // Same with base row offset. - viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (ST_Y - viewheight) >> 1; -} - -//========================================================================== -// -// CVAR screenblocks -// -// Selects the size of the visible window -// -//========================================================================== - -CUSTOM_CVAR (Int, screenblocks, 10, CVAR_ARCHIVE) -{ - if (self > 12) - self = 12; - else if (self < 3) - self = 3; - else - R_SetViewSize (self); -} - //========================================================================== // // CVAR r_columnmethod @@ -836,25 +477,13 @@ CUSTOM_CVAR (Int, r_columnmethod, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //========================================================================== -void R_Init () +void R_InitRenderer() { - atterm (R_Shutdown); - + atterm(R_ShutdownRenderer); + // viewwidth / viewheight are set by the defaults clearbufshort (zeroarray, MAXWIDTH, 0); - StartScreen->Progress(); - V_InitFonts(); - StartScreen->Progress(); - R_InitColormaps (); - StartScreen->Progress(); - - R_InitPointToAngle (); - R_InitTables (); - // viewwidth / viewheight are set by the defaults - - R_SetViewSize (screenblocks); R_InitPlanes (); - R_InitTranslationTables (); R_InitShadeMaps(); R_InitColumnDrawers (); @@ -867,23 +496,17 @@ void R_Init () hcolfunc_pre = R_DrawColumnHoriz; hcolfunc_post1 = rt_map1col; hcolfunc_post4 = rt_map4cols; - - framecount = 0; } //========================================================================== // -// R_Shutdown +// R_ShutdownRenderer // //========================================================================== -static void R_Shutdown () +static void R_ShutdownRenderer() { - R_DeinitTranslationTables(); R_DeinitPlanes(); - R_DeinitColormaps (); - FCanvasTextureInfo::EmptyList(); - // Free openings if (openings != NULL) { @@ -899,200 +522,6 @@ static void R_Shutdown () } } -//========================================================================== -// -// R_PointInSubsector -// -//========================================================================== - -subsector_t *R_PointInSubsector (fixed_t x, fixed_t y) -{ - node_t *node; - int side; - - // single subsector is a special case - if (numnodes == 0) - return subsectors; - - node = nodes + numnodes - 1; - - do - { - side = R_PointOnSide (x, y, node); - node = (node_t *)node->children[side]; - } - while (!((size_t)node & 1)); - - return (subsector_t *)((BYTE *)node - 1); -} - -//========================================================================== -// -// R_InterpolateView -// -//========================================================================== - -//CVAR (Int, tf, 0, 0) -EXTERN_CVAR (Bool, cl_noprediction) - -void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *iview) -{ -// frac = tf; - if (NoInterpolateView) - { - NoInterpolateView = false; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; - } - viewx = iview->oviewx + FixedMul (frac, iview->nviewx - iview->oviewx); - viewy = iview->oviewy + FixedMul (frac, iview->nviewy - iview->oviewy); - viewz = iview->oviewz + FixedMul (frac, iview->nviewz - iview->oviewz); - if (player != NULL && - player - players == consoleplayer && - camera == player->mo && - !demoplayback && - iview->nviewx == camera->x && - iview->nviewy == camera->y && - !(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) && - player->playerstate == PST_LIVE && - player->mo->reactiontime == 0 && - !NoInterpolateView && - !paused && - (!netgame || !cl_noprediction) && - !LocalKeyboardTurner) - { - viewangle = iview->nviewangle + (LocalViewAngle & 0xFFFF0000); - - fixed_t delta = -(signed)(LocalViewPitch & 0xFFFF0000); - - viewpitch = iview->nviewpitch; - if (delta > 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch + delta <= viewpitch) - { - viewpitch = screen->GetMaxViewPitch(true); - } - else - { - viewpitch = MIN(viewpitch + delta, screen->GetMaxViewPitch(true)); - } - } - else if (delta < 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch + delta >= viewpitch) - { - viewpitch = screen->GetMaxViewPitch(false); - } - else - { - viewpitch = MAX(viewpitch + delta, screen->GetMaxViewPitch(false)); - } - } - } - else - { - viewpitch = iview->oviewpitch + FixedMul (frac, iview->nviewpitch - iview->oviewpitch); - viewangle = iview->oviewangle + FixedMul (frac, iview->nviewangle - iview->oviewangle); - } - - // Due to interpolation this is not necessarily the same as the sector the camera is in. - viewsector = R_PointInSubsector(viewx, viewy)->sector; -} - -//========================================================================== -// -// R_ResetViewInterpolation -// -//========================================================================== - -void R_ResetViewInterpolation () -{ - NoInterpolateView = true; -} - -//========================================================================== -// -// R_SetViewAngle -// -//========================================================================== - -void R_SetViewAngle () -{ - angle_t ang = viewangle >> ANGLETOFINESHIFT; - - viewsin = finesine[ang]; - viewcos = finecosine[ang]; - - viewtansin = FixedMul (FocalTangent, viewsin); - viewtancos = FixedMul (FocalTangent, viewcos); -} - -//========================================================================== -// -// FindPastViewer -// -//========================================================================== - -static InterpolationViewer *FindPastViewer (AActor *actor) -{ - for (unsigned int i = 0; i < PastViewers.Size(); ++i) - { - if (PastViewers[i].ViewActor == actor) - { - return &PastViewers[i]; - } - } - - // Not found, so make a new one - InterpolationViewer iview = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - iview.ViewActor = actor; - iview.otic = -1; - return &PastViewers[PastViewers.Push (iview)]; -} - -//========================================================================== -// -// R_FreePastViewers -// -//========================================================================== - -void R_FreePastViewers () -{ - PastViewers.Clear (); -} - -//========================================================================== -// -// R_ClearPastViewer -// -// If the actor changed in a non-interpolatable way, remove it. -// -//========================================================================== - -void R_ClearPastViewer (AActor *actor) -{ - for (unsigned int i = 0; i < PastViewers.Size(); ++i) - { - if (PastViewers[i].ViewActor == actor) - { - // Found it, so remove it. - if (i == PastViewers.Size()) - { - PastViewers.Delete (i); - } - else - { - PastViewers.Pop (PastViewers[i]); - } - } - } -} - //========================================================================== // // R_CopyStackedViewParameters @@ -1111,198 +540,14 @@ void R_CopyStackedViewParameters() //========================================================================== // -// R_SetupFrame +// R_SetupColormap +// +// Sets up special fixed colormaps // //========================================================================== -void R_SetupFrame (AActor *actor) +void R_SetupColormap(player_t *player) { - if (actor == NULL) - { - I_Error ("Tried to render from a NULL actor."); - } - - player_t *player = actor->player; - unsigned int newblend; - InterpolationViewer *iview; - - if (player != NULL && player->mo == actor) - { // [RH] Use camera instead of viewplayer - camera = player->camera; - if (camera == NULL) - { - camera = player->camera = player->mo; - } - if (camera == actor) - { - P_PredictPlayer (player); - } - } - else - { - camera = actor; - } - - if (camera == NULL) - { - I_Error ("You lost your body. Bad dehacked work is likely to blame."); - } - - iview = FindPastViewer (camera); - - int nowtic = I_GetTime (false); - if (iview->otic != -1 && nowtic > iview->otic) - { - iview->otic = nowtic; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; - } - - if (player != NULL && gamestate != GS_TITLELEVEL && - ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && - (camera->RenderStyle.BlendOp != STYLEOP_None) && - !(camera->renderflags & RF_INVISIBLE) && - camera->sprite != SPR_TNT1) - { - // [RH] Use chasecam view - P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector); - r_showviewer = true; - } - else - { - iview->nviewx = camera->x; - iview->nviewy = camera->y; - iview->nviewz = camera->player ? camera->player->viewz : camera->z + camera->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight); - viewsector = camera->Sector; - r_showviewer = false; - } - iview->nviewpitch = camera->pitch; - if (camera->player != 0) - { - player = camera->player; - } - - iview->nviewangle = camera->angle + viewangleoffset; - if (iview->otic == -1 || r_NoInterpolate) - { - R_ResetViewInterpolation (); - iview->otic = nowtic; - } - - r_TicFrac = I_GetTimeFrac (&r_FrameTime); - if (cl_capfps || r_NoInterpolate) - { - r_TicFrac = FRACUNIT; - } - - R_InterpolateView (player, r_TicFrac, iview); - -#ifdef TEST_X - viewx = TEST_X; - viewy = TEST_Y; - viewz = TEST_Z; - viewangle = TEST_ANGLE; -#endif - - R_CopyStackedViewParameters(); - R_SetViewAngle (); - - interpolator.DoInterpolations (r_TicFrac); - - // Keep the view within the sector's floor and ceiling - fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT; - if (viewz > theZ) - { - viewz = theZ; - } - - theZ = viewsector->floorplane.ZatPoint (viewx, viewy) + 4*FRACUNIT; - if (viewz < theZ) - { - viewz = theZ; - } - - if (!paused) - { - int intensity = DEarthquake::StaticGetQuakeIntensity (camera); - if (intensity != 0) - { - viewx += ((pr_torchflicker() % (intensity<<2)) - -(intensity<<1))<player ? camera->player->extralight : 0; - newblend = 0; - - // killough 3/20/98, 4/4/98: select colormap based on player status - // [RH] Can also select a blend - - TArray &lightlist = viewsector->e->XFloor.lightlist; - if (lightlist.Size() > 0) - { - for(unsigned int i=0;ifloorplane.ZatPoint(viewx, viewy); - - if (lightbottom < viewz) - { - // 3d floor 'fog' is rendered as a blending value - PalEntry blendv = lightlist[i].blend; - - // If no alpha is set, use 50% - if (blendv.a==0 && blendv!=0) blendv.a=128; - newblend = blendv.d; - break; - } - } - } - else - { - const sector_t *s = viewsector->GetHeightSec(); - if (s != NULL) - { - newblend = viewz < s->floorplane.ZatPoint (viewx, viewy) - ? s->bottommap - : viewz > s->ceilingplane.ZatPoint (viewx, viewy) - ? s->topmap - : s->midmap; - if (APART(newblend) == 0 && newblend >= numfakecmaps) - newblend = 0; - } - } - - // [RH] Don't override testblend unless entering a sector with a - // blend different from the previous sector's. Same goes with - // NormalLight's maps pointer. - if (R_OldBlend != newblend) - { - R_OldBlend = newblend; - if (APART(newblend)) - { - BaseBlendR = RPART(newblend); - BaseBlendG = GPART(newblend); - BaseBlendB = BPART(newblend); - BaseBlendA = APART(newblend) / 255.f; - NormalLight.Maps = realcolormaps; - } - else - { - NormalLight.Maps = realcolormaps + NUMCOLORMAPS*256*newblend; - BaseBlendR = BaseBlendG = BaseBlendB = 0; - BaseBlendA = 0.f; - } - } - realfixedcolormap = NULL; fixedcolormap = NULL; fixedlightlev = -1; @@ -1335,8 +580,18 @@ void R_SetupFrame (AActor *actor) fixedcolormap = SpecialColormaps[INVERSECOLORMAP].Colormap; extralight = 0; } +} - // [RH] freelook stuff +//========================================================================== +// +// R_SetupFreelook +// +// [RH] freelook stuff +// +//========================================================================== + +void R_SetupFreelook() +{ { fixed_t dy; @@ -1393,43 +648,14 @@ void R_SetupFrame (AActor *actor) } while (++i < e); } } +} - P_UnPredictPlayer (); - framecount++; - validcount++; - +void R_SetupPolymost() +{ if (r_polymost) { polyclipped = RP_SetupFrame (false); } - - if (RenderTarget == screen && r_clearbuffer != 0) - { - int color; - int hom = r_clearbuffer; - - if (hom == 3) - { - hom = ((I_FPSTime() / 128) & 1) + 1; - } - if (hom == 1) - { - color = GPalette.BlackIndex; - } - else if (hom == 2) - { - color = GPalette.WhiteIndex; - } - else if (hom == 4) - { - color = (I_FPSTime() / 32) & 255; - } - else - { - color = pr_hom(); - } - memset(RenderTarget->GetBuffer(), color, RenderTarget->GetPitch() * RenderTarget->GetHeight()); - } } //========================================================================== @@ -1715,152 +941,6 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, viewactive = savedviewactive; } -//========================================================================== -// -// FCanvasTextureInfo :: Add -// -// Assigns a camera to a canvas texture. -// -//========================================================================== - -void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, int fov) -{ - FCanvasTextureInfo *probe; - FCanvasTexture *texture; - - if (!picnum.isValid()) - { - return; - } - texture = static_cast(TexMan[picnum]); - if (!texture->bHasCanvas) - { - Printf ("%s is not a valid target for a camera\n", texture->Name); - return; - } - - // Is this texture already assigned to a camera? - for (probe = List; probe != NULL; probe = probe->Next) - { - if (probe->Texture == texture) - { - // Yes, change its assignment to this new camera - if (probe->Viewpoint != viewpoint || probe->FOV != fov) - { - texture->bFirstUpdate = true; - } - probe->Viewpoint = viewpoint; - probe->FOV = fov; - return; - } - } - // No, create a new assignment - probe = new FCanvasTextureInfo; - probe->Viewpoint = viewpoint; - probe->Texture = texture; - probe->PicNum = picnum; - probe->FOV = fov; - probe->Next = List; - texture->bFirstUpdate = true; - List = probe; -} - -//========================================================================== -// -// FCanvasTextureInfo :: UpdateAll -// -// Updates all canvas textures that were visible in the last frame. -// -//========================================================================== - -void FCanvasTextureInfo::UpdateAll () -{ - FCanvasTextureInfo *probe; - - for (probe = List; probe != NULL; probe = probe->Next) - { - if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) - { - probe->Texture->RenderView (probe->Viewpoint, probe->FOV); - } - } -} - -//========================================================================== -// -// FCanvasTextureInfo :: EmptyList -// -// Removes all camera->texture assignments. -// -//========================================================================== - -void FCanvasTextureInfo::EmptyList () -{ - FCanvasTextureInfo *probe, *next; - - for (probe = List; probe != NULL; probe = next) - { - next = probe->Next; - delete probe; - } - List = NULL; -} - -//========================================================================== -// -// FCanvasTextureInfo :: Serialize -// -// Reads or writes the current set of mappings in an archive. -// -//========================================================================== - -void FCanvasTextureInfo::Serialize (FArchive &arc) -{ - if (arc.IsStoring ()) - { - FCanvasTextureInfo *probe; - - for (probe = List; probe != NULL; probe = probe->Next) - { - if (probe->Texture != NULL && probe->Viewpoint != NULL) - { - arc << probe->Viewpoint << probe->FOV << probe->PicNum; - } - } - AActor *nullactor = NULL; - arc << nullactor; - } - else - { - AActor *viewpoint; - int fov; - FTextureID picnum; - - EmptyList (); - while (arc << viewpoint, viewpoint != NULL) - { - arc << fov << picnum; - Add (viewpoint, picnum, fov); - } - } -} - -//========================================================================== -// -// FCanvasTextureInfo :: Mark -// -// Marks all viewpoints in the list for the collector. -// -//========================================================================== - -void FCanvasTextureInfo::Mark() -{ - for (FCanvasTextureInfo *probe = List; probe != NULL; probe = probe->Next) - { - GC::Mark(probe->Viewpoint); - } -} - //========================================================================== // // R_MultiresInit @@ -1872,6 +952,5 @@ void FCanvasTextureInfo::Mark() void R_MultiresInit () { R_PlaneInitData (); - R_OldBlend = ~0; } diff --git a/src/r_main.h b/src/r_main.h index 223b1e4b0a..d63ec25341 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -34,7 +34,6 @@ typedef BYTE lighttable_t; // This could be wider for >8 bit display. // // POV related. // -extern DCanvas *RenderTarget; extern bool bRenderingToCanvas; extern fixed_t viewcos; extern fixed_t viewsin; @@ -106,7 +105,7 @@ extern float r_TiltVisibility; extern fixed_t r_SpriteVisibility; extern fixed_t r_SkyVisibility; -extern int extralight, r_actualextralight; +extern int r_actualextralight; extern bool foggy; extern int fixedlightlev; extern lighttable_t* fixedcolormap; @@ -131,8 +130,6 @@ extern void (*hcolfunc_post2) (int hx, int sx, int yl, int yh); extern void (STACK_ARGS *hcolfunc_post4) (int sx, int yl, int yh); -void R_SetFOV (float fov); -float R_GetFOV (); void R_InitTextureMapping (); void R_SetViewAngle (); @@ -147,14 +144,6 @@ void R_SetupBuffer (); void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines = false); - -// Called by startup code. -void R_Init (void); -void R_ExecuteSetViewSize (void); - -// Called by M_Responder. -void R_SetViewSize (int blocks); - // [RH] Initialize multires stuff for renderer void R_MultiresInit (void); diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp index 4cee72f015..0075d6ca04 100644 --- a/src/r_polymost.cpp +++ b/src/r_polymost.cpp @@ -529,7 +529,6 @@ int PolyClipper::DoMost (float x0, float y0, float x1, float y1, pmostcallbackty } #include "d_event.h" -CVAR(Bool, testpolymost, false, 0) static int pmx, pmy; static int pt, px0, py0, px1, py1; static struct polypt { float x, y; } polypts[80]; diff --git a/src/r_polymost.h b/src/r_polymost.h index 8c0957fe01..8afbefb227 100644 --- a/src/r_polymost.h +++ b/src/r_polymost.h @@ -51,7 +51,5 @@ private: }; -EXTERN_CVAR(Bool, testpolymost) - extern void drawpolymosttest(); struct event_t; void Polymost_Responder (event_t *ev); diff --git a/src/r_renderer.h b/src/r_renderer.h new file mode 100644 index 0000000000..e815abf12f --- /dev/null +++ b/src/r_renderer.h @@ -0,0 +1,68 @@ +#ifndef __R_RENDERER_H +#define __R_RENDERER_H + +#include + +struct FRenderer; +extern FRenderer *Renderer; +class FArchive; +class FTexture; +class AActor; +class player_t; +struct sector_t; +class FCanvasTexture; + +struct FRenderer +{ + FRenderer() + { + Renderer = this; + } + + ~FRenderer() + { + Renderer = NULL; + } + + // Can be overridden so that the colormaps for sector color/fade won't be built. + virtual bool UsesColormap() const = 0; + + // precache one texture + virtual void PrecacheTexture(FTexture *tex, int cache) = 0; + + // render 3D view + virtual void RenderView(player_t *player) = 0; + + // Remap voxel palette + virtual void RemapVoxels() {} + + // renders view to a savegame picture + virtual void WriteSavePic (player_t *player, FILE *file, int width, int height) = 0; + + // draws player sprites with hardware acceleration (only useful for software rendering) + virtual void DrawRemainingPlayerSprites() {} + + // notifies the renderer that an actor has changed state. + virtual void StateChanged(AActor *actor) {} + + // notify the renderer that serialization of the curent level is about to start/end + virtual void StartSerialize(FArchive &arc) {} + virtual void EndSerialize(FArchive &arc) {} + + virtual int GetMaxViewPitch(bool down) = 0; + + virtual void OnModeSet () {} + virtual void ErrorCleanup () {} + virtual void ClearBuffer(int color) = 0; + virtual void Init() = 0; + virtual void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) {} + virtual void SetupFrame(player_t *player) {} + virtual void CopyStackedViewParameters() {} + virtual void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) = 0; + virtual sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) = 0; + + +}; + + +#endif diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 8ff2d6c62d..fb65cf9add 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -54,7 +54,7 @@ CUSTOM_CVAR (Bool, r_stretchsky, true, CVAR_ARCHIVE) R_InitSkyMap (); } -extern fixed_t freelookviewheight; +fixed_t freelookviewheight; //========================================================================== // diff --git a/src/r_sky.h b/src/r_sky.h index f285c4268c..2c8c62dc73 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -33,6 +33,7 @@ extern fixed_t skytexturemid; extern fixed_t skyiscale; extern fixed_t skyscale; extern bool skystretch; +extern fixed_t freelookviewheight; #define SKYSTRETCH_HEIGHT 228 diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp new file mode 100644 index 0000000000..c518abf909 --- /dev/null +++ b/src/r_swrenderer.cpp @@ -0,0 +1,298 @@ +/* +** r_swrender.cpp +** Software renderer interface +** +**--------------------------------------------------------------------------- +** Copyright 2011 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + + +#include "r_local.h" +#include "v_palette.h" +#include "v_video.h" +#include "m_png.h" +#include "r_bsp.h" +#include "r_swrenderer.h" +#include "r_3dfloors.h" +#include "r_polymost.h" +#include "textures/textures.h" +#include "r_data/voxels.h" + + +class FArchive; +void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); +void R_SetupColormap(player_t *); +void R_SetupFreelook(); +void R_SetupPolymost(); +void R_InitRenderer(); + +extern float LastFOV; + +//========================================================================== +// +// DCanvas :: Init +// +//========================================================================== + +void FSoftwareRenderer::Init() +{ + R_InitRenderer(); +} + +//========================================================================== +// +// DCanvas :: UsesColormap +// +//========================================================================== + +bool FSoftwareRenderer::UsesColormap() const +{ + return true; +} + +//=========================================================================== +// +// Texture precaching +// +//=========================================================================== + +void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) +{ + if (tex != NULL) + { + if (cache & 1) + { + const FTexture::Span *spanp; + tex->GetColumn(0, &spanp); + } + else if (cache != 0) + { + tex->GetPixels (); + } + else + { + tex->Unload (); + } + } +} + +//=========================================================================== +// +// Render the view +// +//=========================================================================== + +void FSoftwareRenderer::RenderView(player_t *player) +{ + R_RenderActorView (player->mo); + // [RH] Let cameras draw onto textures that were visible this frame. + FCanvasTextureInfo::UpdateAll (); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareRenderer::RemapVoxels() +{ + for (unsigned i=0; iRemap(); + } +} + +//=========================================================================== +// +// Render the view to a savegame picture +// +//=========================================================================== + +void FSoftwareRenderer::WriteSavePic (player_t *player, FILE *file, int width, int height) +{ + DCanvas *pic = new DSimpleCanvas (width, height); + PalEntry palette[256]; + + // Take a snapshot of the player's view + pic->ObjectFlags |= OF_Fixed; + pic->Lock (); + R_RenderViewToCanvas (player->mo, pic, 0, 0, width, height); + screen->GetFlashedPalette (palette); + M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch()); + pic->Unlock (); + pic->Destroy(); + pic->ObjectFlags |= OF_YesReallyDelete; + delete pic; +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FSoftwareRenderer::DrawRemainingPlayerSprites() +{ + R_DrawRemainingPlayerSprites(); +} + +//=========================================================================== +// +// Get max. view angle (renderer specific information so it goes here now) +// +//=========================================================================== +#define MAX_DN_ANGLE 56 // Max looking down angle +#define MAX_UP_ANGLE 32 // Max looking up angle + +int FSoftwareRenderer::GetMaxViewPitch(bool down) +{ + return down? MAX_DN_ANGLE*ANGLE_1 : -MAX_UP_ANGLE*ANGLE_1; +} + +//========================================================================== +// +// OnModeSet +// +// Called from V_SetResolution() +// +//========================================================================== + +void FSoftwareRenderer::OnModeSet () +{ + R_MultiresInit (); + + RenderTarget = screen; + screen->Lock (true); + R_SetupBuffer (); + screen->Unlock (); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FSoftwareRenderer::ErrorCleanup () +{ + fakeActive = 0; + fake3D = 0; + while (CurrentSkybox) + { + R_3D_DeleteHeights(); + R_3D_LeaveSkybox(); + } + R_3D_ResetClip(); + R_3D_DeleteHeights(); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FSoftwareRenderer::ClearBuffer(int color) +{ + memset(RenderTarget->GetBuffer(), color, RenderTarget->GetPitch() * RenderTarget->GetHeight()); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FSoftwareRenderer::SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) +{ + R_SWRSetWindow(windowSize, fullWidth, fullHeight, stHeight, trueratio); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FSoftwareRenderer::SetupFrame(player_t *player) +{ + R_SetupColormap(player); + R_SetupFreelook(); + R_SetupPolymost(); +} + +//========================================================================== +// +// R_CopyStackedViewParameters +// +//========================================================================== + +void FSoftwareRenderer::CopyStackedViewParameters() +{ + R_CopyStackedViewParameters(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) +{ + BYTE *Pixels = const_cast(tex->GetPixels()); + DSimpleCanvas *Canvas = tex->GetCanvas(); + + float savedfov = LastFOV; + R_SetFOV ((float)fov); + R_RenderViewToCanvas (viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); + R_SetFOV (savedfov); + if (Pixels == Canvas->GetBuffer()) + { + FTexture::FlipSquareBlockRemap (Pixels, tex->GetWidth(), tex->GetHeight(), GPalette.Remap); + } + else + { + FTexture::FlipNonSquareBlockRemap (Pixels, Canvas->GetBuffer(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap); + } + tex->SetUpdated(); +} + +//========================================================================== +// +// +// +//========================================================================== + +sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) +{ + return R_FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, back); +} + diff --git a/src/r_swrenderer.h b/src/r_swrenderer.h new file mode 100644 index 0000000000..4b37e4eed6 --- /dev/null +++ b/src/r_swrenderer.h @@ -0,0 +1,41 @@ +#ifndef __R_SWRENDERER_H +#define __R_SWRENDERER_H + +#include "r_renderer.h" + +struct FSoftwareRenderer : public FRenderer +{ + // Can be overridden so that the colormaps for sector color/fade won't be built. + virtual bool UsesColormap() const; + + // precache one texture + virtual void PrecacheTexture(FTexture *tex, int cache); + + // render 3D view + virtual void RenderView(player_t *player); + + // Remap voxel palette + virtual void RemapVoxels(); + + // renders view to a savegame picture + virtual void WriteSavePic (player_t *player, FILE *file, int width, int height); + + // draws player sprites with hardware acceleration (only useful for software rendering) + virtual void DrawRemainingPlayerSprites(); + + virtual int GetMaxViewPitch(bool down); + + void OnModeSet (); + void ErrorCleanup (); + void ClearBuffer(int color); + void Init(); + void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); + void SetupFrame(player_t *player); + void CopyStackedViewParameters(); + void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov); + sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back); + +}; + + +#endif diff --git a/src/r_utility.cpp b/src/r_utility.cpp new file mode 100644 index 0000000000..dc3cb15650 --- /dev/null +++ b/src/r_utility.cpp @@ -0,0 +1,1050 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// Rendering main loop and setup functions, +// utility functions (BSP, geometry, trigonometry). +// See tables.c, too. +// +//----------------------------------------------------------------------------- + +// HEADER FILES ------------------------------------------------------------ + +#include +#include + +#include "templates.h" +#include "doomdef.h" +#include "d_net.h" +#include "doomstat.h" +#include "m_random.h" +#include "m_bbox.h" +#include "p_local.h" +#include "r_sky.h" +#include "st_stuff.h" +#include "c_cvars.h" +#include "c_dispatch.h" +#include "v_video.h" +#include "stats.h" +#include "i_video.h" +#include "i_system.h" +#include "a_sharedglobal.h" +#include "r_data/r_translate.h" +#include "p_3dmidtex.h" +#include "r_data/r_interpolate.h" +#include "v_palette.h" +#include "po_man.h" +#include "p_effect.h" +#include "st_start.h" +#include "v_font.h" +#include "r_renderer.h" +#include "r_data/colormaps.h" +#include "farchive.h" + + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +extern bool DrawFSHUD; // [RH] Defined in d_main.cpp +EXTERN_CVAR (Bool, cl_capfps) + +// TYPES ------------------------------------------------------------------- + +struct InterpolationViewer +{ + AActor *ViewActor; + int otic; + fixed_t oviewx, oviewy, oviewz; + fixed_t nviewx, nviewy, nviewz; + int oviewpitch, nviewpitch; + angle_t oviewangle, nviewangle; +}; + +// PRIVATE DATA DECLARATIONS ----------------------------------------------- +static TArray PastViewers; +static FRandom pr_torchflicker ("TorchFlicker"); +static FRandom pr_hom; +static bool NoInterpolateView; + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +CVAR (Bool, r_deathcamera, false, CVAR_ARCHIVE) +CVAR (Int, r_clearbuffer, 0, 0) + +DCanvas *RenderTarget; // [RH] canvas to render to + +fixed_t viewx; +fixed_t viewy; +fixed_t viewz; +int viewpitch; +int otic; + +angle_t viewangle; +sector_t *viewsector; + +fixed_t viewcos, viewtancos; +fixed_t viewsin, viewtansin; + +AActor *camera; // [RH] camera to draw from. doesn't have to be a player + +fixed_t r_TicFrac; // [RH] Fractional tic to render +DWORD r_FrameTime; // [RH] Time this frame started drawing (in ms) +bool r_NoInterpolate; +bool r_showviewer; + +angle_t LocalViewAngle; +int LocalViewPitch; +bool LocalKeyboardTurner; + +float LastFOV; +int WidescreenRatio; +int setblocks; +int extralight; + +unsigned int R_OldBlend = ~0; + + +// CODE -------------------------------------------------------------------- +static void R_Shutdown (); + +//========================================================================== +// +// SlopeDiv +// +// Utility function, called by R_PointToAngle. +// +//========================================================================== + +angle_t SlopeDiv (unsigned int num, unsigned den) +{ + unsigned int ans; + + if (den < 512) + return (ANG45 - 1); //tantoangle[SLOPERANGE] + + ans = (num << 3) / (den >> 8); + + return ans <= SLOPERANGE ? tantoangle[ans] : (ANG45 - 1); +} + + +//========================================================================== +// +// R_PointToAngle +// +// To get a global angle from cartesian coordinates, the coordinates are +// flipped until they are in the first octant of the coordinate system, +// then the y (<=x) is scaled and divided by x to get a tangent (slope) +// value which is looked up in the tantoangle[] table. +// +//========================================================================== + +angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y) +{ + x -= x1; + y -= y1; + + if ((x | y) == 0) + { + return 0; + } + + // We need to be aware of overflows here. If the values get larger than INT_MAX/4 + // this code won't work anymore. + + if (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4) + { + if (x >= 0) + { + if (y >= 0) + { + if (x > y) + { // octant 0 + return SlopeDiv(y, x); + } + else + { // octant 1 + return ANG90 - 1 - SlopeDiv(x, y); + } + } + else // y < 0 + { + y = -y; + if (x > y) + { // octant 8 + return 0 - SlopeDiv(y, x); + } + else + { // octant 7 + return ANG270 + SlopeDiv(x, y); + } + } + } + else // x < 0 + { + x = -x; + if (y >= 0) + { + if (x > y) + { // octant 3 + return ANG180 - 1 - SlopeDiv(y, x); + } + else + { // octant 2 + return ANG90 + SlopeDiv(x, y); + } + } + else // y < 0 + { + y = -y; + if (x > y) + { // octant 4 + return ANG180 + SlopeDiv(y, x); + } + else + { // octant 5 + return ANG270 - 1 - SlopeDiv(x, y); + } + } + } + } + else + { + // we have to use the slower but more precise floating point atan2 function here. + return xs_RoundToUInt(atan2(double(y), double(x)) * (ANGLE_180/M_PI)); + } +} + +//========================================================================== +// +// R_InitPointToAngle +// +//========================================================================== + +void R_InitPointToAngle (void) +{ + double f; + int i; +// +// slope (tangent) to angle lookup +// + for (i = 0; i <= SLOPERANGE; i++) + { + f = atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); + tantoangle[i] = (angle_t)(0xffffffff*f); + } +} + +//========================================================================== +// +// R_PointToDist2 +// +// Returns the distance from (0,0) to some other point. In a +// floating point environment, we'd probably be better off using the +// Pythagorean Theorem to determine the result. +// +// killough 5/2/98: simplified +// [RH] Simplified further [sin (t + 90 deg) == cos (t)] +// Not used. Should it go away? +// +//========================================================================== + +fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy) +{ + dx = abs (dx); + dy = abs (dy); + + if ((dx | dy) == 0) + { + return 0; + } + + if (dy > dx) + { + swapvalues (dx, dy); + } + + return FixedDiv (dx, finecosine[tantoangle[FixedDiv (dy, dx) >> DBITS] >> ANGLETOFINESHIFT]); +} + +//========================================================================== +// +// R_InitTables +// +//========================================================================== + +void R_InitTables (void) +{ + int i; + const double pimul = PI*2/FINEANGLES; + + // viewangle tangent table + finetangent[0] = (fixed_t)(FRACUNIT*tan ((0.5-FINEANGLES/4)*pimul)+0.5); + for (i = 1; i < FINEANGLES/2; i++) + { + finetangent[i] = (fixed_t)(FRACUNIT*tan ((i-FINEANGLES/4)*pimul)+0.5); + } + + // finesine table + for (i = 0; i < FINEANGLES/4; i++) + { + finesine[i] = (fixed_t)(FRACUNIT * sin (i*pimul)); + } + for (i = 0; i < FINEANGLES/4; i++) + { + finesine[i+FINEANGLES/4] = finesine[FINEANGLES/4-1-i]; + } + for (i = 0; i < FINEANGLES/2; i++) + { + finesine[i+FINEANGLES/2] = -finesine[i]; + } + finesine[FINEANGLES/4] = FRACUNIT; + finesine[FINEANGLES*3/4] = -FRACUNIT; + memcpy (&finesine[FINEANGLES], &finesine[0], sizeof(angle_t)*FINEANGLES/4); +} + +//========================================================================== +// +// R_SetFOV +// +// Changes the field of view in degrees +// +//========================================================================== + +void R_SetFOV (float fov) +{ + if (fov < 5.f) + fov = 5.f; + else if (fov > 170.f) + fov = 170.f; + if (fov != LastFOV) + { + LastFOV = fov; + FieldOfView = (int)(fov * (float)FINEANGLES / 360.f); + setsizeneeded = true; + } +} + +//========================================================================== +// +// R_GetFOV +// +// Returns the current field of view in degrees +// +//========================================================================== + +float R_GetFOV () +{ + return LastFOV; +} + +//========================================================================== +// +// R_SetViewSize +// +// Do not really change anything here, because it might be in the middle +// of a refresh. The change will take effect next refresh. +// +//========================================================================== + +void R_SetViewSize (int blocks) +{ + setsizeneeded = true; + setblocks = blocks; +} + +//========================================================================== +// +// R_SetWindow +// +//========================================================================== + +void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) +{ + int trueratio; + + if (windowSize >= 11) + { + viewwidth = fullWidth; + freelookviewheight = viewheight = fullHeight; + } + else if (windowSize == 10) + { + viewwidth = fullWidth; + viewheight = stHeight; + freelookviewheight = fullHeight; + } + else + { + viewwidth = ((setblocks*fullWidth)/10) & (~15); + viewheight = ((setblocks*stHeight)/10)&~7; + freelookviewheight = ((setblocks*fullHeight)/10)&~7; + } + + // If the screen is approximately 16:9 or 16:10, consider it widescreen. + WidescreenRatio = CheckRatio (fullWidth, fullHeight, &trueratio); + + DrawFSHUD = (windowSize == 11); + + // [RH] Sky height fix for screens not 200 (or 240) pixels tall + R_InitSkyMap (); + Renderer->SetWindow(windowSize, fullWidth, fullHeight, stHeight, trueratio); +} + +//========================================================================== +// +// R_ExecuteSetViewSize +// +//========================================================================== + +void R_ExecuteSetViewSize () +{ + setsizeneeded = false; + BorderNeedRefresh = screen->GetPageCount (); + + R_SetWindow (setblocks, SCREENWIDTH, SCREENHEIGHT, ST_Y); + + // Handle resize, e.g. smaller view windows with border and/or status bar. + viewwindowx = (screen->GetWidth() - viewwidth) >> 1; + + // Same with base row offset. + viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (ST_Y - viewheight) >> 1; +} + +//========================================================================== +// +// CVAR screenblocks +// +// Selects the size of the visible window +// +//========================================================================== + +CUSTOM_CVAR (Int, screenblocks, 10, CVAR_ARCHIVE) +{ + if (self > 12) + self = 12; + else if (self < 3) + self = 3; + else + R_SetViewSize (self); +} + +//========================================================================== +// +// R_PointInSubsector +// +//========================================================================== + +subsector_t *R_PointInSubsector (fixed_t x, fixed_t y) +{ + node_t *node; + int side; + + // single subsector is a special case + if (numnodes == 0) + return subsectors; + + node = nodes + numnodes - 1; + + do + { + side = R_PointOnSide (x, y, node); + node = (node_t *)node->children[side]; + } + while (!((size_t)node & 1)); + + return (subsector_t *)((BYTE *)node - 1); +} + +//========================================================================== +// +// R_Init +// +//========================================================================== + +void R_Init () +{ + atterm (R_Shutdown); + + StartScreen->Progress(); + V_InitFonts(); + StartScreen->Progress(); + R_InitColormaps (); + StartScreen->Progress(); + + R_InitPointToAngle (); + R_InitTables (); + R_InitTranslationTables (); + R_SetViewSize (screenblocks); + Renderer->Init(); +} + +//========================================================================== +// +// R_Shutdown +// +//========================================================================== + +static void R_Shutdown () +{ + R_DeinitTranslationTables(); + R_DeinitColormaps (); + FCanvasTextureInfo::EmptyList(); +} + +//========================================================================== +// +// R_InterpolateView +// +//========================================================================== + +//CVAR (Int, tf, 0, 0) +EXTERN_CVAR (Bool, cl_noprediction) + +void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *iview) +{ +// frac = tf; + if (NoInterpolateView) + { + NoInterpolateView = false; + iview->oviewx = iview->nviewx; + iview->oviewy = iview->nviewy; + iview->oviewz = iview->nviewz; + iview->oviewpitch = iview->nviewpitch; + iview->oviewangle = iview->nviewangle; + } + viewx = iview->oviewx + FixedMul (frac, iview->nviewx - iview->oviewx); + viewy = iview->oviewy + FixedMul (frac, iview->nviewy - iview->oviewy); + viewz = iview->oviewz + FixedMul (frac, iview->nviewz - iview->oviewz); + if (player != NULL && + player - players == consoleplayer && + camera == player->mo && + !demoplayback && + iview->nviewx == camera->x && + iview->nviewy == camera->y && + !(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) && + player->playerstate == PST_LIVE && + player->mo->reactiontime == 0 && + !NoInterpolateView && + !paused && + (!netgame || !cl_noprediction) && + !LocalKeyboardTurner) + { + viewangle = iview->nviewangle + (LocalViewAngle & 0xFFFF0000); + + fixed_t delta = -(signed)(LocalViewPitch & 0xFFFF0000); + + viewpitch = iview->nviewpitch; + if (delta > 0) + { + // Avoid overflowing viewpitch (can happen when a netgame is stalled) + if (viewpitch + delta <= viewpitch) + { + viewpitch = Renderer->GetMaxViewPitch(true); + } + else + { + viewpitch = MIN(viewpitch + delta, Renderer->GetMaxViewPitch(true)); + } + } + else if (delta < 0) + { + // Avoid overflowing viewpitch (can happen when a netgame is stalled) + if (viewpitch + delta >= viewpitch) + { + viewpitch = Renderer->GetMaxViewPitch(false); + } + else + { + viewpitch = MAX(viewpitch + delta, Renderer->GetMaxViewPitch(false)); + } + } + } + else + { + viewpitch = iview->oviewpitch + FixedMul (frac, iview->nviewpitch - iview->oviewpitch); + viewangle = iview->oviewangle + FixedMul (frac, iview->nviewangle - iview->oviewangle); + } + + // Due to interpolation this is not necessarily the same as the sector the camera is in. + viewsector = R_PointInSubsector(viewx, viewy)->sector; +} + +//========================================================================== +// +// R_ResetViewInterpolation +// +//========================================================================== + +void R_ResetViewInterpolation () +{ + NoInterpolateView = true; +} + +//========================================================================== +// +// R_SetViewAngle +// +//========================================================================== + +void R_SetViewAngle () +{ + angle_t ang = viewangle >> ANGLETOFINESHIFT; + + viewsin = finesine[ang]; + viewcos = finecosine[ang]; + + viewtansin = FixedMul (FocalTangent, viewsin); + viewtancos = FixedMul (FocalTangent, viewcos); +} + +//========================================================================== +// +// FindPastViewer +// +//========================================================================== + +static InterpolationViewer *FindPastViewer (AActor *actor) +{ + for (unsigned int i = 0; i < PastViewers.Size(); ++i) + { + if (PastViewers[i].ViewActor == actor) + { + return &PastViewers[i]; + } + } + + // Not found, so make a new one + InterpolationViewer iview = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + iview.ViewActor = actor; + iview.otic = -1; + return &PastViewers[PastViewers.Push (iview)]; +} + +//========================================================================== +// +// R_FreePastViewers +// +//========================================================================== + +void R_FreePastViewers () +{ + PastViewers.Clear (); +} + +//========================================================================== +// +// R_ClearPastViewer +// +// If the actor changed in a non-interpolatable way, remove it. +// +//========================================================================== + +void R_ClearPastViewer (AActor *actor) +{ + for (unsigned int i = 0; i < PastViewers.Size(); ++i) + { + if (PastViewers[i].ViewActor == actor) + { + // Found it, so remove it. + if (i == PastViewers.Size()) + { + PastViewers.Delete (i); + } + else + { + PastViewers.Pop (PastViewers[i]); + } + } + } +} + +//========================================================================== +// +// R_SetupFrame +// +//========================================================================== + +void R_SetupFrame (AActor *actor) +{ + if (actor == NULL) + { + I_Error ("Tried to render from a NULL actor."); + } + + player_t *player = actor->player; + unsigned int newblend; + InterpolationViewer *iview; + + if (player != NULL && player->mo == actor) + { // [RH] Use camera instead of viewplayer + camera = player->camera; + if (camera == NULL) + { + camera = player->camera = player->mo; + } + if (camera == actor) + { + P_PredictPlayer (player); + } + } + else + { + camera = actor; + } + + if (camera == NULL) + { + I_Error ("You lost your body. Bad dehacked work is likely to blame."); + } + + iview = FindPastViewer (camera); + + int nowtic = I_GetTime (false); + if (iview->otic != -1 && nowtic > iview->otic) + { + iview->otic = nowtic; + iview->oviewx = iview->nviewx; + iview->oviewy = iview->nviewy; + iview->oviewz = iview->nviewz; + iview->oviewpitch = iview->nviewpitch; + iview->oviewangle = iview->nviewangle; + } + + if (player != NULL && gamestate != GS_TITLELEVEL && + ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && + (camera->RenderStyle.BlendOp != STYLEOP_None) && + !(camera->renderflags & RF_INVISIBLE) && + camera->sprite != SPR_TNT1) + { + // [RH] Use chasecam view + P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector); + r_showviewer = true; + } + else + { + iview->nviewx = camera->x; + iview->nviewy = camera->y; + iview->nviewz = camera->player ? camera->player->viewz : camera->z + camera->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight); + viewsector = camera->Sector; + r_showviewer = false; + } + iview->nviewpitch = camera->pitch; + if (camera->player != 0) + { + player = camera->player; + } + + iview->nviewangle = camera->angle + viewangleoffset; + if (iview->otic == -1 || r_NoInterpolate) + { + R_ResetViewInterpolation (); + iview->otic = nowtic; + } + + r_TicFrac = I_GetTimeFrac (&r_FrameTime); + if (cl_capfps || r_NoInterpolate) + { + r_TicFrac = FRACUNIT; + } + + R_InterpolateView (player, r_TicFrac, iview); + +#ifdef TEST_X + viewx = TEST_X; + viewy = TEST_Y; + viewz = TEST_Z; + viewangle = TEST_ANGLE; +#endif + + Renderer->CopyStackedViewParameters(); + R_SetViewAngle (); + + interpolator.DoInterpolations (r_TicFrac); + + // Keep the view within the sector's floor and ceiling + fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT; + if (viewz > theZ) + { + viewz = theZ; + } + + theZ = viewsector->floorplane.ZatPoint (viewx, viewy) + 4*FRACUNIT; + if (viewz < theZ) + { + viewz = theZ; + } + + if (!paused) + { + int intensity = DEarthquake::StaticGetQuakeIntensity (camera); + if (intensity != 0) + { + viewx += ((pr_torchflicker() % (intensity<<2)) + -(intensity<<1))<player ? camera->player->extralight : 0; + + // killough 3/20/98, 4/4/98: select colormap based on player status + // [RH] Can also select a blend + newblend = 0; + + TArray &lightlist = viewsector->e->XFloor.lightlist; + if (lightlist.Size() > 0) + { + for(unsigned int i=0;ifloorplane.ZatPoint(viewx, viewy); + + if (lightbottom < viewz) + { + // 3d floor 'fog' is rendered as a blending value + PalEntry blendv = lightlist[i].blend; + + // If no alpha is set, use 50% + if (blendv.a==0 && blendv!=0) blendv.a=128; + newblend = blendv.d; + break; + } + } + } + else + { + const sector_t *s = viewsector->GetHeightSec(); + if (s != NULL) + { + newblend = viewz < s->floorplane.ZatPoint (viewx, viewy) + ? s->bottommap + : viewz > s->ceilingplane.ZatPoint (viewx, viewy) + ? s->topmap + : s->midmap; + if (APART(newblend) == 0 && newblend >= numfakecmaps) + newblend = 0; + } + } + + // [RH] Don't override testblend unless entering a sector with a + // blend different from the previous sector's. Same goes with + // NormalLight's maps pointer. + if (R_OldBlend != newblend) + { + R_OldBlend = newblend; + if (APART(newblend)) + { + BaseBlendR = RPART(newblend); + BaseBlendG = GPART(newblend); + BaseBlendB = BPART(newblend); + BaseBlendA = APART(newblend) / 255.f; + NormalLight.Maps = realcolormaps; + } + else + { + NormalLight.Maps = realcolormaps + NUMCOLORMAPS*256*newblend; + BaseBlendR = BaseBlendG = BaseBlendB = 0; + BaseBlendA = 0.f; + } + } + + Renderer->SetupFrame(player); + + P_UnPredictPlayer (); + validcount++; + + if (RenderTarget == screen && r_clearbuffer != 0) + { + int color; + int hom = r_clearbuffer; + + if (hom == 3) + { + hom = ((I_FPSTime() / 128) & 1) + 1; + } + if (hom == 1) + { + color = GPalette.BlackIndex; + } + else if (hom == 2) + { + color = GPalette.WhiteIndex; + } + else if (hom == 4) + { + color = (I_FPSTime() / 32) & 255; + } + else + { + color = pr_hom(); + } + Renderer->ClearBuffer(color); + } +} + + +//========================================================================== +// +// FCanvasTextureInfo :: Add +// +// Assigns a camera to a canvas texture. +// +//========================================================================== + +void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, int fov) +{ + FCanvasTextureInfo *probe; + FCanvasTexture *texture; + + if (!picnum.isValid()) + { + return; + } + texture = static_cast(TexMan[picnum]); + if (!texture->bHasCanvas) + { + Printf ("%s is not a valid target for a camera\n", texture->Name); + return; + } + + // Is this texture already assigned to a camera? + for (probe = List; probe != NULL; probe = probe->Next) + { + if (probe->Texture == texture) + { + // Yes, change its assignment to this new camera + if (probe->Viewpoint != viewpoint || probe->FOV != fov) + { + texture->bFirstUpdate = true; + } + probe->Viewpoint = viewpoint; + probe->FOV = fov; + return; + } + } + // No, create a new assignment + probe = new FCanvasTextureInfo; + probe->Viewpoint = viewpoint; + probe->Texture = texture; + probe->PicNum = picnum; + probe->FOV = fov; + probe->Next = List; + texture->bFirstUpdate = true; + List = probe; +} + +//========================================================================== +// +// FCanvasTextureInfo :: UpdateAll +// +// Updates all canvas textures that were visible in the last frame. +// +//========================================================================== + +void FCanvasTextureInfo::UpdateAll () +{ + FCanvasTextureInfo *probe; + + for (probe = List; probe != NULL; probe = probe->Next) + { + if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) + { + Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); + } + } +} + +//========================================================================== +// +// FCanvasTextureInfo :: EmptyList +// +// Removes all camera->texture assignments. +// +//========================================================================== + +void FCanvasTextureInfo::EmptyList () +{ + FCanvasTextureInfo *probe, *next; + + for (probe = List; probe != NULL; probe = next) + { + next = probe->Next; + delete probe; + } + List = NULL; +} + +//========================================================================== +// +// FCanvasTextureInfo :: Serialize +// +// Reads or writes the current set of mappings in an archive. +// +//========================================================================== + +void FCanvasTextureInfo::Serialize (FArchive &arc) +{ + if (arc.IsStoring ()) + { + FCanvasTextureInfo *probe; + + for (probe = List; probe != NULL; probe = probe->Next) + { + if (probe->Texture != NULL && probe->Viewpoint != NULL) + { + arc << probe->Viewpoint << probe->FOV << probe->PicNum; + } + } + AActor *nullactor = NULL; + arc << nullactor; + } + else + { + AActor *viewpoint; + int fov; + FTextureID picnum; + + EmptyList (); + while (arc << viewpoint, viewpoint != NULL) + { + arc << fov << picnum; + Add (viewpoint, picnum, fov); + } + } +} + +//========================================================================== +// +// FCanvasTextureInfo :: Mark +// +// Marks all viewpoints in the list for the collector. +// +//========================================================================== + +void FCanvasTextureInfo::Mark() +{ + for (FCanvasTextureInfo *probe = List; probe != NULL; probe = probe->Next) + { + GC::Mark(probe->Viewpoint); + } +} + diff --git a/src/r_utility.h b/src/r_utility.h index 9aec22e99d..79b133ec5b 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -9,8 +9,14 @@ // There a 0-31, i.e. 32 LUT in the COLORMAP lump. #define NUMCOLORMAPS 32 +extern DCanvas *RenderTarget; + extern fixed_t viewx; extern fixed_t viewy; +extern fixed_t viewz; +extern int viewpitch; + +extern int setblocks; extern fixed_t viewtancos; extern fixed_t viewtansin; @@ -26,6 +32,9 @@ extern int WidescreenRatio; extern fixed_t r_TicFrac; extern DWORD r_FrameTime; +extern int extralight; +extern unsigned int R_OldBlend; + //========================================================================== // @@ -49,6 +58,18 @@ subsector_t *R_PointInSubsector (fixed_t x, fixed_t y); fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy); void R_ResetViewInterpolation (); void R_SetViewSize (int blocks); +void R_SetFOV (float fov); +float R_GetFOV (); +void R_SetupFrame (AActor * camera); + +// Called by startup code. +void R_Init (void); +void R_ExecuteSetViewSize (void); + +// Called by M_Responder. +void R_SetViewSize (int blocks); +void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight); + extern void R_FreePastViewers (); extern void R_ClearPastViewer (AActor *actor); diff --git a/src/sdl/hardware.cpp b/src/sdl/hardware.cpp index 88c700767b..d2853d4fa0 100644 --- a/src/sdl/hardware.cpp +++ b/src/sdl/hardware.cpp @@ -80,6 +80,21 @@ void I_InitGraphics () Video->SetWindowedScale (vid_winscale); } +static void I_DeleteRenderer() +{ + if (Renderer != NULL) delete Renderer; +} + +void I_CreateRenderer() +{ + if (Renderer == NULL) + { + Renderer = new FSoftwareRenderer; + atterm(I_DeleteRenderer); + } +} + + /** Remaining code is common to Win32 and Linux **/ // VIDEO WRAPPERS --------------------------------------------------------- diff --git a/src/sdl/hardware.h b/src/sdl/hardware.h index 5b14b7cbb7..f82af7bb42 100644 --- a/src/sdl/hardware.h +++ b/src/sdl/hardware.h @@ -57,6 +57,7 @@ class IVideo void I_InitGraphics (); void I_ShutdownGraphics (); +void I_CreateRenderer(); extern IVideo *Video; diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index a61efa5ab7..26723c583e 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -11,6 +11,7 @@ #include "stats.h" #include "v_palette.h" #include "sdlvideo.h" +#include "r_swrenderer.h" #include @@ -147,6 +148,7 @@ static MiniModeInfo WinModes[] = { 1600, 900 }, // 16:9 { 1600, 1000 }, // 16:10 { 1600, 1200 }, + { 1920, 1080 }, }; static cycle_t BlitCycles; diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index c62a8ef026..a6e1918dfc 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -35,13 +35,10 @@ #include "doomtype.h" #include "files.h" -#include "r_local.h" #include "v_palette.h" #include "v_video.h" #include "textures/textures.h" -extern float LastFOV; - FCanvasTexture::FCanvasTexture (const char *name, int width, int height) { strncpy (Name, name, 8); @@ -62,6 +59,7 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) bDidUpdate = false; bHasCanvas = true; bFirstUpdate = true; + bPixelsAllocated = false; } FCanvasTexture::~FCanvasTexture () @@ -112,10 +110,12 @@ void FCanvasTexture::MakeTexture () if (Width != Height || Width != Canvas->GetPitch()) { Pixels = new BYTE[Width*Height]; + bPixelsAllocated = true; } else { Pixels = Canvas->GetBuffer(); + bPixelsAllocated = false; } // Draw a special "unrendered" initial texture into the buffer. memset (Pixels, 0, Width*Height/2); @@ -124,13 +124,15 @@ void FCanvasTexture::MakeTexture () void FCanvasTexture::Unload () { + if (bPixelsAllocated) + { + if (Pixels != NULL) delete [] Pixels; + bPixelsAllocated = false; + Pixels = NULL; + } + if (Canvas != NULL) { - if (Pixels != NULL && Pixels != Canvas->GetBuffer()) - { - delete[] Pixels; - } - Pixels = NULL; GC::DelSoftRoot(Canvas); Canvas->Destroy(); Canvas = NULL; @@ -147,26 +149,3 @@ bool FCanvasTexture::CheckModified () return false; } -void FCanvasTexture::RenderView (AActor *viewpoint, int fov) -{ - if (Canvas == NULL) - { - MakeTexture (); - } - float savedfov = LastFOV; - R_SetFOV ((float)fov); - R_RenderViewToCanvas (viewpoint, Canvas, 0, 0, Width, Height, bFirstUpdate); - R_SetFOV (savedfov); - if (Pixels == Canvas->GetBuffer()) - { - FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap); - } - else - { - FlipNonSquareBlockRemap (Pixels, Canvas->GetBuffer(), Width, Height, Canvas->GetPitch(), GPalette.Remap); - } - bNeedsUpdate = false; - bDidUpdate = true; - bFirstUpdate = false; -} - diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 3f6ee054e9..622d92f755 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -50,6 +50,7 @@ #include "m_fixed.h" #include "farchive.h" #include "v_video.h" +#include "r_renderer.h" #include "textures/textures.h" FTextureManager TexMan; @@ -1169,7 +1170,7 @@ void FTextureManager::PrecacheLevel (void) screen->GetHitlist(hitlist); for (int i = cnt - 1; i >= 0; i--) { - screen->PrecacheTexture(ByIndex(i), hitlist[i]); + Renderer->PrecacheTexture(ByIndex(i), hitlist[i]); } delete[] hitlist; diff --git a/src/textures/textures.h b/src/textures/textures.h index 1c40ea6424..a35c911ade 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -295,6 +295,7 @@ protected: Rotations = other->Rotations; } +public: static void FlipSquareBlock (BYTE *block, int x, int y); static void FlipSquareBlockRemap (BYTE *block, int x, int y, const BYTE *remap); static void FlipNonSquareBlock (BYTE *blockto, const BYTE *blockfrom, int x, int y, int srcpitch); @@ -522,18 +523,21 @@ public: const BYTE *GetPixels (); void Unload (); bool CheckModified (); - void RenderView (AActor *viewpoint, int fov); void NeedUpdate() { bNeedsUpdate=true; } + void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; } + DSimpleCanvas *GetCanvas() { return Canvas; } + void MakeTexture (); protected: DSimpleCanvas *Canvas; BYTE *Pixels; Span DummySpans[2]; - BYTE bNeedsUpdate:1; - BYTE bDidUpdate:1; - BYTE bFirstUpdate:1; + bool bNeedsUpdate; + bool bDidUpdate; + bool bPixelsAllocated; +public: + bool bFirstUpdate; - void MakeTexture (); friend struct FCanvasTextureInfo; }; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 6c5da30a1e..e86f112bdd 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -32,6 +32,8 @@ ** */ +// #define NO_SWRENDER // set this if you want to exclude the software renderer. Without software renderer the base implementations of DrawTextureV and FillSimplePoly need to be disabled because they depend on it. + #include #include @@ -39,9 +41,11 @@ #include "v_video.h" #include "m_swap.h" #include "r_defs.h" +#ifndef NO_SWRENDER #include "r_draw.h" #include "r_main.h" #include "r_things.h" +#endif #include "r_data/r_translate.h" #include "doomstat.h" #include "v_palette.h" @@ -68,7 +72,6 @@ int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; // FillSimplePoly uses this extern "C" short spanend[MAXHEIGHT]; -extern int setblocks; CVAR (Bool, hud_scale, false, CVAR_ARCHIVE); @@ -110,6 +113,7 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, double x, double y, int tag void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) { +#ifndef NO_SWRENDER FTexture::Span unmaskedSpan[2]; const FTexture::Span **spanptr, *spans; static short bottomclipper[MAXWIDTH], topclipper[MAXWIDTH]; @@ -318,6 +322,7 @@ void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, double x, double y, uint32 { NetUpdate(); } +#endif } bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool hw) const @@ -1119,6 +1124,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, angle_t rotation, FDynamicColormap *colormap, int lightlevel) { +#ifndef NO_SWRENDER // Use an equation similar to player sprites to determine shade fixed_t shade = LIGHT2SHADE(lightlevel) - 12*FRACUNIT; float topy, boty, leftx, rightx; @@ -1263,6 +1269,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, pt1 = pt2; pt2--; if (pt2 < 0) pt2 = npoints; } while (pt1 != botpt); +#endif } diff --git a/src/v_video.cpp b/src/v_video.cpp index 35b5c6b509..314ae22f83 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -28,7 +28,6 @@ #include "i_system.h" #include "x86.h" #include "i_video.h" -#include "r_local.h" #include "r_state.h" #include "doomdef.h" @@ -61,10 +60,14 @@ #include "colormatcher.h" #include "v_palette.h" #include "r_sky.h" +#include "r_utility.h" +#include "r_renderer.h" #include "menu/menu.h" #include "r_data/voxels.h" +FRenderer *Renderer; + IMPLEMENT_ABSTRACT_CLASS (DCanvas) IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer) @@ -373,17 +376,6 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) } } -//========================================================================== -// -// DCanvas :: UsesColormap -// -//========================================================================== - -bool DCanvas::UsesColormap() const -{ - return true; -} - //========================================================================== // // DCanvas :: GetScreenshotBuffer @@ -1274,130 +1266,6 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist) } } -//=========================================================================== -// -// Texture precaching -// -//=========================================================================== - -void DFrameBuffer::PrecacheTexture(FTexture *tex, int cache) -{ - if (tex != NULL) - { - if (cache & 1) - { - const FTexture::Span *spanp; - tex->GetColumn(0, &spanp); - } - else if (cache != 0) - { - tex->GetPixels (); - } - else - { - tex->Unload (); - } - } -} - -//=========================================================================== -// -// Render the view -// -//=========================================================================== - -void DFrameBuffer::RenderView(player_t *player) -{ - R_RenderActorView (player->mo); - // [RH] Let cameras draw onto textures that were visible this frame. - FCanvasTextureInfo::UpdateAll (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void DFrameBuffer::RemapVoxels() -{ - for (unsigned i=0; iRemap(); - } -} - -//=========================================================================== -// -// Render the view to a savegame picture -// -//=========================================================================== - -void DFrameBuffer::WriteSavePic (player_t *player, FILE *file, int width, int height) -{ - DCanvas *pic = new DSimpleCanvas (width, height); - PalEntry palette[256]; - - // Take a snapshot of the player's view - pic->ObjectFlags |= OF_Fixed; - pic->Lock (); - R_RenderViewToCanvas (player->mo, pic, 0, 0, width, height); - GetFlashedPalette (palette); - M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch()); - pic->Unlock (); - pic->Destroy(); - pic->ObjectFlags |= OF_YesReallyDelete; - delete pic; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void DFrameBuffer::DrawRemainingPlayerSprites() -{ - R_DrawRemainingPlayerSprites(); -} - -//=========================================================================== -// -// notify the renderer that an actor has changed state -// -//=========================================================================== - -void DFrameBuffer::StateChanged(AActor *actor) -{ -} - -//=========================================================================== -// -// notify the renderer that serialization of the curent level is about to start/end -// -//=========================================================================== - -void DFrameBuffer::StartSerialize(FArchive &arc) -{ -} - -void DFrameBuffer::EndSerialize(FArchive &arc) -{ -} - -//=========================================================================== -// -// Get max. view angle (renderer specific information so it goes here now) -// -//=========================================================================== -#define MAX_DN_ANGLE 56 // Max looking down angle -#define MAX_UP_ANGLE 32 // Max looking up angle - -int DFrameBuffer::GetMaxViewPitch(bool down) -{ - return down? MAX_DN_ANGLE*ANGLE_1 : -MAX_UP_ANGLE*ANGLE_1; -} - //========================================================================== // // DFrameBuffer :: GameRestart @@ -1532,13 +1400,9 @@ bool V_DoModeSetup (int width, int height, int bits) DisplayHeight = height; DisplayBits = bits; - R_MultiresInit (); - - RenderTarget = screen; - screen->Lock (true); - R_SetupBuffer (); - screen->Unlock (); - + R_OldBlend = ~0; + Renderer->OnModeSet(); + M_RefreshModesList (); return true; @@ -1703,7 +1567,7 @@ void V_Init2() Printf ("Resolution: %d x %d\n", SCREENWIDTH, SCREENHEIGHT); screen->SetGamma (gamma); - screen->RemapVoxels(); + Renderer->RemapVoxels(); FBaseCVar::ResetColors (); C_NewModeAdjust(); M_InitVideoModesMenu(); diff --git a/src/v_video.h b/src/v_video.h index b414d6658d..da184cba32 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -193,8 +193,6 @@ public: // Calculate gamma table void CalcGamma (float gamma, BYTE gammalookup[256]); - // Can be overridden so that the colormaps for sector color/fade won't be built. - virtual bool UsesColormap() const; // Retrieves a buffer containing image data for a screenshot. // Hint: Pitch can be negative for upside-down images, in which case buffer @@ -364,27 +362,6 @@ public: // Set the rect defining the area affected by blending. virtual void SetBlendingRect (int x1, int y1, int x2, int y2); - // Remap voxel palette - virtual void RemapVoxels(); - - // render 3D view - virtual void RenderView(player_t *player); - - // renders view to a savegame picture - virtual void WriteSavePic (player_t *player, FILE *file, int width, int height); - - // draws player sprites with hardware acceleration (only useful for software rendering) - virtual void DrawRemainingPlayerSprites(); - - // notifies the renderer that an actor has changed state. - virtual void StateChanged(AActor *actor); - - // notify the renderer that serialization of the curent level is about to start/end - virtual void StartSerialize(FArchive &arc); - virtual void EndSerialize(FArchive &arc); - - virtual int GetMaxViewPitch(bool down); - bool Accel2D; // If true, 2D drawing can be accelerated. // Begin 2D drawing operations. This is like Update, but it doesn't end @@ -408,7 +385,6 @@ public: // Precaches or unloads a texture virtual void GetHitlist(BYTE *hitlist); - virtual void PrecacheTexture(FTexture *tex, int cache); // Report a game restart virtual void GameRestart(); diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index 7afce95875..6408e9279b 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -46,6 +46,8 @@ #include "v_text.h" #include "doomstat.h" #include "m_argv.h" +#include "version.h" +#include "r_swrenderer.h" EXTERN_CVAR (Bool, ticker) EXTERN_CVAR (Bool, fullscreen) @@ -104,6 +106,20 @@ void I_InitGraphics () Video->SetWindowedScale (vid_winscale); } +static void I_DeleteRenderer() +{ + if (Renderer != NULL) delete Renderer; +} + +void I_CreateRenderer() +{ + if (Renderer == NULL) + { + Renderer = new FSoftwareRenderer; + atterm(I_DeleteRenderer); + } +} + /** Remaining code is common to Win32 and Linux **/ // VIDEO WRAPPERS --------------------------------------------------------- diff --git a/src/win32/hardware.h b/src/win32/hardware.h index 223ba621c0..38cb15ea86 100644 --- a/src/win32/hardware.h +++ b/src/win32/hardware.h @@ -57,6 +57,7 @@ class IVideo void I_InitGraphics (); void I_ShutdownGraphics (); +void I_CreateRenderer(); void I_SaveWindowedPos (); void I_RestoreWindowedPos (); diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index eeab8226a4..2a65e8c9c2 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -263,6 +263,7 @@ static void FinalGC() { Args = NULL; GC::FullGC(); + GC::DelSoftRootHead(); // the soft root head will not be collected by a GC so we have to do it explicitly } //========================================================================== @@ -1300,7 +1301,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n _CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF); // Use this to break at a specific allocation number. - //_crtBreakAlloc = 30055; + //_crtBreakAlloc = 77624; #endif DoMain (hInstance); diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 5314fc667d..60dc9cbd3a 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -54,6 +54,7 @@ EXTERN_CVAR (Bool, vid_vsync) class D3DTex; class D3DPal; +struct FSoftwareRenderer; class Win32Video : public IVideo { diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 06fdaff1f2..d82744ef79 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -68,6 +68,7 @@ #include "m_argv.h" #include "r_defs.h" #include "v_text.h" +#include "r_swrenderer.h" #include "win32iface.h" @@ -709,7 +710,6 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr retry = 0; fb->SetFlash (flashColor, flashAmount); - return fb; } diff --git a/zdoom.vcproj b/zdoom.vcproj index b31f108f3c..dff0e6cb22 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2344,7 +2344,7 @@ > - - @@ -2392,21 +2388,13 @@ > - - - - + + + + + + + + + + + + + + + +