diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d1d1724a..dfba4e959 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 026fec2e8..a6b03446f 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 070fc9167..efc33b5f4 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 a2354aa80..2ae5493c6 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 1bc05269e..6fae559c3 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 1acab7a14..9ff2d4225 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 4a6287be8..0b89dafa8 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 eb22dc6c0..36339ffee 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 bbf4be3a5..df8d88725 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 7ab9bb176..b78d87256 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 ba55410a8..81f9080e0 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 3a9fce10a..5a0bd4b82 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 223b1e4b0..d63ec2534 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 4cee72f01..0075d6ca0 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 8c0957fe0..8afbefb22 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 000000000..e815abf12 --- /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 8ff2d6c62..fb65cf9ad 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 f285c4268..2c8c62dc7 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 000000000..c518abf90 --- /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 000000000..4b37e4eed --- /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 000000000..dc3cb1565 --- /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 9aec22e99..79b133ec5 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 88c700767..d2853d4fa 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 5b14b7cbb..f82af7bb4 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 a61efa5ab..26723c583 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 c62a8ef02..a6e1918df 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 3f6ee054e..622d92f75 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 1c40ea642..a35c911ad 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 6c5da30a1..e86f112bd 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 35b5c6b50..314ae22f8 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 b414d6658..da184cba3 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 7afce9587..6408e9279 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 223ba621c..38cb15ea8 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 eeab8226a..2a65e8c9c 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 5314fc667..60dc9cbd3 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 06fdaff1f..d82744ef7 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 b31f108f3..dff0e6cb2 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2344,7 +2344,7 @@ > - - @@ -2392,21 +2388,13 @@ > - - - - + + + + + + + + + + + + + + + +