diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0100d5c31..3a3efad30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -872,7 +872,6 @@ set( POLYRENDER_SOURCES polyrenderer/drawers/poly_draw_args.cpp polyrenderer/drawers/screen_triangle.cpp polyrenderer/math/tri_matrix.cpp - polyrenderer/math/poly_intersection.cpp ) # These files will be flagged as "headers" so that they appear in project files diff --git a/src/d_main.cpp b/src/d_main.cpp index 25dc4537c..7216881d4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2569,7 +2569,13 @@ void D_DoomMain (void) P_SetupWeapons_ntohton(); //SBarInfo support. - SBarInfo::Load(); + // This needs special checking because there are two distinct methods of defining status bars. + // SBARINFO should only be picked if it is the most recently defined one, so that both + // methods can override each other if loaded in sequence. + if (gameinfo.statusbarfile > gameinfo.statusbarclassfile) + { + SBarInfo::Load(); + } HUD_InitHud(); if (!batchrun) diff --git a/src/g_level.cpp b/src/g_level.cpp index 0347e79d3..1a3d1d073 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -435,59 +435,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) S_ResumeSound (false); } - if (StatusBar != NULL) - { - StatusBar->Destroy(); - StatusBar = NULL; - } - auto cls = PClass::FindClass("DoomStatusBar"); - - if (bTitleLevel) - { - StatusBar = new DBaseStatusBar (); - StatusBar->SetSize(0); - } - else if (cls && gameinfo.gametype == GAME_Doom) - { - StatusBar = (DBaseStatusBar*)cls->CreateNew(); - } - else if (SBarInfoScript[SCRIPT_CUSTOM] != NULL) - { - int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType(); - - //Did the user specify a "base" - if(cstype == GAME_Strife) - { - StatusBar = CreateStrifeStatusBar(); - } - else if(cstype == GAME_Any) //Use the default, empty or custom. - { - StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM); - } - else - { - StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT); - } - } - if (StatusBar == NULL) - { - if (gameinfo.gametype & (GAME_DoomChex|GAME_Heretic|GAME_Hexen)) - { - StatusBar = CreateCustomStatusBar (SCRIPT_DEFAULT); - } - else if (gameinfo.gametype == GAME_Strife) - { - StatusBar = CreateStrifeStatusBar (); - } - else - { - StatusBar = new DBaseStatusBar(); - StatusBar->SetSize(0); - } - } - GC::WriteBarrier(StatusBar); - StatusBar->AttachToPlayer (&players[consoleplayer]); - StatusBar->NewGame (); + ST_CreateStatusBar(bTitleLevel); setsizeneeded = true; if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 0079d5b71..1f8fb62e4 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -390,6 +390,7 @@ public: void DrawTopStuff (EHudState state); void FlashItem (const PClass *itemtype); void AttachToPlayer(player_t *player); + DVector2 GetHUDScale() const; virtual void FlashCrosshair (); virtual void BlendView (float blend[4]); void NewGame (); @@ -406,12 +407,9 @@ public: void DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing = 0, bool monospaced = false, int shadowX = 0, int shadowY = 0); - void GetCoords(int &x, int &y) - { - x = ST_X; - y = ST_Y; - } - + void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); + void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); + void ForceHUDScale(bool on) { ForcedScale = on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD. //protected: void DrawPowerups (); @@ -423,10 +421,14 @@ public: AInventory *ValidateInvFirst (int numVisible) const; void DrawCrosshair (); + // Sizing info for ths status bar. int ST_X, ST_Y; int RelTop; int HorizontalResolution, VerticalResolution; - bool Scaled; + bool Scaled; // This needs to go away. + DVector2 defaultScale; // factor for fully scaled fullscreen display. + bool ForcedScale = false; + bool Centering; bool FixedOrigin; bool CompleteBorder; @@ -442,7 +444,6 @@ public: DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet) bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior. - DVector2 cleanScale; // factor for scaled fullscreen display. FMugShot mugshot; private: @@ -458,7 +459,6 @@ extern DBaseStatusBar *StatusBar; // Status bar factories ----------------------------------------------------- -DBaseStatusBar *CreateStrifeStatusBar(); DBaseStatusBar *CreateCustomStatusBar(int script=0); // Crosshair stuff ---------------------------------------------------------- @@ -466,6 +466,7 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0); void ST_FormatMapName(FString &mapname, const char *mapnamecolor = ""); void ST_LoadCrosshair(bool alwaysload=false); void ST_Clear(); +void ST_CreateStatusBar(bool bTitleLevel); extern FTexture *CrosshairImage; FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale); diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index e747717cc..438c3e3d2 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -47,6 +47,7 @@ #include "a_keys.h" #include "templates.h" #include "i_system.h" +#include "sbar.h" #include "sbarinfo.h" #include "gi.h" #include "r_data/r_translate.h" @@ -72,11 +73,11 @@ enum EXTERN_CVAR(Int, fraglimit) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, vid_fps) -EXTERN_CVAR(Bool, hud_scale) class DSBarInfo; static double nulclip[] = { 0,0,0,0 }; + //////////////////////////////////////////////////////////////////////////////// /** @@ -629,10 +630,10 @@ void SBarInfo::ParseSBarInfo(int lump) break; case SBARINFO_RESOLUTION: sc.MustGetToken(TK_IntConst); - resW = sc.Number; + _resW = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); - resH = sc.Number; + _resH = sc.Number; sc.MustGetToken(';'); break; case SBARINFO_STATUSBAR: @@ -818,10 +819,8 @@ void SBarInfo::Init() height = 0; spacingCharacter = '\0'; spacingAlignment = ALIGN_CENTER; - resW = 320; - resH = 200; - cleanX = -1; - cleanY = -1; + _resW = 320; + _resH = 200; for(unsigned int i = 0;i < NUMHUDS;i++) huds[i] = new SBarInfoMainBlock(this); @@ -957,14 +956,14 @@ void Popup::close() //////////////////////////////////////////////////////////////////////////////// -inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, const double &xScale, const double &yScale) +inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, double ScaleX, double ScaleY) { if(relX) - outX = x + (SCREENWIDTH/(hud_scale ? xScale*2 : 2)); + outX = x + (SCREENWIDTH/(ScaleX*2)); else outX = x; if(relY) - outY = y + (SCREENHEIGHT/(hud_scale ? yScale*2 : 2)); + outY = y + (SCREENHEIGHT/(ScaleY*2)); else outY = y; } @@ -1016,25 +1015,8 @@ public: CPlayer = player; } - void _ScreenSizeChanged() - { - if (uiscale > 0) - { - script->cleanX = uiscale; - script->cleanY = uiscale; - } - else - { - V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY); - } - } - void _Draw (EHudState state) { - if (script->cleanX <= 0) - { // Calculate cleanX and cleanY - wrapper->CallScreenSizeChanged(); - } int hud = STBAR_NORMAL; if(state == HUD_StatusBar) { @@ -1055,11 +1037,10 @@ public: { hud = STBAR_NONE; } - bool oldhud_scale = hud_scale; if(script->huds[hud]->ForceScaled()) //scale the statusbar { if(script->huds[hud]->FullScreenOffsets()) - hud_scale = true; + wrapper->ForceHUDScale(true); else if(!Scaled) { scalingWasForced = true; @@ -1145,8 +1126,8 @@ public: else lastPopup = NULL; - // Reset hud_scale - hud_scale = oldhud_scale; + // Reset hud scale + wrapper->ForceHUDScale(false); } void _NewGame () @@ -1161,14 +1142,8 @@ public: return script->huds[STBAR_POPUPLOG]->NumCommands() == 0; } - void _SetMugShotState (const char *state_name, bool wait_till_done, bool reset) - { - script->MugShot.SetState(state_name, wait_till_done, reset); - } - void _Tick () { - script->MugShot.Tick(CPlayer); if(currentPopup != DBaseStatusBar::POP_None) { script->popups[currentPopup-1].tick(); @@ -1188,11 +1163,6 @@ public: lastInventoryBar->Tick(NULL, this, false); } - void _ReceivedWeapon(AWeapon *weapon) - { - script->MugShot.Grin(); - } - // void DSBarInfo::FlashItem(const PClass *itemtype) - Is defined with CommandDrawSelectedInventory void _FlashItem(const PClass *itemtype); @@ -1240,10 +1210,10 @@ public: if(!fullScreenOffsets) { double tmp = 0; - int stX, stY; - wrapper->GetCoords(stX, stY); - dx += stX; - dy += stY - (Scaled ? script->resH : 200) + script->height; + int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution; + + dx += wrapper->ST_X; + dy += wrapper->ST_Y - (Scaled ? barH : 200) + script->height; w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth; h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight; double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(); @@ -1255,19 +1225,19 @@ public: { if(clip[0] != 0 || clip[1] != 0) { - screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true); + screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, barW, barH, true); if (clip[0] == 0) dcx = 0; if (clip[1] == 0) dcy = 0; } if(clip[2] != 0 || clip[3] != 0 || clearDontDraw) - screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true); - screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true); + screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, barW, barH, true); + screen->VirtualToRealCoords(dx, dy, w, h, barW, barH, true); } else { - dy += 200 - script->resH; - dcy += 200 - script->resH; - dcb += 200 - script->resH; + dy += 200 - barH; + dcy += 200 - barH; + dcb += 200 - barH; } if(clearDontDraw) @@ -1312,10 +1282,9 @@ public: { double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX; - double xScale = !hud_scale ? 1 : script->cleanX; - double yScale = !hud_scale ? 1 : script->cleanY; + DVector2 Scale = wrapper->GetHUDScale(); - adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale); + adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, Scale.X, Scale.Y); // Translation: No high res. bool xright = *x < 0 && !x.RelCenter(); @@ -1325,13 +1294,12 @@ public: h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight); if(vid_fps && rx < 0 && ry >= 0) ry += 10; - if(hud_scale) - { - rx *= xScale; - ry *= yScale; - w *= xScale; - h *= yScale; - } + + rx *= Scale.X; + ry *= Scale.Y; + w *= Scale.X; + h *= Scale.Y; + if(xright) rx = SCREENWIDTH + rx; if(ybot) @@ -1340,10 +1308,10 @@ public: // Check for clipping if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0) { - rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*xScale); - rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*yScale); - rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*xScale); - rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*yScale); + rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X); + rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y); + rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X); + rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y); } if(clearDontDraw) @@ -1392,8 +1360,7 @@ public: double ax = *x; double ay = *y; - double xScale = 1.0; - double yScale = 1.0; + DVector2 Scale; const uint8_t* str = (const uint8_t*) cstring; const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); @@ -1401,12 +1368,12 @@ public: if(fullScreenOffsets) { - if(hud_scale) - { - xScale = script->cleanX; - yScale = script->cleanY; - } - adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale); + Scale = wrapper->GetHUDScale(); + adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, Scale.X, Scale.Y); + } + else + { + Scale = { 1.,1. }; } while(*str != '\0') { @@ -1467,15 +1434,15 @@ public: if(!fullScreenOffsets) { - int stX, stY; - wrapper->GetCoords(stX, stY); - rx += stX; - ry += stY - (Scaled ? script->resH : 200) + script->height; + + int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution; + rx += wrapper->ST_X; + ry += wrapper->ST_Y - (Scaled ? barH : 200) + script->height; if(Scaled) - screen->VirtualToRealCoords(rx, ry, rw, rh, script->resW, script->resH, true); + screen->VirtualToRealCoords(rx, ry, rw, rh, barW, barH, true); else { - ry += (200 - script->resH); + ry += (200 - barH); } } else @@ -1486,13 +1453,11 @@ public: bool xright = rx < 0; bool ybot = ry < 0; - if(hud_scale) - { - rx *= xScale; - ry *= yScale; - rw *= xScale; - rh *= yScale; - } + rx *= Scale.X; + ry *= Scale.Y; + rw *= Scale.X; + rh *= Scale.Y; + if(xright) rx = SCREENWIDTH + rx; if(ybot) @@ -1501,8 +1466,8 @@ public: if(drawshadow) { double salpha = (Alpha *HR_SHADOW); - double srx = rx + (shadowX*xScale); - double sry = ry + (shadowY*yScale); + double srx = rx + (shadowX*Scale.X); + double sry = ry + (shadowY*Scale.Y); screen->DrawChar(font, CR_UNTRANSLATED, srx, sry, character, DTA_DestWidthF, rw, DTA_DestHeightF, rh, @@ -1558,11 +1523,8 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu { if(FullScreenOffsets()) { - if(!hud_scale) - { - rescale = true; - hud_scale = true; - } + rescale = true; + statusBar->wrapper->ForceHUDScale(true); } else if(!statusBar->Scaled) { @@ -1576,7 +1538,7 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu if(rescale) { if(FullScreenOffsets()) - hud_scale = false; + statusBar->wrapper->ForceHUDScale(false); else statusBar->wrapper->SetScaled(false); } @@ -1615,13 +1577,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, AttachToPlayer) return 0; } -DEFINE_ACTION_FUNCTION(DSBarInfo, ScreenSizeChanged) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - self->_ScreenSizeChanged(); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, Draw) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1644,16 +1599,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, MustDrawLog) ACTION_RETURN_BOOL(self->_MustDrawLog((EHudState)State)); } -DEFINE_ACTION_FUNCTION(DSBarInfo, SetMugshotState) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - PARAM_STRING(name); - PARAM_BOOL(wait); - PARAM_BOOL(reset); - self->_SetMugShotState(name, wait, reset); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, Tick) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1661,14 +1606,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, Tick) return 0; } -DEFINE_ACTION_FUNCTION(DSBarInfo, ReceivedWeapon) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - PARAM_OBJECT(w, AWeapon); - self->_ReceivedWeapon(w); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, FlashItem) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1695,7 +1632,7 @@ DBaseStatusBar *CreateCustomStatusBar(int scriptno) auto sbar = (DBaseStatusBar*)PClass::FindClass("SBarInfoWrapper")->CreateNew(); auto core = new DSBarInfo(sbar, script); sbar->PointerVar("core") = core; - sbar->SetSize(script->height, script->resW, script->resH); + sbar->SetSize(script->height, script->_resW, script->_resH); core->_SetScaled(sbar->Scaled); sbar->CompleteBorder = script->completeBorder; return sbar; diff --git a/src/g_statusbar/sbarinfo.h b/src/g_statusbar/sbarinfo.h index 06e426773..136f814f7 100644 --- a/src/g_statusbar/sbarinfo.h +++ b/src/g_statusbar/sbarinfo.h @@ -106,11 +106,9 @@ struct SBarInfo int armorInterpolationSpeed; int height; int gameType; - FMugShot MugShot; - int resW; - int resH; - int cleanX; - int cleanY; + + int _resW; + int _resH; int GetGameType() { return gameType; } void ParseSBarInfo(int lump); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index ccddc5939..f9b772581 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -1616,7 +1616,7 @@ class CommandDrawMugShot : public SBarInfoCommand void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) { - FTexture *face = script->MugShot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags); + FTexture *face = statusBar->wrapper->mugshot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags); if (face != NULL) statusBar->DrawGraphic(face, x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); } @@ -1661,7 +1661,6 @@ class CommandDrawMugShot : public SBarInfoCommand } void Reset() { - script->MugShot.Reset(); } protected: diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 51106914e..d8c46a1dd 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit +** Copyright 2017 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -59,6 +60,7 @@ #include "virtual.h" #include "p_acs.h" #include "r_data/r_translate.h" +#include "sbarinfo.h" #include "../version.h" @@ -81,8 +83,8 @@ EXTERN_CVAR (Bool, am_showtime) EXTERN_CVAR (Bool, am_showtotaltime) EXTERN_CVAR (Bool, noisedebug) EXTERN_CVAR (Int, con_scaletext) -EXTERN_CVAR(Bool, hud_scale) EXTERN_CVAR(Bool, vid_fps) +CVAR(Int, hud_scale, -1, CVAR_ARCHIVE); int active_con_scaletext(); @@ -90,7 +92,7 @@ DBaseStatusBar *StatusBar; extern int setblocks; -int gST_X, gST_Y; +int gST_Y; FTexture *CrosshairImage; static int CrosshairNum; @@ -222,6 +224,85 @@ void ST_Clear() CrosshairNum = 0; } +//--------------------------------------------------------------------------- +// +// create a new status bar +// +//--------------------------------------------------------------------------- + +void ST_CreateStatusBar(bool bTitleLevel) +{ + if (StatusBar != NULL) + { + StatusBar->Destroy(); + StatusBar = NULL; + } + + if (bTitleLevel) + { + StatusBar = new DBaseStatusBar(); + StatusBar->SetSize(0); + } + else if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile) + { + auto cls = PClass::FindClass(gameinfo.statusbarclass); + if (cls != nullptr) + { + StatusBar = (DBaseStatusBar *)cls->CreateNew(); + IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init) + { + VMValue params[] = { StatusBar }; + GlobalVMStack.Call(func, params, 1, nullptr, 0); + } + } + } + if (StatusBar == nullptr && SBarInfoScript[SCRIPT_CUSTOM] != nullptr) + { + int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType(); + + //Did the user specify a "base" + if (cstype == GAME_Any) //Use the default, empty or custom. + { + StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM); + } + else + { + StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT); + } + } + if (StatusBar == nullptr) + { + FName defname; + + if (gameinfo.gametype & GAME_DoomChex) defname = "DoomStatusBar"; + else if (gameinfo.gametype == GAME_Heretic) defname = "HereticStatusBar"; + else if (gameinfo.gametype == GAME_Hexen) defname = "HexenStatusBar"; + else if (gameinfo.gametype == GAME_Strife) defname = "StrifeStatusBar"; + if (defname != NAME_None) + { + auto cls = PClass::FindClass(defname); + if (cls != nullptr) + { + + StatusBar = (DBaseStatusBar *)cls->CreateNew(); + IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init) + { + VMValue params[] = { StatusBar }; + GlobalVMStack.Call(func, params, 1, nullptr, 0); + } + } + } + } + if (StatusBar == nullptr) + { + StatusBar = new DBaseStatusBar(); + StatusBar->SetSize(0); + } + + GC::WriteBarrier(StatusBar); + StatusBar->AttachToPlayer(&players[consoleplayer]); + StatusBar->NewGame(); +} //--------------------------------------------------------------------------- // // Constructor @@ -238,8 +319,7 @@ DBaseStatusBar::DBaseStatusBar () Displacement = 0; CPlayer = NULL; ShowLog = false; - cleanScale = { (double)CleanXfac, (double)CleanYfac }; - + defaultScale = { (double)CleanXfac, (double)CleanYfac }; } void DBaseStatusBar::SetSize(int reltop, int hres, int vres) @@ -327,7 +407,6 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) } Displacement = 0; } - gST_X = ST_X; } DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetScaled) @@ -349,6 +428,96 @@ void DBaseStatusBar::CallSetScaled(bool scale, bool force) else SetScaled(scale, force); } +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +DVector2 DBaseStatusBar::GetHUDScale() const +{ + int scale; + if (hud_scale < 0 || ForcedScale) // a negative value is the equivalent to the old boolean hud_scale. This can yield different values for x and y for higher resolutions. + { + return defaultScale; + } + if (hud_scale > 0) // use the scale as an absolute value, but also factor in the specified resolution of the HUD + { + scale = hud_scale; + } + else if (uiscale == 0) + { + return defaultScale; + } + else + { + scale = MAX(1, uiscale); + } + + // Since status bars and HUDs can be designed for non 320x200 screens this needs to be factored in here. + // The global scaling factors are for resources at 320x200, so if the actual ones are higher resolution + // the resulting scaling factor needs to be reduced accordingly. + int realscale = MAX(1, (320 * scale) / HorizontalResolution); + return{ double(realscale), double(realscale) }; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetHUDScale) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + ACTION_RETURN_VEC2(self->GetHUDScale()); +} + +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool completeborder, bool forceScaled) +{ + SetSize(relTop, resW, resH); + SetScaled(st_scale, forceScaled); + CompleteBorder = completeborder; + fullscreenOffsets = false; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginStatusBar) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_INT(w); + PARAM_INT(h); + PARAM_INT(r); + PARAM_BOOL_DEF(cb); + PARAM_BOOL_DEF(fs); + self->BeginStatusBar(w, h, r, cb, fs); + return 0; +} +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled) +{ + SetSize(0, resW, resH); // this intentionally resets the relative top to force the caller to go through BeginStatusBar and not just reset some variables. + this->Alpha = Alpha; + ForcedScale = forcescaled; + CompleteBorder = false; + fullscreenOffsets = true; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginHUD) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_INT(w); + PARAM_INT(h); + PARAM_FLOAT(a); + PARAM_BOOL_DEF(fs); + self->BeginHUD(w, h, a, fs); + return 0; +} + //--------------------------------------------------------------------------- // // PROC AttachToPlayer @@ -1016,6 +1185,16 @@ bool DBaseStatusBar::MustDrawLog(EHudState state) return true; } +DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetMugshotState) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_STRING(statename); + PARAM_BOOL(wait); + PARAM_BOOL(reset); + self->mugshot.SetState(statename, wait, reset); + return 0; +} + void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, bool reset) { IFVIRTUAL(DBaseStatusBar, SetMugShotState) @@ -1024,7 +1203,6 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b VMValue params[] = { (DObject*)this, &statestring, waitTillDone, reset }; GlobalVMStack.Call(func, params, countof(params), nullptr, 0); } - mugshot.SetState(stateName, waitTillDone, reset); } //--------------------------------------------------------------------------- @@ -1223,7 +1401,7 @@ void DBaseStatusBar::ScreenSizeChanged () int x, y; V_CalcCleanFacs(HorizontalResolution, VerticalResolution, SCREENWIDTH, SCREENHEIGHT, &x, &y); - cleanScale = { (double)x, (double)y }; + defaultScale = { (double)x, (double)y }; for (size_t i = 0; i < countof(Messages); ++i) { @@ -1423,13 +1601,12 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, dou if (screenalign == (RIGHT | TOP) && vid_fps) y += 10; - if (hud_scale) - { - x *= cleanScale.X; - y *= cleanScale.Y; - width *= cleanScale.X; - height *= cleanScale.Y; - } + DVector2 Scale = GetHUDScale(); + + x *= Scale.X; + y *= Scale.Y; + width *= Scale.X; + height *= Scale.Y; x += orgx; y += orgy; } @@ -1495,14 +1672,13 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); int fontcolor = translation; double orgx = 0, orgy = 0; + DVector2 Scale; if (fullscreenOffsets) { - if (hud_scale) - { - shadowX *= (int)cleanScale.X; - shadowY *= (int)cleanScale.Y; - } + Scale = GetHUDScale(); + shadowX *= (int)Scale.X; + shadowY *= (int)Scale.Y; switch (screenalign & HMASK) { @@ -1520,6 +1696,10 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10; } + else + { + Scale = { 1.,1. }; + } int ch; while (ch = *str++, ch != '\0') { @@ -1582,13 +1762,11 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d } else { - if (hud_scale) - { - rx *= cleanScale.X; - ry *= cleanScale.Y; - rw *= cleanScale.X; - rh *= cleanScale.Y; - } + rx *= Scale.X; + ry *= Scale.Y; + rw *= Scale.X; + rh *= Scale.Y; + rx += orgx; ry += orgy; } @@ -1697,23 +1875,11 @@ DEFINE_FIELD(DBaseStatusBar, Alpha); DEFINE_FIELD(DBaseStatusBar, drawOffset); DEFINE_FIELD(DBaseStatusBar, drawClip); DEFINE_FIELD(DBaseStatusBar, fullscreenOffsets); -DEFINE_FIELD(DBaseStatusBar, cleanScale); +DEFINE_FIELD(DBaseStatusBar, defaultScale); DEFINE_GLOBAL(StatusBar); -DBaseStatusBar *CreateStrifeStatusBar() -{ - auto sb = (DBaseStatusBar *)PClass::FindClass("StrifeStatusBar")->CreateNew(); - IFVIRTUALPTR(sb, DBaseStatusBar, Init) - { - VMValue params[] = { sb }; - GlobalVMStack.Call(func, params, 1, nullptr, 0); - } - return sb; -} - - static DObject *InitObject(PClass *type, int paramnum, VM_ARGS) { auto obj = type->CreateNew(); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 8b4e11ab5..03f865a99 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -354,6 +354,21 @@ void FGameConfigFile::DoGlobalSetup () SetValueForKey ("5", "use ArtiInvulnerability2"); } } + if (last < 212) + { + FBaseCVar *var = FindCVar("hud_scale", NULL); + if (var != NULL) + { + var->ResetToDefault(); + } + var = FindCVar("snd_channels", NULL); + if (var != NULL) + { + // old settings were default 32, minimum 8, new settings are default 128, minimum 64. + UCVarValue v = var->GetGenericRep(CVAR_Int); + if (v.Int < 64) var->ResetToDefault(); + } + } } } } diff --git a/src/gi.cpp b/src/gi.cpp index 0ac9c82b6..77a8f9eec 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -153,6 +153,14 @@ const char* GameInfoBorders[] = gameinfo.key = sc.String; \ } +#define GAMEINFOKEY_STRING_STAMPED(key, variable, stampvar) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.key = sc.String; \ + gameinfo.stampvar = Wads.GetLumpFile(sc.LumpNum); \ + } + #define GAMEINFOKEY_INT(key, variable) \ else if(nextKey.CompareNoCase(variable) == 0) \ { \ @@ -358,7 +366,8 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor") GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor") GAMEINFOKEY_STRING(backpacktype, "backpacktype") - GAMEINFOKEY_STRING(statusbar, "statusbar") + GAMEINFOKEY_STRING_STAMPED(statusbar, "statusbar", statusbarfile) + GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile) GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic") GAMEINFOKEY_STRING(CursorPic, "CursorPic") GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") diff --git a/src/gi.h b/src/gi.h index 3f51055fe..52fdaf49c 100644 --- a/src/gi.h +++ b/src/gi.h @@ -148,8 +148,11 @@ struct gameinfo_t FString translator; uint32_t defaultbloodcolor; uint32_t defaultbloodparticlecolor; - FName backpacktype; FString statusbar; + int statusbarfile = -1; + FName statusbarclass; + int statusbarclassfile = -1; + FName backpacktype; FString intermissionMusic; int intermissionOrder; FString CursorPic; diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index d8f93d388..eaa812dc9 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -37,23 +37,23 @@ #include "poly_draw_args.h" #include "swrenderer/viewport/r_viewport.h" -void PolyDrawArgs::SetClipPlane(float a, float b, float c, float d) +void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane) { - clipPlane[0] = a; - clipPlane[1] = b; - clipPlane[2] = c; - clipPlane[3] = d; + mClipPlane[0] = plane.A; + mClipPlane[1] = plane.B; + mClipPlane[2] = plane.C; + mClipPlane[3] = plane.D; } void PolyDrawArgs::SetTexture(FTexture *texture) { - textureWidth = texture->GetWidth(); - textureHeight = texture->GetHeight(); + mTextureWidth = texture->GetWidth(); + mTextureHeight = texture->GetHeight(); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) - texturePixels = (const uint8_t *)texture->GetPixelsBgra(); + mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else - texturePixels = texture->GetPixels(); - translation = nullptr; + mTexturePixels = texture->GetPixels(); + mTranslation = nullptr; } void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal) @@ -64,22 +64,22 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo if (table != nullptr && !table->Inactive) { if (PolyRenderer::Instance()->RenderTarget->IsBgra()) - translation = (uint8_t*)table->Palette; + mTranslation = (uint8_t*)table->Palette; else - translation = table->Remap; + mTranslation = table->Remap; - textureWidth = texture->GetWidth(); - textureHeight = texture->GetHeight(); - texturePixels = texture->GetPixels(); + mTextureWidth = texture->GetWidth(); + mTextureHeight = texture->GetHeight(); + mTexturePixels = texture->GetPixels(); return; } } if (forcePal) { - textureWidth = texture->GetWidth(); - textureHeight = texture->GetHeight(); - texturePixels = texture->GetPixels(); + mTextureWidth = texture->GetWidth(); + mTextureHeight = texture->GetHeight(); + mTexturePixels = texture->GetPixels(); } else { @@ -87,21 +87,48 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo } } -void PolyDrawArgs::SetColormap(FSWColormap *base_colormap) +void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, double globVis, bool fixed) { - uniforms.light_red = base_colormap->Color.r * 256 / 255; - uniforms.light_green = base_colormap->Color.g * 256 / 255; - uniforms.light_blue = base_colormap->Color.b * 256 / 255; - uniforms.light_alpha = base_colormap->Color.a * 256 / 255; - uniforms.fade_red = base_colormap->Fade.r; - uniforms.fade_green = base_colormap->Fade.g; - uniforms.fade_blue = base_colormap->Fade.b; - uniforms.fade_alpha = base_colormap->Fade.a; - uniforms.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256; - bool simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0); - if (simple_shade) - uniforms.flags |= TriUniforms::simple_shade; - else - uniforms.flags &= ~TriUniforms::simple_shade; - colormaps = base_colormap->Maps; + mGlobVis = (float)globVis; + + PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) + { + lightlevel = cameraLight->FixedLightLevel() >= 0 ? cameraLight->FixedLightLevel() : 255; + fixed = true; + } + + mLight = clamp(lightlevel, 0, 255); + mFixedLight = fixed; + mLightRed = base_colormap->Color.r * 256 / 255; + mLightGreen = base_colormap->Color.g * 256 / 255; + mLightBlue = base_colormap->Color.b * 256 / 255; + mLightAlpha = base_colormap->Color.a * 256 / 255; + mFadeRed = base_colormap->Fade.r; + mFadeGreen = base_colormap->Fade.g; + mFadeBlue = base_colormap->Fade.b; + mFadeAlpha = base_colormap->Fade.a; + mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256; + mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0); + mColormaps = base_colormap->Maps; +} + +void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex) +{ + if (PolyRenderer::Instance()->RenderTarget->IsBgra()) + { + mColor = bgra; + } + else + { + mColor = palindex; + } +} + +void PolyDrawArgs::DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode) +{ + mVertices = vertices; + mVertexCount = vcount; + mDrawMode = mode; + PolyRenderer::Instance()->DrawQueue->Push(*this, PolyTriangleDrawer::is_mirror()); } diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index bf38ffab9..20c73ec58 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -27,43 +27,123 @@ #include "screen_triangle.h" class FTexture; +struct TriMatrix; -enum class TriangleDrawMode +enum class PolyDrawMode { - Normal, - Fan, - Strip + Triangles, + TriangleFan, + TriangleStrip }; -struct TriDrawTriangleArgs; -struct TriMatrix; +class PolyClipPlane +{ +public: + PolyClipPlane() : A(0.0f), B(0.0f), C(0.0f), D(1.0f) { } + PolyClipPlane(float a, float b, float c, float d) : A(a), B(b), C(c), D(d) { } + + float A, B, C, D; +}; class PolyDrawArgs { public: - TriUniforms uniforms; - const TriMatrix *objectToClip = nullptr; - const TriVertex *vinput = nullptr; - int vcount = 0; - TriangleDrawMode mode = TriangleDrawMode::Normal; - bool ccw = false; - // bool stencilTest = true; // Always true for now - bool subsectorTest = false; - bool writeStencil = true; - bool writeColor = true; - bool writeSubsector = true; - const uint8_t *texturePixels = nullptr; - int textureWidth = 0; - int textureHeight = 0; - const uint8_t *translation = nullptr; - uint8_t stenciltestvalue = 0; - uint8_t stencilwritevalue = 0; - const uint8_t *colormaps = nullptr; - float clipPlane[4]; - TriBlendMode blendmode = TriBlendMode::Copy; - - void SetClipPlane(float a, float b, float c, float d); + void SetClipPlane(const PolyClipPlane &plane); void SetTexture(FTexture *texture); void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false); - void SetColormap(FSWColormap *base_colormap); + void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed); + void SetSubsectorDepth(uint32_t subsectorDepth) { mSubsectorDepth = subsectorDepth; } + void SetSubsectorDepthTest(bool enable) { mSubsectorTest = enable; } + void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; } + void SetWriteColor(bool enable) { mWriteColor = enable; } + void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; } + void SetWriteSubsectorDepth(bool enable) { mWriteSubsector = enable; } + void SetFaceCullCCW(bool counterclockwise) { mFaceCullCCW = counterclockwise; } + void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); } + void SetTransform(const TriMatrix *objectToClip) { mObjectToClip = objectToClip; } + void SetColor(uint32_t bgra, uint8_t palindex); + void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles); + + const TriMatrix *ObjectToClip() const { return mObjectToClip; } + const float *ClipPlane() const { return mClipPlane; } + + const TriVertex *Vertices() const { return mVertices; } + int VertexCount() const { return mVertexCount; } + PolyDrawMode DrawMode() const { return mDrawMode; } + + bool FaceCullCCW() const { return mFaceCullCCW; } + bool WriteColor() const { return mWriteColor; } + + const uint8_t *TexturePixels() const { return mTexturePixels; } + int TextureWidth() const { return mTextureWidth; } + int TextureHeight() const { return mTextureHeight; } + const uint8_t *Translation() const { return mTranslation; } + + bool WriteStencil() const { return mWriteStencil; } + uint8_t StencilTestValue() const { return mStencilTestValue; } + uint8_t StencilWriteValue() const { return mStencilWriteValue; } + + bool SubsectorTest() const { return mSubsectorTest; } + bool WriteSubsector() const { return mWriteSubsector; } + uint32_t SubsectorDepth() const { return mSubsectorDepth; } + + TriBlendMode BlendMode() const { return mBlendMode; } + uint32_t Color() const { return mColor; } + uint32_t SrcAlpha() const { return mSrcAlpha; } + uint32_t DestAlpha() const { return mDestAlpha; } + + float GlobVis() const { return mGlobVis; } + uint32_t Light() const { return mLight; } + const uint8_t *BaseColormap() const { return mColormaps; } + uint16_t ShadeLightAlpha() const { return mLightAlpha; } + uint16_t ShadeLightRed() const { return mLightRed; } + uint16_t ShadeLightGreen() const { return mLightGreen; } + uint16_t ShadeLightBlue() const { return mLightBlue; } + uint16_t ShadeFadeAlpha() const { return mFadeAlpha; } + uint16_t ShadeFadeRed() const { return mFadeRed; } + uint16_t ShadeFadeGreen() const { return mFadeGreen; } + uint16_t ShadeFadeBlue() const { return mFadeBlue; } + uint16_t ShadeDesaturate() const { return mDesaturate; } + + bool SimpleShade() const { return mSimpleShade; } + bool NearestFilter() const { return mNearestFilter; } + bool FixedLight() const { return mFixedLight; } + +private: + const TriMatrix *mObjectToClip = nullptr; + const TriVertex *mVertices = nullptr; + int mVertexCount = 0; + PolyDrawMode mDrawMode = PolyDrawMode::Triangles; + bool mFaceCullCCW = false; + bool mSubsectorTest = false; + bool mWriteStencil = true; + bool mWriteColor = true; + bool mWriteSubsector = true; + const uint8_t *mTexturePixels = nullptr; + int mTextureWidth = 0; + int mTextureHeight = 0; + const uint8_t *mTranslation = nullptr; + uint8_t mStencilTestValue = 0; + uint8_t mStencilWriteValue = 0; + const uint8_t *mColormaps = nullptr; + float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + TriBlendMode mBlendMode = TriBlendMode::Copy; + uint32_t mLight = 0; + uint32_t mSubsectorDepth = 0; + uint32_t mColor = 0; + uint32_t mSrcAlpha = 0; + uint32_t mDestAlpha = 0; + uint16_t mLightAlpha = 0; + uint16_t mLightRed = 0; + uint16_t mLightGreen = 0; + uint16_t mLightBlue = 0; + uint16_t mFadeAlpha = 0; + uint16_t mFadeRed = 0; + uint16_t mFadeGreen = 0; + uint16_t mFadeBlue = 0; + uint16_t mDesaturate = 0; + float mGlobVis = 0.0f; + bool mSimpleShade = true; + bool mNearestFilter = true; + bool mFixedLight = false; }; diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index c86d3bc93..a3568b6c1 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -32,12 +32,11 @@ public: { using namespace TriScreenDrawerModes; - auto flags = args->uniforms->flags; - bool is_simple_shade = (flags & TriUniforms::simple_shade) == TriUniforms::simple_shade; + bool is_simple_shade = args->uniforms->SimpleShade(); if (SamplerT::Mode == (int)Samplers::Texture) { - bool is_nearest_filter = (flags & TriUniforms::nearest_filter) == TriUniforms::nearest_filter; + bool is_nearest_filter = args->uniforms->NearestFilter(); if (is_simple_shade) { @@ -79,11 +78,10 @@ public: int startX = thread->StartX; int startY = thread->StartY; - auto flags = args->uniforms->flags; - bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light; + bool is_fixed_light = args->uniforms->FixedLight(); uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - uint32_t srcalpha = args->uniforms->srcalpha; - uint32_t destalpha = args->uniforms->destalpha; + uint32_t srcalpha = args->uniforms->SrcAlpha(); + uint32_t destalpha = args->uniforms->DestAlpha(); // Calculate gradients const TriVertex &v1 = *args->v1; @@ -107,16 +105,17 @@ public: int pitch = args->pitch; // Light - uint32_t light = args->uniforms->light; - float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f; - float globVis = args->uniforms->globvis * (1.0f / 32.0f); + uint32_t light = args->uniforms->Light(); + float shade = 2.0f - (light + 12.0f) / 128.0f; + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + light += (light >> 7); // 255 -> 256 // Sampling stuff - uint32_t color = args->uniforms->color; - const uint32_t * RESTRICT translation = (const uint32_t *)args->translation; - const uint32_t * RESTRICT texPixels = (const uint32_t *)args->texturePixels; - uint32_t texWidth = args->textureWidth; - uint32_t texHeight = args->textureHeight; + uint32_t color = args->uniforms->Color(); + const uint32_t * RESTRICT translation = (const uint32_t *)args->uniforms->Translation(); + const uint32_t * RESTRICT texPixels = (const uint32_t *)args->uniforms->TexturePixels(); + uint32_t texWidth = args->uniforms->TextureWidth(); + uint32_t texHeight = args->uniforms->TextureHeight(); uint32_t oneU, oneV; if (SamplerT::Mode != (int)Samplers::Fill) { @@ -134,10 +133,10 @@ public: int desaturate; if (ShadeModeT::Mode == (int)ShadeMode::Advanced) { - inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate); - shade_fade = _mm_set_epi16(args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue, args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue); - shade_light = _mm_set_epi16(args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue, args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue); - desaturate = args->uniforms->desaturate; + inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate()); + shade_fade = _mm_set_epi16(args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue(), args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue()); + shade_light = _mm_set_epi16(args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue(), args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue()); + desaturate = args->uniforms->ShadeDesaturate(); } else { diff --git a/src/polyrenderer/drawers/poly_drawer8.h b/src/polyrenderer/drawers/poly_drawer8.h index 6535f4852..2ae40e524 100644 --- a/src/polyrenderer/drawers/poly_drawer8.h +++ b/src/polyrenderer/drawers/poly_drawer8.h @@ -39,12 +39,11 @@ public: int startX = thread->StartX; int startY = thread->StartY; - auto flags = args->uniforms->flags; - bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light; + bool is_fixed_light = args->uniforms->FixedLight(); uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - auto colormaps = args->colormaps; - uint32_t srcalpha = args->uniforms->srcalpha; - uint32_t destalpha = args->uniforms->destalpha; + auto colormaps = args->uniforms->BaseColormap(); + uint32_t srcalpha = args->uniforms->SrcAlpha(); + uint32_t destalpha = args->uniforms->DestAlpha(); // Calculate gradients const TriVertex &v1 = *args->v1; @@ -68,16 +67,17 @@ public: int pitch = args->pitch; // Light - uint32_t light = args->uniforms->light; - float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f; - float globVis = args->uniforms->globvis * (1.0f / 32.0f); + uint32_t light = args->uniforms->Light(); + float shade = 2.0f - (light + 12.0f) / 128.0f; + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + light += light >> 7; // 255 -> 256 // Sampling stuff - uint32_t color = args->uniforms->color; - const uint8_t * RESTRICT translation = args->translation; - const uint8_t * RESTRICT texPixels = args->texturePixels; - uint32_t texWidth = args->textureWidth; - uint32_t texHeight = args->textureHeight; + uint32_t color = args->uniforms->Color(); + const uint8_t * RESTRICT translation = args->uniforms->Translation(); + const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels(); + uint32_t texWidth = args->uniforms->TextureWidth(); + uint32_t texHeight = args->uniforms->TextureHeight(); for (int i = 0; i < numSpans; i++) { diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index fa4b8b98c..d07102f1e 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -80,35 +80,35 @@ void PolyTriangleDrawer::toggle_mirror() mirror = !mirror; } -void PolyTriangleDrawer::draw(const PolyDrawArgs &args) +bool PolyTriangleDrawer::is_mirror() { - PolyRenderer::Instance()->DrawQueue->Push(args, mirror); + return mirror; } void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread) { - if (drawargs.vcount < 3) + if (drawargs.VertexCount() < 3) return; PolyDrawFuncPtr drawfuncs[4]; int num_drawfuncs = 0; - drawfuncs[num_drawfuncs++] = drawargs.subsectorTest ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal; + drawfuncs[num_drawfuncs++] = drawargs.SubsectorTest() ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal; if (!r_debug_trisetup) // For profiling how much time is spent in setup vs drawal { - int bmode = (int)drawargs.blendmode; + int bmode = (int)drawargs.BlendMode(); - if (drawargs.writeColor && drawargs.texturePixels) + if (drawargs.WriteColor() && drawargs.TexturePixels()) drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDraw32[bmode] : ScreenTriangle::TriDraw8[bmode]; - else if (drawargs.writeColor) + else if (drawargs.WriteColor()) drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriFill32[bmode] : ScreenTriangle::TriFill8[bmode]; } - if (drawargs.writeStencil) + if (drawargs.WriteStencil()) drawfuncs[num_drawfuncs++] = &ScreenTriangle::StencilWrite; - if (drawargs.writeSubsector) + if (drawargs.WriteSubsector()) drawfuncs[num_drawfuncs++] = &ScreenTriangle::SubsectorWrite; TriDrawTriangleArgs args; @@ -118,53 +118,44 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD args.clipright = dest_width; args.cliptop = 0; args.clipbottom = dest_height; - args.texturePixels = drawargs.texturePixels; - args.textureWidth = drawargs.textureWidth; - args.textureHeight = drawargs.textureHeight; - args.translation = drawargs.translation; - args.uniforms = &drawargs.uniforms; - args.stencilTestValue = drawargs.stenciltestvalue; - args.stencilWriteValue = drawargs.stencilwritevalue; + args.uniforms = &drawargs; args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth(); args.stencilValues = PolyStencilBuffer::Instance()->Values(); args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values(); - args.colormaps = drawargs.colormaps; - args.RGB256k = RGB256k.All; - args.BaseColors = (const uint8_t *)GPalette.BaseColors; - bool ccw = drawargs.ccw; - const TriVertex *vinput = drawargs.vinput; - int vcount = drawargs.vcount; + bool ccw = drawargs.FaceCullCCW(); + const TriVertex *vinput = drawargs.Vertices(); + int vcount = drawargs.VertexCount(); ShadedTriVertex vert[3]; - if (drawargs.mode == TriangleDrawMode::Normal) + if (drawargs.DrawMode() == PolyDrawMode::Triangles) { for (int i = 0; i < vcount / 3; i++) { for (int j = 0; j < 3; j++) - vert[j] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); + vert[j] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs); } } - else if (drawargs.mode == TriangleDrawMode::Fan) + else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan) { - vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); - vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); + vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); + vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs); vert[1] = vert[2]; } } - else // TriangleDrawMode::Strip + else // TriangleDrawMode::TriangleStrip { - vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); - vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); + vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++)); + vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs); vert[0] = vert[1]; vert[1] = vert[2]; @@ -448,7 +439,7 @@ DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, boo : args(args) { if (mirror) - this->args.ccw = !this->args.ccw; + this->args.SetFaceCullCCW(!this->args.FaceCullCCW()); } void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) @@ -461,32 +452,3 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) PolyTriangleDrawer::draw_arrays(args, &thread_data); } - -FString DrawPolyTrianglesCommand::DebugInfo() -{ - FString blendmodestr; - switch (args.blendmode) - { - default: blendmodestr = "Unknown"; break; - case TriBlendMode::Copy: blendmodestr = "Copy"; break; - case TriBlendMode::AlphaBlend: blendmodestr = "AlphaBlend"; break; - case TriBlendMode::AddSolid: blendmodestr = "AddSolid"; break; - case TriBlendMode::Add: blendmodestr = "Add"; break; - case TriBlendMode::Sub: blendmodestr = "Sub"; break; - case TriBlendMode::RevSub: blendmodestr = "RevSub"; break; - case TriBlendMode::Stencil: blendmodestr = "Stencil"; break; - case TriBlendMode::Shaded: blendmodestr = "Shaded"; break; - case TriBlendMode::TranslateCopy: blendmodestr = "TranslateCopy"; break; - case TriBlendMode::TranslateAlphaBlend: blendmodestr = "TranslateAlphaBlend"; break; - case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break; - case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break; - case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break; - case TriBlendMode::AddSrcColorOneMinusSrcColor: blendmodestr = "AddSrcColorOneMinusSrcColor"; break; - } - - FString info; - info.Format("DrawPolyTriangles: blend mode = %s, color = %d, light = %d, textureWidth = %d, textureHeight = %d, texture = %s, translation = %s, colormaps = %s", - blendmodestr.GetChars(), args.uniforms.color, args.uniforms.light, args.textureWidth, args.textureHeight, - args.texturePixels ? "ptr" : "null", args.translation ? "ptr" : "null", args.colormaps ? "ptr" : "null"); - return info; -} diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index a52faa326..d3019fc36 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -40,8 +40,8 @@ class PolyTriangleDrawer { public: static void set_viewport(int x, int y, int width, int height, DCanvas *canvas); - static void draw(const PolyDrawArgs &args); static void toggle_mirror(); + static bool is_mirror(); private: static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v); @@ -66,7 +66,7 @@ public: DrawPolyTrianglesCommand(const PolyDrawArgs &args, bool mirror); void Execute(DrawerThread *thread) override; - FString DebugInfo() override; + FString DebugInfo() override { return "DrawPolyTriangles"; } private: PolyDrawArgs args; diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 37a14c062..ab0928d0e 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -52,7 +52,7 @@ void ScreenTriangle::SetupNormal(const TriDrawTriangleArgs *args, WorkerThreadDa int stencilPitch = args->stencilPitch; uint8_t * RESTRICT stencilValues = args->stencilValues; uint32_t * RESTRICT stencilMasks = args->stencilMasks; - uint8_t stencilTestValue = args->stencilTestValue; + uint8_t stencilTestValue = args->uniforms->StencilTestValue(); TriFullSpan * RESTRICT span = thread->FullSpans; TriPartialBlock * RESTRICT partial = thread->PartialBlocks; @@ -389,10 +389,10 @@ void ScreenTriangle::SetupSubsector(const TriDrawTriangleArgs *args, WorkerThrea int stencilPitch = args->stencilPitch; uint8_t * RESTRICT stencilValues = args->stencilValues; uint32_t * RESTRICT stencilMasks = args->stencilMasks; - uint8_t stencilTestValue = args->stencilTestValue; + uint8_t stencilTestValue = args->uniforms->StencilTestValue(); uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer; - uint32_t subsectorDepth = args->uniforms->subsectorDepth; + uint32_t subsectorDepth = args->uniforms->SubsectorDepth(); int32_t pitch = args->pitch; TriFullSpan * RESTRICT span = thread->FullSpans; @@ -800,7 +800,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD { uint8_t * RESTRICT stencilValues = args->stencilValues; uint32_t * RESTRICT stencilMasks = args->stencilMasks; - uint32_t stencilWriteValue = args->stencilWriteValue; + uint32_t stencilWriteValue = args->uniforms->StencilWriteValue(); uint32_t stencilPitch = args->stencilPitch; int numSpans = thread->NumFullSpans; @@ -869,7 +869,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread) { uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer; - uint32_t subsectorDepth = args->uniforms->subsectorDepth; + uint32_t subsectorDepth = args->uniforms->SubsectorDepth(); int pitch = args->pitch; int numSpans = thread->NumFullSpans; diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 470029c84..81d7cdb68 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -26,6 +26,7 @@ #include class FString; +class PolyDrawArgs; struct TriFullSpan { @@ -67,32 +68,6 @@ struct TriVertex float varying[NumVarying]; }; -struct TriUniforms -{ - uint32_t light; - uint32_t subsectorDepth; - uint32_t color; - uint32_t srcalpha; - uint32_t destalpha; - uint16_t light_alpha; - uint16_t light_red; - uint16_t light_green; - uint16_t light_blue; - uint16_t fade_alpha; - uint16_t fade_red; - uint16_t fade_green; - uint16_t fade_blue; - uint16_t desaturate; - float globvis; - uint32_t flags; - enum Flags - { - simple_shade = 1, - nearest_filter = 2, - fixed_light = 4 - }; -}; - struct TriDrawTriangleArgs { uint8_t *dest; @@ -104,20 +79,11 @@ struct TriDrawTriangleArgs int32_t clipright; int32_t cliptop; int32_t clipbottom; - const uint8_t *texturePixels; - uint32_t textureWidth; - uint32_t textureHeight; - const uint8_t *translation; - const TriUniforms *uniforms; uint8_t *stencilValues; uint32_t *stencilMasks; int32_t stencilPitch; - uint8_t stencilTestValue; - uint8_t stencilWriteValue; uint32_t *subsectorGBuffer; - const uint8_t *colormaps; - const uint8_t *RGB256k; - const uint8_t *BaseColors; + const PolyDrawArgs *uniforms; }; enum class TriBlendMode diff --git a/src/polyrenderer/math/poly_intersection.cpp b/src/polyrenderer/math/poly_intersection.cpp deleted file mode 100644 index ed5e8ef43..000000000 --- a/src/polyrenderer/math/poly_intersection.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* -** Various 3D intersection tests -** Copyright (c) 1997-2015 The UICore Team -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#include -#include "templates.h" -#include "doomdef.h" -#include "poly_intersection.h" - -IntersectionTest::Result IntersectionTest::plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb) -{ - Vec3f center = aabb.center(); - Vec3f extents = aabb.extents(); - float e = extents.x * std::abs(plane.x) + extents.y * std::abs(plane.y) + extents.z * std::abs(plane.z); - float s = center.x * plane.x + center.y * plane.y + center.z * plane.z + plane.w; - if (s - e > 0) - return inside; - else if (s + e < 0) - return outside; - else - return intersecting; -} - -IntersectionTest::Result IntersectionTest::plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb) -{ - Vec3f n(plane); - float d = plane.w; - float e = obb.extents.x * std::abs(Vec3f::dot(obb.axis_x, n)) + obb.extents.y * std::abs(Vec3f::dot(obb.axis_y, n)) + obb.extents.z * std::abs(Vec3f::dot(obb.axis_z, n)); - float s = Vec3f::dot(obb.center, n) + d; - if (s - e > 0) - return inside; - else if (s + e < 0) - return outside; - else - return intersecting; -} - -IntersectionTest::OverlapResult IntersectionTest::sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2) -{ - Vec3f h = center1 - center2; - float square_distance = Vec3f::dot(h, h); - float radius_sum = radius1 + radius2; - if (square_distance > radius_sum * radius_sum) - return disjoint; - else - return overlap; -} - -IntersectionTest::OverlapResult IntersectionTest::sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb) -{ - Vec3f a = aabb.aabb_min - center; - Vec3f b = center - aabb.aabb_max; - a.x = std::max(a.x, 0.0f); - a.y = std::max(a.y, 0.0f); - a.z = std::max(a.z, 0.0f); - b.x = std::max(b.x, 0.0f); - b.y = std::max(b.y, 0.0f); - b.z = std::max(b.z, 0.0f); - Vec3f e = a + b; - float d = Vec3f::dot(e, e); - if (d > radius * radius) - return disjoint; - else - return overlap; -} - -IntersectionTest::OverlapResult IntersectionTest::aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b) -{ - if (a.aabb_min.x > b.aabb_max.x || b.aabb_min.x > a.aabb_max.x || - a.aabb_min.y > b.aabb_max.y || b.aabb_min.y > a.aabb_max.y || - a.aabb_min.z > b.aabb_max.z || b.aabb_min.z > a.aabb_max.z) - { - return disjoint; - } - else - { - return overlap; - } -} - -IntersectionTest::Result IntersectionTest::frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box) -{ - bool is_intersecting = false; - for (int i = 0; i < 6; i++) - { - Result result = plane_aabb(frustum.planes[i], box); - if (result == outside) - return outside; - else if (result == intersecting) - is_intersecting = true; - break; - } - if (is_intersecting) - return intersecting; - else - return inside; -} - -IntersectionTest::Result IntersectionTest::frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box) -{ - bool is_intersecting = false; - for (int i = 0; i < 6; i++) - { - Result result = plane_obb(frustum.planes[i], box); - if (result == outside) - return outside; - else if (result == intersecting) - is_intersecting = true; - } - if (is_intersecting) - return intersecting; - else - return inside; -} - -IntersectionTest::OverlapResult IntersectionTest::ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &aabb) -{ - Vec3f c = (ray_start + ray_end) * 0.5f; - Vec3f w = ray_end - c; - Vec3f h = aabb.extents(); - - c -= aabb.center(); - - Vec3f v(std::abs(w.x), std::abs(w.y), std::abs(w.z)); - - if (std::abs(c.x) > v.x + h.x || std::abs(c.y) > v.y + h.y || std::abs(c.z) > v.z + h.z) - return disjoint; - - if (std::abs(c.y * w.z - c.z * w.y) > h.y * v.z + h.z * v.y || - std::abs(c.x * w.z - c.z * w.x) > h.x * v.z + h.z * v.x || - std::abs(c.x * w.y - c.y * w.x) > h.x * v.y + h.y * v.x) - return disjoint; - - return overlap; -} - -///////////////////////////////////////////////////////////////////////////// - -FrustumPlanes::FrustumPlanes() -{ -} - -FrustumPlanes::FrustumPlanes(const Mat4f &world_to_projection) -{ - planes[0] = near_frustum_plane(world_to_projection); - planes[1] = far_frustum_plane(world_to_projection); - planes[2] = left_frustum_plane(world_to_projection); - planes[3] = right_frustum_plane(world_to_projection); - planes[4] = top_frustum_plane(world_to_projection); - planes[5] = bottom_frustum_plane(world_to_projection); -} - -Vec4f FrustumPlanes::left_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] + m.matrix[0 + 0 * 4], - m.matrix[3 + 1 * 4] + m.matrix[0 + 1 * 4], - m.matrix[3 + 2 * 4] + m.matrix[0 + 2 * 4], - m.matrix[3 + 3 * 4] + m.matrix[0 + 3 * 4]); - plane /= plane.length3(); - return plane; -} - -Vec4f FrustumPlanes::right_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] - m.matrix[0 + 0 * 4], - m.matrix[3 + 1 * 4] - m.matrix[0 + 1 * 4], - m.matrix[3 + 2 * 4] - m.matrix[0 + 2 * 4], - m.matrix[3 + 3 * 4] - m.matrix[0 + 3 * 4]); - plane /= plane.length3(); - return plane; -} - -Vec4f FrustumPlanes::top_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] - m.matrix[1 + 0 * 4], - m.matrix[3 + 1 * 4] - m.matrix[1 + 1 * 4], - m.matrix[3 + 2 * 4] - m.matrix[1 + 2 * 4], - m.matrix[3 + 3 * 4] - m.matrix[1 + 3 * 4]); - plane /= plane.length3(); - return plane; -} - -Vec4f FrustumPlanes::bottom_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] + m.matrix[1 + 0 * 4], - m.matrix[3 + 1 * 4] + m.matrix[1 + 1 * 4], - m.matrix[3 + 2 * 4] + m.matrix[1 + 2 * 4], - m.matrix[3 + 3 * 4] + m.matrix[1 + 3 * 4]); - plane /= plane.length3(); - return plane; -} - -Vec4f FrustumPlanes::near_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] + m.matrix[2 + 0 * 4], - m.matrix[3 + 1 * 4] + m.matrix[2 + 1 * 4], - m.matrix[3 + 2 * 4] + m.matrix[2 + 2 * 4], - m.matrix[3 + 3 * 4] + m.matrix[2 + 3 * 4]); - plane /= plane.length3(); - return plane; -} - -Vec4f FrustumPlanes::far_frustum_plane(const Mat4f &m) -{ - Vec4f plane( - m.matrix[3 + 0 * 4] - m.matrix[2 + 0 * 4], - m.matrix[3 + 1 * 4] - m.matrix[2 + 1 * 4], - m.matrix[3 + 2 * 4] - m.matrix[2 + 2 * 4], - m.matrix[3 + 3 * 4] - m.matrix[2 + 3 * 4]); - plane /= plane.length3(); - return plane; -} diff --git a/src/polyrenderer/math/poly_intersection.h b/src/polyrenderer/math/poly_intersection.h deleted file mode 100644 index 438146fce..000000000 --- a/src/polyrenderer/math/poly_intersection.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -** Various 3D intersection tests -** Copyright (c) 1997-2015 The UICore Team -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#pragma once - -#include "polyrenderer/drawers/poly_triangle.h" -#include -#include - -class Vec3f; - -class Vec4f -{ -public: - Vec4f() = default; - Vec4f(const Vec4f &) = default; - Vec4f(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } - Vec4f(float v) : x(v), y(v), z(v), w(v) { } - Vec4f(const Vec3f &xyz, float w); - - static float dot(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } - static float dot3(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } - float length3() const { return std::sqrt(dot3(*this, *this)); } - float magnitude() const { return std::sqrt(dot(*this, *this)); } - - Vec4f &operator+=(const Vec4f &b) { *this = Vec4f(x + b.x, y + b.y, z + b.z, w + b.w); return *this; } - Vec4f &operator-=(const Vec4f &b) { *this = Vec4f(x - b.x, y - b.y, z - b.z, w - b.w); return *this; } - Vec4f &operator*=(const Vec4f &b) { *this = Vec4f(x * b.x, y * b.y, z * b.z, w * b.w); return *this; } - Vec4f &operator/=(const Vec4f &b) { *this = Vec4f(x / b.x, y / b.y, z / b.z, w / b.w); return *this; } - Vec4f &operator+=(float b) { *this = Vec4f(x + b, y + b, z + b, w + b); return *this; } - Vec4f &operator-=(float b) { *this = Vec4f(x - b, y - b, z - b, w - b); return *this; } - Vec4f &operator*=(float b) { *this = Vec4f(x * b, y * b, z * b, w * b); return *this; } - Vec4f &operator/=(float b) { *this = Vec4f(x / b, y / b, z / b, w / b); return *this; } - - float x, y, z, w; -}; - -inline bool operator==(const Vec4f &a, const Vec4f &b) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; } -inline bool operator!=(const Vec4f &a, const Vec4f &b) { return a.x != b.x || a.y != b.y || a.z != b.z || a.w == b.w; } - -class Vec3f -{ -public: - Vec3f() = default; - Vec3f(const Vec3f &) = default; - Vec3f(const Vec4f &v) : x(v.x), y(v.y), z(v.z) { } - Vec3f(float x, float y, float z) : x(x), y(y), z(z) { } - Vec3f(float v) : x(v), y(v), z(v) { } - - static float dot(const Vec3f &a, const Vec3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } - float length() const { return std::sqrt(dot(*this, *this)); } - - Vec3f &operator+=(const Vec3f &b) { *this = Vec3f(x + b.x, y + b.y, z + b.z); return *this; } - Vec3f &operator-=(const Vec3f &b) { *this = Vec3f(x - b.x, y - b.y, z - b.z); return *this; } - Vec3f &operator*=(const Vec3f &b) { *this = Vec3f(x * b.x, y * b.y, z * b.z); return *this; } - Vec3f &operator/=(const Vec3f &b) { *this = Vec3f(x / b.x, y / b.y, z / b.z); return *this; } - Vec3f &operator+=(float b) { *this = Vec3f(x + b, y + b, z + b); return *this; } - Vec3f &operator-=(float b) { *this = Vec3f(x - b, y - b, z - b); return *this; } - Vec3f &operator*=(float b) { *this = Vec3f(x * b, y * b, z * b); return *this; } - Vec3f &operator/=(float b) { *this = Vec3f(x / b, y / b, z / b); return *this; } - - float x, y, z; -}; - -inline bool operator==(const Vec3f &a, const Vec3f &b) { return a.x == b.x && a.y == b.y && a.z == b.z; } -inline bool operator!=(const Vec3f &a, const Vec3f &b) { return a.x != b.x || a.y != b.y || a.z != b.z; } - -inline Vec3f operator+(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x + b.x, a.y + b.y, a.z + b.z); } -inline Vec3f operator-(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x - b.x, a.y - b.y, a.z - b.z); } -inline Vec3f operator*(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x * b.x, a.y * b.y, a.z * b.z); } -inline Vec3f operator/(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x / b.x, a.y / b.y, a.z / b.z); } - -inline Vec3f operator+(const Vec3f &a, float b) { return Vec3f(a.x + b, a.y + b, a.z + b); } -inline Vec3f operator-(const Vec3f &a, float b) { return Vec3f(a.x - b, a.y - b, a.z - b); } -inline Vec3f operator*(const Vec3f &a, float b) { return Vec3f(a.x * b, a.y * b, a.z * b); } -inline Vec3f operator/(const Vec3f &a, float b) { return Vec3f(a.x / b, a.y / b, a.z / b); } - -inline Vec3f operator+(float a, const Vec3f &b) { return Vec3f(a + b.x, a + b.y, a + b.z); } -inline Vec3f operator-(float a, const Vec3f &b) { return Vec3f(a - b.x, a - b.y, a - b.z); } -inline Vec3f operator*(float a, const Vec3f &b) { return Vec3f(a * b.x, a * b.y, a * b.z); } -inline Vec3f operator/(float a, const Vec3f &b) { return Vec3f(a / b.x, a / b.y, a / b.z); } - -inline Vec4f::Vec4f(const Vec3f &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) { } - -typedef TriMatrix Mat4f; - -class AxisAlignedBoundingBox -{ -public: - AxisAlignedBoundingBox() : aabb_min(), aabb_max() {} - AxisAlignedBoundingBox(const Vec3f &aabb_min, const Vec3f &aabb_max) : aabb_min(aabb_min), aabb_max(aabb_max) { } - AxisAlignedBoundingBox(const AxisAlignedBoundingBox &aabb, const Vec3f &barycentric_min, const Vec3f &barycentric_max) - : aabb_min(mix(aabb.aabb_min, aabb.aabb_max, barycentric_min)), aabb_max(mix(aabb.aabb_min, aabb.aabb_max, barycentric_max)) { } - - Vec3f center() const { return (aabb_max + aabb_min) * 0.5f; } - Vec3f extents() const { return (aabb_max - aabb_min) * 0.5f; } - - Vec3f aabb_min; - Vec3f aabb_max; - -private: - template - inline A mix(A a, B b, C mix) - { - return a * (C(1) - mix) + b * mix; - } -}; - -class OrientedBoundingBox -{ -public: - Vec3f center; - Vec3f extents; - Vec3f axis_x; - Vec3f axis_y; - Vec3f axis_z; -}; - -class FrustumPlanes -{ -public: - FrustumPlanes(); - explicit FrustumPlanes(const Mat4f &world_to_projection); - - Vec4f planes[6]; - -private: - static Vec4f left_frustum_plane(const Mat4f &matrix); - static Vec4f right_frustum_plane(const Mat4f &matrix); - static Vec4f top_frustum_plane(const Mat4f &matrix); - static Vec4f bottom_frustum_plane(const Mat4f &matrix); - static Vec4f near_frustum_plane(const Mat4f &matrix); - static Vec4f far_frustum_plane(const Mat4f &matrix); -}; - -class IntersectionTest -{ -public: - enum Result - { - outside, - inside, - intersecting, - }; - - enum OverlapResult - { - disjoint, - overlap - }; - - static Result plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb); - static Result plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb); - static OverlapResult sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2); - static OverlapResult sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb); - static OverlapResult aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b); - static Result frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box); - static Result frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box); - static OverlapResult ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &box); -}; diff --git a/src/polyrenderer/poly_all.cpp b/src/polyrenderer/poly_all.cpp index 2ad4b45a4..286dae4cb 100644 --- a/src/polyrenderer/poly_all.cpp +++ b/src/polyrenderer/poly_all.cpp @@ -3,7 +3,6 @@ #include "drawers/poly_draw_args.cpp" #include "drawers/poly_triangle.cpp" #include "drawers/screen_triangle.cpp" -#include "math/poly_intersection.cpp" #include "math/tri_matrix.cpp" #include "scene/poly_cull.cpp" #include "scene/poly_decal.cpp" diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 2e400975f..1fb6de710 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -135,7 +135,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) ClearBuffers(); SetSceneViewport(); SetupPerspectiveMatrix(); - MainPortal.SetViewpoint(WorldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue()); + MainPortal.SetViewpoint(WorldToClip, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue()); MainPortal.Render(0); Skydome.Render(WorldToClip); MainPortal.RenderTranslucent(0); diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index 01f157a93..623b6e9df 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -28,10 +28,9 @@ #include "poly_cull.h" #include "polyrenderer/poly_renderer.h" -void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane) +void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane) { PvsSectors.clear(); - frustumPlanes = FrustumPlanes(worldToClip); PortalClipPlane = portalClipPlane; // Cull front to back @@ -210,20 +209,6 @@ int PolyCull::PointOnSide(const DVector2 &pos, const node_t *node) bool PolyCull::CheckBBox(float *bspcoord) { -#if 0 // This doesn't work because it creates gaps in the angle based clipper segment list :( - // Start using a quick frustum AABB test: - - AxisAlignedBoundingBox aabb(Vec3f(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z - 1000.0f), Vec3f(bspcoord[BOXRIGHT], bspcoord[BOXTOP], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z + 1000.0f)); - auto result = IntersectionTest::frustum_aabb(frustumPlanes, aabb); - if (result == IntersectionTest::outside) - return false; - - // Skip if its in front of the portal: - - if (IntersectionTest::plane_aabb(PortalClipPlane, aabb) == IntersectionTest::outside) - return false; -#endif - // Occlusion test using solid segments: static const uint8_t checkcoord[12][4] = { diff --git a/src/polyrenderer/scene/poly_cull.h b/src/polyrenderer/scene/poly_cull.h index d0430501d..64e4d5739 100644 --- a/src/polyrenderer/scene/poly_cull.h +++ b/src/polyrenderer/scene/poly_cull.h @@ -23,13 +23,12 @@ #pragma once #include "polyrenderer/drawers/poly_triangle.h" -#include "polyrenderer/math/poly_intersection.h" class PolyCull { public: void ClearSolidSegments(); - void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane); + void CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane); bool GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const; void MarkSegmentCulled(angle_t angle1, angle_t angle2); @@ -61,8 +60,7 @@ private: const int SolidCullScale = 3000; bool FirstSkyHeight = true; - FrustumPlanes frustumPlanes; - Vec4f PortalClipPlane; + PolyClipPlane PortalClipPlane; static angle_t PointToPseudoAngle(double x, double y); static angle_t AngleToPseudo(angle_t ang); diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index 0759ac64d..829f444b6 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -31,7 +31,7 @@ #include "a_sharedglobal.h" #include "swrenderer/scene/r_scene.h" -void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) +void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) { if (line->linedef == nullptr && line->sidedef == nullptr) return; @@ -43,7 +43,7 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f } } -void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) +void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) { if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid()) return; @@ -130,49 +130,21 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan } bool fullbrightSprite = (decal->RenderFlags & RF_FULLBRIGHT) == RF_FULLBRIGHT; - - PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + int lightlevel = fullbrightSprite ? 255 : front->lightlevel + actualextralight; PolyDrawArgs args; - args.uniforms.flags = TriUniforms::nearest_filter; - args.SetColormap(GetColorTable(front->Colormap)); + args.SetLight(GetColorTable(front->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite); args.SetTexture(tex, decal->Translation, true); - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); - if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - { - args.uniforms.light = 256; - args.uniforms.flags |= TriUniforms::fixed_light; - } - else - { - args.uniforms.light = (uint32_t)((front->lightlevel + actualextralight) / 255.0f * 256.0f); - } - args.uniforms.subsectorDepth = subsectorDepth; - - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) - { - args.uniforms.color = 0xff000000 | decal->AlphaColor; - } - else - { - args.uniforms.color = ((uint32_t)decal->AlphaColor) >> 24; - } - - args.uniforms.srcalpha = (uint32_t)(decal->Alpha * 256.0 + 0.5); - args.uniforms.destalpha = 256 - args.uniforms.srcalpha; - - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = 4; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue; - //mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); - args.blendmode = TriBlendMode::Shaded; - args.subsectorTest = true; - args.writeStencil = false; - args.writeSubsector = false; - PolyTriangleDrawer::draw(args); + args.SetSubsectorDepth(subsectorDepth); + args.SetColor(0xff000000 | decal->AlphaColor, decal->AlphaColor >> 24); + args.SetStyle(TriBlendMode::Shaded, decal->Alpha, 1.0 - decal->Alpha); // R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(stencilValue); + args.SetWriteStencil(true, stencilValue); + args.SetClipPlane(clipPlane); + args.SetSubsectorDepthTest(true); + args.SetWriteStencil(false); + args.SetWriteSubsectorDepth(false); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_decal.h b/src/polyrenderer/scene/poly_decal.h index 48907780a..a0d676951 100644 --- a/src/polyrenderer/scene/poly_decal.h +++ b/src/polyrenderer/scene/poly_decal.h @@ -24,13 +24,11 @@ #include "polyrenderer/drawers/poly_triangle.h" -class Vec4f; - class RenderPolyDecal { public: - static void RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); + static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); private: - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); }; diff --git a/src/polyrenderer/scene/poly_light.cpp b/src/polyrenderer/scene/poly_light.cpp index 5de6756d7..92c74e469 100644 --- a/src/polyrenderer/scene/poly_light.cpp +++ b/src/polyrenderer/scene/poly_light.cpp @@ -25,6 +25,7 @@ #include "doomdef.h" #include "sbar.h" #include "poly_light.h" +#include "polyrenderer/poly_renderer.h" fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) { @@ -41,3 +42,8 @@ fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128)); } } + +double PolyLightVisibility::FocalTangent() +{ + return PolyRenderer::Instance()->Viewwindow.FocalTangent; +} diff --git a/src/polyrenderer/scene/poly_light.h b/src/polyrenderer/scene/poly_light.h index 9644387e7..dcb397cb8 100644 --- a/src/polyrenderer/scene/poly_light.h +++ b/src/polyrenderer/scene/poly_light.h @@ -31,9 +31,9 @@ typedef swrenderer::CameraLight PolyCameraLight; class PolyLightVisibility { public: - double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } - double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } - double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); } + double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); } + double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); } + double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility * 0.5 / FocalTangent(); } // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } @@ -43,6 +43,8 @@ public: static fixed_t LightLevelToShade(int lightlevel, bool foggy); private: + static double FocalTangent(); + // 1706 is the value for walls on 1080p 16:9 displays. double WallVisibility = 1706.0; bool NoLightFade = false; diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 8d09be467..d4a49334b 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -29,7 +29,7 @@ #include "polyrenderer/poly_renderer.h" #include "polyrenderer/scene/poly_light.h" -void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) +void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) { DVector3 pos = particle->Pos; double psize = particle->size / 8.0; @@ -68,51 +68,20 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipP vertices[i].varying[1] = (float)(1.0f - offsets[i].second); } - // int color = (particle->color >> 24) & 0xff; // pal index, I think bool fullbrightSprite = particle->bright != 0; - PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + int lightlevel = fullbrightSprite ? 255 : sub->sector->lightlevel + actualextralight; PolyDrawArgs args; - - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.ParticleGlobVis(foggy); - - if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - { - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter; - } - else - { - args.uniforms.light = (uint32_t)((sub->sector->lightlevel + actualextralight) / 255.0f * 256.0f); - args.uniforms.flags = TriUniforms::nearest_filter; - } - args.uniforms.subsectorDepth = subsectorDepth; - - uint32_t alpha = (uint32_t)clamp(particle->alpha * 255.0f + 0.5f, 0.0f, 255.0f); - - if (PolyRenderer::Instance()->RenderTarget->IsBgra()) - { - args.uniforms.color = (alpha << 24) | (particle->color & 0xffffff); - } - else - { - args.uniforms.color = ((uint32_t)particle->color) >> 24; - args.uniforms.srcalpha = alpha; - args.uniforms.destalpha = 255 - alpha; - } - - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = 4; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue; - args.SetColormap(GetColorTable(sub->sector->Colormap)); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); - args.subsectorTest = true; - args.writeStencil = false; - args.writeSubsector = false; - args.blendmode = TriBlendMode::AlphaBlend; - PolyTriangleDrawer::draw(args); + args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.ParticleGlobVis(foggy), fullbrightSprite); + args.SetSubsectorDepth(subsectorDepth); + args.SetSubsectorDepthTest(true); + args.SetColor(particle->color | 0xff000000, particle->color >> 24); + args.SetStyle(TriBlendMode::AlphaBlend, particle->alpha, 1.0 - particle->alpha); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(stencilValue); + args.SetWriteStencil(false); + args.SetWriteSubsectorDepth(false); + args.SetClipPlane(clipPlane); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_particle.h b/src/polyrenderer/scene/poly_particle.h index b3b25b996..e91174591 100644 --- a/src/polyrenderer/scene/poly_particle.h +++ b/src/polyrenderer/scene/poly_particle.h @@ -25,10 +25,8 @@ #include "polyrenderer/drawers/poly_triangle.h" #include "p_effect.h" -class Vec4f; - class RenderPolyParticle { public: - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); }; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 03ea75b37..d41328d57 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -33,7 +33,7 @@ EXTERN_CVAR(Int, r_3dfloors) -void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals) +void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals) { RenderPolyPlane plane; @@ -91,7 +91,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &cl plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals); } -void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor) +void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor) { FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture; FTexture *tex = TexMan(picnum); @@ -111,16 +111,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c UVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex); - PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); // .SlopePlaneGlobVis(foggy) * 48.0f; - args.uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f); - if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::nearest_filter; - args.uniforms.subsectorDepth = subsectorDepth; - TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory(sub->numlines); - if (ceiling) { for (uint32_t i = 0; i < sub->numlines; i++) @@ -138,21 +129,20 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c } } - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = sub->numlines; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue + 1; + PolyDrawArgs args; + args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); + args.SetSubsectorDepth(subsectorDepth); + args.SetTransform(&worldToClip); + args.SetStyle(TriBlendMode::Copy); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(stencilValue); + args.SetWriteStencil(true, stencilValue + 1); args.SetTexture(tex); - args.SetColormap(GetColorTable(sub->sector->Colormap)); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); - args.blendmode = TriBlendMode::Copy; - PolyTriangleDrawer::draw(args); + args.SetClipPlane(clipPlane); + args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan); } -void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals) +void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; bool foggy = false; @@ -291,16 +281,6 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan UVTransform transform(ceiling ? frontsector->planes[sector_t::ceiling].xform : frontsector->planes[sector_t::floor].xform, tex); - PolyCameraLight *cameraLight = PolyCameraLight::Instance(); - - PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);// ->SlopePlaneGlobVis(foggy) * 48.0f; - args.uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f); - if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::nearest_filter; - args.uniforms.subsectorDepth = isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth; - TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory(sub->numlines); if (ceiling) @@ -320,37 +300,36 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan } } - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = sub->numlines; - args.mode = TriangleDrawMode::Fan; - args.ccw = ccw; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue + 1; - args.SetColormap(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling])); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); + PolyDrawArgs args; + args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]), frontsector->lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); + args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(ccw); + args.SetStencilTestValue(stencilValue); + args.SetWriteStencil(true, stencilValue + 1); + args.SetClipPlane(clipPlane); if (!isSky) { args.SetTexture(tex); - args.blendmode = TriBlendMode::Copy; - PolyTriangleDrawer::draw(args); + args.SetStyle(TriBlendMode::Copy); + args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan); } else { if (portal) { - args.stencilwritevalue = polyportal->StencilValue; - polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth }); + args.SetWriteStencil(true, polyportal->StencilValue); + polyportal->Shape.push_back({ vertices, (int)sub->numlines, ccw, subsectorDepth }); } else { - args.stencilwritevalue = 255; + args.SetWriteStencil(true, 255); } - args.writeColor = false; - args.writeSubsector = false; - PolyTriangleDrawer::draw(args); + args.SetWriteColor(false); + args.SetWriteSubsectorDepth(false); + args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan); for (uint32_t i = 0; i < sub->numlines; i++) { @@ -414,13 +393,11 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan wallvert[3] = PlaneVertex(line->v1, skyHeight, transform); } - args.vinput = wallvert; - args.vcount = 4; - PolyTriangleDrawer::draw(args); + args.DrawArray(wallvert, 4, PolyDrawMode::TriangleFan); if (portal) { - polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth }); + polyportal->Shape.push_back({ wallvert, 4, ccw, subsectorDepth }); } } } diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h index bf844dcc2..ce2192594 100644 --- a/src/polyrenderer/scene/poly_plane.h +++ b/src/polyrenderer/scene/poly_plane.h @@ -26,12 +26,11 @@ class PolyDrawSectorPortal; class PolyCull; -class Vec4f; class RenderPolyPlane { public: - static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals); + static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals); private: struct UVTransform @@ -48,7 +47,7 @@ private: float xOffs, yOffs; }; - void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor); - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals); + void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals); TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform); }; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 21db4b7cd..9920d2dc9 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -28,7 +28,6 @@ #include "poly_playersprite.h" #include "polyrenderer/poly_renderer.h" #include "d_player.h" -#include "swrenderer/viewport/r_viewport.h" #include "polyrenderer/scene/poly_light.h" EXTERN_CVAR(Bool, r_drawplayersprites) @@ -44,6 +43,14 @@ void RenderPolyPlayerSprites::Render() const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; + int i; + int lightnum; + DPSprite* psp; + DPSprite* weapon; + sector_t* sec = nullptr; + int floorlight, ceilinglight; + F3DFloor *rover; + if (!r_drawplayersprites || !viewpoint.camera || !viewpoint.camera->player || @@ -51,282 +58,427 @@ void RenderPolyPlayerSprites::Render() (r_deathcamera && viewpoint.camera->health <= 0)) return; - float bobx, boby; - P_BobWeapon(viewpoint.camera->player, &bobx, &boby, viewpoint.TicFrac); - - // Interpolate the main weapon layer once so as to be able to add it to other layers. - double wx, wy; - DPSprite *weapon = viewpoint.camera->player->FindPSprite(PSP_WEAPON); - if (weapon) + FDynamicColormap *basecolormap; + PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + if (cameraLight->FixedLightLevel() < 0 && viewpoint.sector->e && viewpoint.sector->e->XFloor.lightlist.Size()) { - if (weapon->firstTic) + for (i = viewpoint.sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) { - wx = weapon->x; - wy = weapon->y; + if (viewpoint.Pos.Z <= viewpoint.sector->e->XFloor.lightlist[i].plane.Zat0()) + { + rover = viewpoint.sector->e->XFloor.lightlist[i].caster; + if (rover) + { + if (rover->flags & FF_DOUBLESHADOW && viewpoint.Pos.Z <= rover->bottom.plane->Zat0()) + break; + sec = rover->model; + if (rover->flags & FF_FADEWALLS) + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true); + else + basecolormap = GetColorTable(viewpoint.sector->e->XFloor.lightlist[i].extra_colormap, sec->SpecialColors[sector_t::sprites], true); + } + break; + } + } + if (!sec) + { + sec = viewpoint.sector; + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true); + } + floorlight = ceilinglight = sec->lightlevel; + } + else + { // This used to use camera->Sector but due to interpolation that can be incorrect + // when the interpolated viewpoint is in a different sector than the camera. + //sec = FakeFlat(viewpoint.sector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0); + // Softpoly has no FakeFlat (its FAKE! Everything is FAKE in Doom. Sigh. Might as well call it FooFlat!) + sec = viewpoint.camera->Sector; + floorlight = ceilinglight = sec->lightlevel; + + // [RH] set basecolormap + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true); + } + + // [RH] set foggy flag + bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); + + // get light level + lightnum = ((floorlight + ceilinglight) >> 1) + (foggy ? 0 : viewpoint.extralight << 4); + int spriteshade = LightLevelToShade(lightnum, foggy) - 24 * FRACUNIT; + + if (viewpoint.camera->player != nullptr) + { + double wx, wy; + float bobx, boby; + + P_BobWeapon(viewpoint.camera->player, &bobx, &boby, viewpoint.TicFrac); + + // Interpolate the main weapon layer once so as to be able to add it to other layers. + if ((weapon = viewpoint.camera->player->FindPSprite(PSP_WEAPON)) != nullptr) + { + if (weapon->firstTic) + { + wx = weapon->x; + wy = weapon->y; + } + else + { + wx = weapon->oldx + (weapon->x - weapon->oldx) * viewpoint.TicFrac; + wy = weapon->oldy + (weapon->y - weapon->oldy) * viewpoint.TicFrac; + } } else { - wx = weapon->oldx + (weapon->x - weapon->oldx) * viewpoint.TicFrac; - wy = weapon->oldy + (weapon->y - weapon->oldy) * viewpoint.TicFrac; + wx = 0; + wy = 0; } - } - else - { - wx = 0; - wy = 0; - } - for (DPSprite *sprite = viewpoint.camera->player->psprites; sprite != nullptr; sprite = sprite->GetNext()) - { - // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. - // It's possible this psprite's caller is now null but the layer itself hasn't been destroyed - // because it didn't tick yet (if we typed 'take all' while in the console for example). - // In this case let's simply not draw it to avoid crashing. - if ((sprite->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && sprite->GetCaller() != nullptr) + // add all active psprites + psp = viewpoint.camera->player->psprites; + while (psp) { - RenderSprite(sprite, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac); + // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. + // It's possible this psprite's caller is now null but the layer itself hasn't been destroyed + // because it didn't tick yet (if we typed 'take all' while in the console for example). + // In this case let's simply not draw it to avoid crashing. + + if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr) + { + RenderSprite(psp, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac, spriteshade, basecolormap, foggy); + } + + psp = psp->GetNext(); } } } void RenderPolyPlayerSprites::RenderRemainingSprites() { - for (auto &sprite : ScreenSprites) - sprite.Render(); - ScreenSprites.clear(); + for (const PolyHWAccelPlayerSprite &sprite : AcceleratedSprites) + { + screen->DrawTexture(sprite.pic, + viewwindowx + sprite.x1, + viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5, + DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale), + DTA_DestHeightF, sprite.pic->GetHeight() * sprite.yscale, + DTA_TranslationIndex, sprite.Translation, + DTA_FlipX, sprite.flip, + DTA_TopOffset, 0, + DTA_LeftOffset, 0, + DTA_ClipLeft, viewwindowx, + DTA_ClipTop, viewwindowy, + DTA_ClipRight, viewwindowx + viewwidth, + DTA_ClipBottom, viewwindowy + viewheight, + DTA_Alpha, sprite.Alpha, + DTA_RenderStyle, sprite.RenderStyle, + DTA_FillColor, sprite.FillColor, + DTA_SpecialColormap, sprite.special, + DTA_ColorOverlay, sprite.overlay.d, + DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr, + TAG_DONE); + } + + AcceleratedSprites.Clear(); } -void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac) +void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy) { + double tx; + int x1; + int x2; + double sx, sy; + spritedef_t* sprdef; + spriteframe_t* sprframe; + FTextureID picnum; + uint16_t flip; + FTexture* tex; + bool noaccel; + double alpha = owner->Alpha; + // decide which patch to use - if ((unsigned)sprite->GetSprite() >= (unsigned)sprites.Size()) + if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size()) { - DPrintf(DMSG_ERROR, "RenderPlayerSprite: invalid sprite number %i\n", sprite->GetSprite()); + DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite number %i\n", pspr->GetSprite()); + return; + } + sprdef = &sprites[pspr->GetSprite()]; + if (pspr->GetFrame() >= sprdef->numframes) + { + DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite frame %i : %i\n", pspr->GetSprite(), pspr->GetFrame()); return; } - spritedef_t *def = &sprites[sprite->GetSprite()]; - if (sprite->GetFrame() >= def->numframes) - { - DPrintf(DMSG_ERROR, "RenderPlayerSprite: invalid sprite frame %i : %i\n", sprite->GetSprite(), sprite->GetFrame()); - return; - } + const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; + const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; + DCanvas *renderTarget = PolyRenderer::Instance()->RenderTarget; - spriteframe_t *frame = &SpriteFrames[def->spriteframes + sprite->GetFrame()]; - FTextureID picnum = frame->Texture[0]; - bool flip = (frame->Flip & 1) != 0; + sprframe = &SpriteFrames[sprdef->spriteframes + pspr->GetFrame()]; - FTexture *tex = TexMan(picnum); - if (tex->UseType == FTexture::TEX_Null) + picnum = sprframe->Texture[0]; + flip = sprframe->Flip & 1; + tex = TexMan(picnum); + + if (tex->UseType == FTexture::TEX_Null || pspr->RenderStyle == STYLE_None) return; - // Can't interpolate the first tic. - if (sprite->firstTic) - { - sprite->firstTic = false; - sprite->oldx = sprite->x; - sprite->oldy = sprite->y; + if (pspr->firstTic) + { // Can't interpolate the first tic. + pspr->firstTic = false; + pspr->oldx = pspr->x; + pspr->oldy = pspr->y; } - double sx = sprite->oldx + (sprite->x - sprite->oldx) * ticfrac; - double sy = sprite->oldy + (sprite->y - sprite->oldy) * ticfrac; + sx = pspr->oldx + (pspr->x - pspr->oldx) * ticfrac; + sy = pspr->oldy + (pspr->y - pspr->oldy) * ticfrac + WEAPON_FUDGE_Y; - if (sprite->Flags & PSPF_ADDBOB) + if (pspr->Flags & PSPF_ADDBOB) { sx += bobx; sy += boby; } - if (sprite->Flags & PSPF_ADDWEAPON && sprite->GetID() != PSP_WEAPON) + if (pspr->Flags & PSPF_ADDWEAPON && pspr->GetID() != PSP_WEAPON) { sx += wx; sy += wy; } - - const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; - auto renderTarget = PolyRenderer::Instance()->RenderTarget; - double YaspectMul = 1.2f; - double pspritexscale = PolyRenderer::Instance()->Viewwindow.centerxwide / 160.0; - double pspriteyscale = pspritexscale * YaspectMul; + double yaspectMul = 1.2;// 320.0 * SCREENHEIGHT / (r_Yaspect * SCREENWIDTH); + + double pspritexscale = viewwindow.centerxwide / 160.0; + double pspriteyscale = pspritexscale * yaspectMul; double pspritexiscale = 1 / pspritexscale; // calculate edges of the shape - double tx = sx - BaseXCenter; + tx = sx - BASEXCENTER; tx -= tex->GetScaledLeftOffset(); - int x1 = xs_RoundToInt(renderTarget->GetWidth() * 0.5 + tx * pspritexscale); + x1 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale); // off the right side if (x1 > viewwidth) return; tx += tex->GetScaledWidth(); - int x2 = xs_RoundToInt(renderTarget->GetWidth() * 0.5 + tx * pspritexscale); + x2 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale); // off the left side if (x2 <= 0) return; - double texturemid = (BaseYCenter - sy) * tex->Scale.Y + tex->TopOffset; + // store information in a vissprite + PolyNoAccelPlayerSprite vis; - // Adjust PSprite for fullscreen views - if (viewpoint.camera->player && (renderTarget != screen || viewheight == renderTarget->GetHeight() || (renderTarget->GetWidth() > (BaseXCenter * 2) && !st_scale))) - { - AWeapon *weapon = dyn_cast(sprite->GetCaller()); + vis.renderflags = owner->renderflags; + + vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; + + if (viewpoint.camera->player && (renderTarget != screen || + viewheight == renderTarget->GetHeight() || + (renderTarget->GetWidth() > (BASEXCENTER * 2) && !st_scale))) + { // Adjust PSprite for fullscreen views + AWeapon *weapon = dyn_cast(pspr->GetCaller()); if (weapon != nullptr && weapon->YAdjust != 0) { if (renderTarget != screen || viewheight == renderTarget->GetHeight()) { - texturemid -= weapon->YAdjust; + vis.texturemid -= weapon->YAdjust; } else { - texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust; + vis.texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust; } } } - - // Move the weapon down for 1280x1024. - if (sprite->GetID() < PSP_TARGETCENTER) - { - texturemid -= AspectPspriteOffset(PolyRenderer::Instance()->Viewwindow.WidescreenRatio); + if (pspr->GetID() < PSP_TARGETCENTER) + { // Move the weapon down for 1280x1024. + vis.texturemid -= AspectPspriteOffset(viewwindow.WidescreenRatio); } + vis.x1 = x1 < 0 ? 0 : x1; + vis.x2 = x2 >= viewwidth ? viewwidth : x2; + vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); + vis.yscale = float(pspriteyscale / tex->Scale.Y); + vis.pic = tex; - int clipped_x1 = MAX(x1, 0); - int clipped_x2 = MIN(x2, viewwidth); - double xscale = pspritexscale / tex->Scale.X; - double yscale = pspriteyscale / tex->Scale.Y; - uint32_t translation = 0; // [RH] Use default colors - - double xiscale, startfrac; - if (flip) + // If flip is used, provided that it's not already flipped (that would just invert itself) + // (It's an XOR...) + if (!(flip) != !(pspr->Flags & PSPF_FLIP)) { - xiscale = -pspritexiscale * tex->Scale.X; - startfrac = 1; + vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X); + vis.startfrac = (tex->GetWidth() << FRACBITS) - 1; } else { - xiscale = pspritexiscale * tex->Scale.X; - startfrac = 0; + vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X); + vis.startfrac = 0; } - if (clipped_x1 > x1) - startfrac += xiscale * (clipped_x1 - x1); + if (vis.x1 > x1) + vis.startfrac += vis.xiscale*(vis.x1 - x1); - bool noaccel = false; - - FDynamicColormap *basecolormap = GetColorTable(viewpoint.sector->Colormap, viewpoint.sector->SpecialColors[sector_t::sprites], true); - FDynamicColormap *colormap_to_use = basecolormap; - - int ColormapNum = 0; - FSWColormap *BaseColormap = basecolormap; - float Alpha = 0; - FRenderStyle RenderStyle; - RenderStyle = STYLE_Normal; - - bool foggy = false; - int actualextralight = foggy ? 0 : viewpoint.extralight << 4; - int spriteshade = PolyLightVisibility::LightLevelToShade(owner->Sector->lightlevel + actualextralight, foggy); - double minz = double((2048 * 4) / double(1 << 20)); - ColormapNum = GETPALOOKUP(PolyRenderer::Instance()->Light.SpriteGlobVis(foggy) / minz, spriteshade); - - if (sprite->GetID() < PSP_TARGETCENTER) + noaccel = false; + FDynamicColormap *colormap_to_use = nullptr; + if (pspr->GetID() < PSP_TARGETCENTER) { - Alpha = float(owner->Alpha); - RenderStyle = owner->RenderStyle; + // [MC] Set the render style + + if (pspr->Flags & PSPF_RENDERSTYLE) + { + const int rs = clamp(pspr->RenderStyle, 0, STYLE_Count); + + if (pspr->Flags & PSPF_FORCESTYLE) + { + vis.RenderStyle = LegacyRenderStyles[rs]; + } + else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy]) + { + vis.RenderStyle = LegacyRenderStyles[STYLE_Fuzzy]; + } + else if (owner->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]) + { + vis.RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy]; + vis.RenderStyle.CheckFuzz(); + } + else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) + { + vis.RenderStyle = LegacyRenderStyles[STYLE_Subtract]; + } + else + { + vis.RenderStyle = LegacyRenderStyles[rs]; + } + } + else + { + vis.RenderStyle = owner->RenderStyle; + } + + // Set the alpha based on if using the overlay's own or not. Also adjust + // and override the alpha if not forced. + if (pspr->Flags & PSPF_ALPHA) + { + if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy]) + { + alpha = owner->Alpha; + } + else if (vis.RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]) + { + FRenderStyle style = vis.RenderStyle; + style.CheckFuzz(); + switch (style.BlendOp) + { + default: + alpha = pspr->alpha * owner->Alpha; + break; + case STYLEOP_Fuzz: + case STYLEOP_Sub: + alpha = owner->Alpha; + break; + } + + } + else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Subtract]) + { + alpha = owner->Alpha; + } + else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Add] || + vis.RenderStyle == LegacyRenderStyles[STYLE_Translucent] || + vis.RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] || + vis.RenderStyle == LegacyRenderStyles[STYLE_AddStencil] || + vis.RenderStyle == LegacyRenderStyles[STYLE_AddShaded]) + { + alpha = owner->Alpha * pspr->alpha; + } + else + { + alpha = owner->Alpha; + } + } + + // Should normal renderstyle come out on top at the end and we desire alpha, + // switch it to translucent. Normal never applies any sort of alpha. + if ((pspr->Flags & PSPF_ALPHA) && + vis.RenderStyle == LegacyRenderStyles[STYLE_Normal] && + vis.Alpha < 1.0) + { + vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; + alpha = owner->Alpha * pspr->alpha; + } + + // ALWAYS take priority if asked for, except fuzz. Fuzz does absolutely nothing + // no matter what way it's changed. + if (pspr->Flags & PSPF_FORCEALPHA) + { + //Due to lack of != operators... + if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] || + vis.RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] || + vis.RenderStyle == LegacyRenderStyles[STYLE_Stencil]) + { + } + else + { + alpha = pspr->alpha; + vis.RenderStyle.Flags |= STYLEF_ForceAlpha; + } + } + vis.Alpha = clamp(float(alpha), 0.f, 1.f); + + // Due to how some of the effects are handled, going to 0 or less causes some + // weirdness to display. There's no point rendering it anyway if it's 0. + if (vis.Alpha <= 0.) + return; + + //----------------------------------------------------------------------------- // The software renderer cannot invert the source without inverting the overlay // too. That means if the source is inverted, we need to do the reverse of what // the invert overlay flag says to do. - INTBOOL invertcolormap = (RenderStyle.Flags & STYLEF_InvertOverlay); + bool invertcolormap = (vis.RenderStyle.Flags & STYLEF_InvertOverlay) != 0; - if (RenderStyle.Flags & STYLEF_InvertSource) + if (vis.RenderStyle.Flags & STYLEF_InvertSource) { invertcolormap = !invertcolormap; } - FDynamicColormap *mybasecolormap = basecolormap; + bool fullbright = !foggy && pspr->GetState()->GetFullbright(); + bool fadeToBlack = (vis.RenderStyle.Flags & STYLEF_FadeToBlack) != 0; - if (RenderStyle.Flags & STYLEF_FadeToBlack) - { - if (invertcolormap) - { // Fade to white - mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255, 255, 255), mybasecolormap->Desaturate); - invertcolormap = false; - } - else - { // Fade to black - mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0, 0, 0), mybasecolormap->Desaturate); - } - } + vis.Light.SetColormap(0, spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); - /* - if (realfixedcolormap != nullptr && (!r_swtruecolor || (r_shadercolormaps && screen->Accel2D))) - { // fixed color - BaseColormap = realfixedcolormap; - ColormapNum = 0; - } - else - { - if (invertcolormap) - { - mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate); - } - if (fixedlightlev >= 0) - { - BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap; - ColormapNum = fixedlightlev >> COLORMAPSHIFT; - } - else if (!foggy && sprite->GetState()->GetFullbright()) - { // full bright - BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap; // [RH] use basecolormap - ColormapNum = 0; - } - else - { // local light - BaseColormap = mybasecolormap; - ColormapNum = GETPALOOKUP(0, spriteshade); - } - } - */ + colormap_to_use = (FDynamicColormap*)vis.Light.BaseColormap; if (viewpoint.camera->Inventory != nullptr) { visstyle_t visstyle; - visstyle.Alpha = Alpha; + visstyle.Alpha = vis.Alpha; visstyle.RenderStyle = STYLE_Count; visstyle.Invert = false; viewpoint.camera->Inventory->AlterWeaponSprite(&visstyle); - Alpha = visstyle.Alpha; + vis.Alpha = visstyle.Alpha; if (visstyle.RenderStyle != STYLE_Count) { - RenderStyle = visstyle.RenderStyle; + vis.RenderStyle = visstyle.RenderStyle; } if (visstyle.Invert) { - BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP]; - ColormapNum = 0; - if (BaseColormap->Maps < mybasecolormap->Maps || BaseColormap->Maps >= mybasecolormap->Maps + NUMCOLORMAPS * 256) - { - noaccel = true; - } + vis.Light.BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP]; + vis.Light.ColormapNum = 0; + noaccel = true; } } - // If we're drawing with a special colormap, but shaders for them are disabled, do // not accelerate. - if (!r_shadercolormaps && (BaseColormap >= &SpecialSWColormaps[0] && - BaseColormap <= &SpecialSWColormaps.Last())) + if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && + vis.Light.BaseColormap <= &SpecialSWColormaps.Last())) { noaccel = true; } // If drawing with a BOOM colormap, disable acceleration. - if (mybasecolormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps) + if (vis.Light.BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps) { noaccel = true; } @@ -334,116 +486,185 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa // colormap, disable acceleration so that the lights can remain fixed. PolyCameraLight *cameraLight = PolyCameraLight::Instance(); if (!noaccel && cameraLight->ShaderColormap() == nullptr && - NormalLightHasFixedLights && mybasecolormap == &NormalLight && - tex->UseBasePalette()) + NormalLightHasFixedLights && vis.Light.BaseColormap == &NormalLight && + vis.pic->UseBasePalette()) { noaccel = true; } - // [SP] If emulating GZDoom fullbright, disable acceleration - if (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0) - mybasecolormap = &FullNormalLight; - if (r_fullbrightignoresectorcolor && !foggy && sprite->GetState()->GetFullbright()) - mybasecolormap = &FullNormalLight; - colormap_to_use = mybasecolormap; + } + else + { + colormap_to_use = basecolormap; + + vis.Light.BaseColormap = basecolormap; + vis.Light.ColormapNum = 0; } // Check for hardware-assisted 2D. If it's available, and this sprite is not // fuzzy, don't draw it until after the switch to 2D mode. if (!noaccel && renderTarget == screen && (DFrameBuffer *)screen->Accel2D) { - FRenderStyle style = RenderStyle; + FRenderStyle style = vis.RenderStyle; style.CheckFuzz(); if (style.BlendOp != STYLEOP_Fuzz) { - PolyScreenSprite screenSprite; - screenSprite.Pic = tex; - screenSprite.X1 = viewwindowx + x1; - screenSprite.Y1 = viewwindowy + viewheight / 2 - texturemid * yscale - 0.5; - screenSprite.Width = tex->GetWidth() * xscale; - screenSprite.Height = tex->GetHeight() * yscale; - screenSprite.Translation = TranslationToTable(translation); - //screenSprite.Translation = translation; - screenSprite.Flip = xiscale < 0; - screenSprite.Alpha = Alpha; - screenSprite.RenderStyle = RenderStyle; - screenSprite.BaseColormap = BaseColormap; - screenSprite.ColormapNum = ColormapNum; - screenSprite.Colormap = colormap_to_use; - ScreenSprites.push_back(screenSprite); + PolyHWAccelPlayerSprite accelSprite; + + accelSprite.pic = vis.pic; + accelSprite.texturemid = vis.texturemid; + accelSprite.yscale = vis.yscale; + accelSprite.xscale = vis.xscale; + + accelSprite.Alpha = vis.Alpha; + accelSprite.RenderStyle = vis.RenderStyle; + accelSprite.Translation = vis.Translation; + accelSprite.FillColor = vis.FillColor; + + accelSprite.basecolormap = colormap_to_use; + accelSprite.x1 = x1; + accelSprite.flip = vis.xiscale < 0; + + if (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && + vis.Light.BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()]) + { + accelSprite.special = &SpecialColormaps[vis.Light.BaseColormap - &SpecialSWColormaps[0]]; + } + else if (PolyCameraLight::Instance()->ShaderColormap()) + { + accelSprite.special = PolyCameraLight::Instance()->ShaderColormap(); + } + else if (colormap_to_use->Color == PalEntry(255, 255, 255) && + colormap_to_use->Desaturate == 0) + { + accelSprite.overlay = colormap_to_use->Fade; + accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS); + } + else + { + accelSprite.usecolormapstyle = true; + accelSprite.colormapstyle.Color = colormap_to_use->Color; + accelSprite.colormapstyle.Fade = colormap_to_use->Fade; + accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate; + accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS); + } + + AcceleratedSprites.Push(accelSprite); return; } } - // To do: draw sprite same way as R_DrawVisSprite(vis) here - - // Draw the fuzzy weapon: - FRenderStyle style = RenderStyle; - style.CheckFuzz(); - if (style.BlendOp == STYLEOP_Fuzz) - { - RenderStyle = LegacyRenderStyles[STYLE_Shadow]; - - PolyScreenSprite screenSprite; - screenSprite.Pic = tex; - screenSprite.X1 = viewwindowx + x1; - screenSprite.Y1 = viewwindowy + viewheight / 2 - texturemid * yscale - 0.5; - screenSprite.Width = tex->GetWidth() * xscale; - screenSprite.Height = tex->GetHeight() * yscale; - screenSprite.Translation = TranslationToTable(translation); - screenSprite.Flip = xiscale < 0; - screenSprite.Alpha = Alpha; - screenSprite.RenderStyle = RenderStyle; - screenSprite.BaseColormap = BaseColormap; - screenSprite.ColormapNum = ColormapNum; - screenSprite.Colormap = colormap_to_use; - ScreenSprites.push_back(screenSprite); - } + vis.Render(); } -void PolyScreenSprite::Render() +fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy) { - FSpecialColormap *special = nullptr; - FColormapStyle colormapstyle; - PalEntry overlay = 0; - bool usecolormapstyle = false; - if (BaseColormap >= &SpecialSWColormaps[0] && - BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()]) + bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); + if (nolightfade) { - special = &SpecialColormaps[BaseColormap - &SpecialSWColormaps[0]]; - } - else if (Colormap->Color == PalEntry(255, 255, 255) && - Colormap->Desaturate == 0) - { - overlay = Colormap->Fade; - overlay.a = uint8_t(ColormapNum * 255 / NUMCOLORMAPS); + return (MAX(255 - lightlevel, 0) * NUMCOLORMAPS) << (FRACBITS - 8); } else { - usecolormapstyle = true; - colormapstyle.Color = Colormap->Color; - colormapstyle.Fade = Colormap->Fade; - colormapstyle.Desaturate = Colormap->Desaturate; - colormapstyle.FadeLevel = ColormapNum / float(NUMCOLORMAPS); + // Convert a light level into an unbounded colormap index (shade). Result is + // fixed point. Why the +12? I wish I knew, but experimentation indicates it + // is necessary in order to best reproduce Doom's original lighting. + return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128)); + } +} + +///////////////////////////////////////////////////////////////////////// + +void PolyNoAccelPlayerSprite::Render() +{ +#if 0 + if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f)) + { // scaled to 0; can't see + return; } - screen->DrawTexture(Pic, - X1, - Y1, - DTA_DestWidthF, Width, - DTA_DestHeightF, Height, - DTA_TranslationIndex, Translation, - DTA_FlipX, Flip, - DTA_TopOffset, 0, - DTA_LeftOffset, 0, - DTA_ClipLeft, viewwindowx, - DTA_ClipTop, viewwindowy, - DTA_ClipRight, viewwindowx + viewwidth, - DTA_ClipBottom, viewwindowy + viewheight, - DTA_Alpha, Alpha, - DTA_RenderStyle, RenderStyle, - DTA_FillColor, FillColor, - DTA_SpecialColormap, special, - DTA_ColorOverlay, overlay.d, - DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : nullptr, - TAG_DONE); + SpriteDrawerArgs drawerargs; + drawerargs.SetLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS); + + FDynamicColormap *basecolormap = static_cast(Light.BaseColormap); + + bool visible = drawerargs.SetStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap, Light.ColormapNum << FRACBITS); + if (!visible) + return; + + double spryscale = yscale; + bool sprflipvert = false; + fixed_t iscale = FLOAT2FIXED(1 / yscale); + + double centerY = viewheight / 2; + + double sprtopscreen; + if (renderflags & RF_YFLIP) + { + sprflipvert = true; + spryscale = -spryscale; + iscale = -iscale; + sprtopscreen = centerY + (texturemid - pic->GetHeight()) * spryscale; + } + else + { + sprflipvert = false; + sprtopscreen = centerY - texturemid * spryscale; + } + + // clip to screen bounds + short *mfloorclip = screenheightarray; + short *mceilingclip = zeroarray; + + fixed_t frac = startfrac; + for (int x = x1; x < x2; x++) + { + drawerargs.DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); + frac += xiscale; + } +#endif +} + +///////////////////////////////////////////////////////////////////////////// + +void PolyColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack) +{ + if (fadeToBlack) + { + if (invertColormap) // Fade to white + { + basecolormap = GetSpecialLights(basecolormap->Color, MAKERGB(255, 255, 255), basecolormap->Desaturate); + invertColormap = false; + } + else // Fade to black + { + basecolormap = GetSpecialLights(basecolormap->Color, MAKERGB(0, 0, 0), basecolormap->Desaturate); + } + } + + if (invertColormap) + { + basecolormap = GetSpecialLights(basecolormap->Color, basecolormap->Fade.InverseColor(), basecolormap->Desaturate); + } + + PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + if (cameraLight->FixedColormap()) + { + BaseColormap = cameraLight->FixedColormap(); + ColormapNum = 0; + } + else if (cameraLight->FixedLightLevel() >= 0) + { + BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap; + ColormapNum = cameraLight->FixedLightLevel() >> COLORMAPSHIFT; + } + else if (fullbright) + { + BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap; + ColormapNum = 0; + } + else + { + BaseColormap = basecolormap; + ColormapNum = GETPALOOKUP(visibility, shade); + } } diff --git a/src/polyrenderer/scene/poly_playersprite.h b/src/polyrenderer/scene/poly_playersprite.h index 97c6e6118..3f1260d48 100644 --- a/src/polyrenderer/scene/poly_playersprite.h +++ b/src/polyrenderer/scene/poly_playersprite.h @@ -24,9 +24,68 @@ #include "r_defs.h" -class PolyScreenSprite; class DPSprite; -struct FSWColormap; +struct FDynamicColormap; + +class PolyColormapLight +{ +public: + int ColormapNum = 0; + FSWColormap *BaseColormap = nullptr; + + void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack); +}; + +class PolyNoAccelPlayerSprite +{ +public: + short x1 = 0; + short x2 = 0; + + double texturemid = 0.0; + + fixed_t xscale = 0; + float yscale = 0.0f; + + FTexture *pic = nullptr; + + fixed_t xiscale = 0; + fixed_t startfrac = 0; + + float Alpha = 0.0f; + FRenderStyle RenderStyle; + uint32_t Translation = 0; + uint32_t FillColor = 0; + + PolyColormapLight Light; + + short renderflags = 0; + + void Render(); +}; + +class PolyHWAccelPlayerSprite +{ +public: + FTexture *pic = nullptr; + double texturemid = 0.0; + float yscale = 0.0f; + fixed_t xscale = 0; + + float Alpha = 0.0f; + FRenderStyle RenderStyle; + uint32_t Translation = 0; + uint32_t FillColor = 0; + + FDynamicColormap *basecolormap = nullptr; + int x1 = 0; + + bool flip = false; + FSpecialColormap *special = nullptr; + PalEntry overlay = 0; + FColormapStyle colormapstyle; + bool usecolormapstyle = false; +}; class RenderPolyPlayerSprites { @@ -35,31 +94,12 @@ public: void RenderRemainingSprites(); private: - void RenderSprite(DPSprite *sprite, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac); + void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy); + static fixed_t LightLevelToShade(int lightlevel, bool foggy); - const int BaseXCenter = 160; - const int BaseYCenter = 100; + enum { BASEXCENTER = 160 }; + enum { BASEYCENTER = 100 }; - std::vector ScreenSprites; -}; - -// DScreen accelerated sprite to be rendered -class PolyScreenSprite -{ -public: - void Render(); - - FTexture *Pic = nullptr; - double X1 = 0.0; - double Y1 = 0.0; - double Width = 0.0; - double Height = 0.0; - FRemapTable *Translation = nullptr; - bool Flip = false; - float Alpha = 1; - FRenderStyle RenderStyle; - FSWColormap *BaseColormap = nullptr; - int ColormapNum = 0; - uint32_t FillColor = 0; - FDynamicColormap *Colormap = nullptr; + TArray AcceleratedSprites; + sector_t tempsec; }; diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index f26213455..0e0ffbf38 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -45,7 +45,7 @@ void PolyDrawSectorPortal::Render(int portalDepth) const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; - Vec4f portalPlane = Vec4f(0.0f); + PolyClipPlane portalPlane(0.0f, 0.0f, 0.0f, 1.0f); if (Portal->mType != PORTS_SKYVIEWPOINT) { float minHeight; @@ -71,17 +71,11 @@ void PolyDrawSectorPortal::Render(int portalDepth) if (!first && minHeight > viewpoint.Pos.Z) { - portalPlane.x = 0.0f; - portalPlane.y = 0.0f; - portalPlane.z = 1.0f; - portalPlane.w = -minHeight; + portalPlane = PolyClipPlane(0.0f, 0.0f, 1.0f, -minHeight); } else if (!first && maxHeight < viewpoint.Pos.Z) { - portalPlane.x = 0.0f; - portalPlane.y = 0.0f; - portalPlane.z = -1.0f; - portalPlane.w = maxHeight; + portalPlane = PolyClipPlane(0.0f, 0.0f, -1.0f, maxHeight); } } @@ -223,7 +217,7 @@ void PolyDrawLinePortal::Render(int portalDepth) DVector2 planeNormal = (clipLine->v2->fPos() - clipLine->v1->fPos()).Rotated90CW(); planeNormal.MakeUnit(); double planeD = -(planeNormal | (planePos + planeNormal * 0.001)); - Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD); + PolyClipPlane portalPlane((float)planeNormal.X, (float)planeNormal.Y, (float)0.0f, (float)planeD); RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue); RenderPortal.SetPortalSegments(Segments); diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index f3a0b2887..3aeda994c 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -43,7 +43,7 @@ RenderPolyScene::~RenderPolyScene() { } -void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue) +void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue) { WorldToClip = worldToClip; StencilValue = stencilValue; @@ -249,40 +249,33 @@ void RenderPolyScene::RenderPortals(int portalDepth) else // Fill with black { PolyDrawArgs args; - args.objectToClip = &WorldToClip; - args.mode = TriangleDrawMode::Fan; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); - args.uniforms.color = 0; - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::fixed_light; - args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w); + args.SetTransform(&WorldToClip); + args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true); + args.SetColor(0, 0); + args.SetClipPlane(PortalPlane); + args.SetStyle(TriBlendMode::Copy); for (auto &portal : SectorPortals) { - args.stenciltestvalue = portal->StencilValue; - args.stencilwritevalue = portal->StencilValue + 1; + args.SetStencilTestValue(portal->StencilValue); + args.SetWriteStencil(true, portal->StencilValue + 1); for (const auto &verts : portal->Shape) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - args.blendmode = TriBlendMode::Copy; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(verts.Ccw); + args.SetSubsectorDepth(verts.SubsectorDepth); + args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } } for (auto &portal : LinePortals) { - args.stenciltestvalue = portal->StencilValue; - args.stencilwritevalue = portal->StencilValue + 1; + args.SetStencilTestValue(portal->StencilValue); + args.SetWriteStencil(true, portal->StencilValue + 1); for (const auto &verts : portal->Shape) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(verts.Ccw); + args.SetSubsectorDepth(verts.SubsectorDepth); + args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } } } @@ -298,19 +291,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth) portal->RenderTranslucent(portalDepth + 1); PolyDrawArgs args; - args.objectToClip = &WorldToClip; - args.mode = TriangleDrawMode::Fan; - args.stenciltestvalue = portal->StencilValue + 1; - args.stencilwritevalue = StencilValue + 1; - args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w); + args.SetTransform(&WorldToClip); + args.SetStencilTestValue(portal->StencilValue + 1); + args.SetWriteStencil(true, StencilValue + 1); + args.SetClipPlane(PortalPlane); for (const auto &verts : portal->Shape) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - args.writeColor = false; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(verts.Ccw); + args.SetSubsectorDepth(verts.SubsectorDepth); + args.SetWriteColor(false); + args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } } @@ -320,19 +310,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth) portal->RenderTranslucent(portalDepth + 1); PolyDrawArgs args; - args.objectToClip = &WorldToClip; - args.mode = TriangleDrawMode::Fan; - args.stenciltestvalue = portal->StencilValue + 1; - args.stencilwritevalue = StencilValue + 1; - args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w); + args.SetTransform(&WorldToClip); + args.SetStencilTestValue(portal->StencilValue + 1); + args.SetWriteStencil(true, StencilValue + 1); + args.SetClipPlane(PortalPlane); for (const auto &verts : portal->Shape) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - args.writeColor = false; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(verts.Ccw); + args.SetSubsectorDepth(verts.SubsectorDepth); + args.SetWriteColor(false); + args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } } } diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 77c7925c0..707ee87a3 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -29,7 +29,6 @@ #include "doomdata.h" #include "r_utility.h" #include "polyrenderer/drawers/poly_triangle.h" -#include "polyrenderer/math/poly_intersection.h" #include "poly_wall.h" #include "poly_sprite.h" #include "poly_wallsprite.h" @@ -74,7 +73,7 @@ class RenderPolyScene public: RenderPolyScene(); ~RenderPolyScene(); - void SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue); + void SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue); void SetPortalSegments(const std::vector &segments); void Render(int portalDepth); void RenderTranslucent(int portalDepth); @@ -91,7 +90,7 @@ private: void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node); TriMatrix WorldToClip; - Vec4f PortalPlane; + PolyClipPlane PortalPlane; uint32_t StencilValue = 0; PolyCull Cull; uint32_t NextSubsectorDepth = 0; diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 3be38e481..374163f96 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -38,7 +38,6 @@ PolySkyDome::PolySkyDome() void PolySkyDome::Render(const TriMatrix &worldToClip) { FTextureID sky1tex, sky2tex; - bool foggy = false; if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY)) sky1tex = sky2texture; else @@ -57,15 +56,12 @@ void PolySkyDome::Render(const TriMatrix &worldToClip) int rc = mRows + 1; PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::nearest_filter; - args.uniforms.subsectorDepth = RenderPolyScene::SkySubsectorDepth; - args.objectToClip = &objectToClip; - args.stenciltestvalue = 255; - args.stencilwritevalue = 1; - args.SetColormap(&NormalLight); - args.SetClipPlane(0.0f, 0.0f, 0.0f, 0.0f); + args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(false), true); + args.SetSubsectorDepth(RenderPolyScene::SkySubsectorDepth); + args.SetTransform(&objectToClip); + args.SetStencilTestValue(255); + args.SetWriteStencil(true, 1); + args.SetClipPlane(PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f)); RenderCapColorRow(args, frontskytex, 0, false); RenderCapColorRow(args, frontskytex, rc, true); @@ -84,28 +80,21 @@ void PolySkyDome::Render(const TriMatrix &worldToClip) void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor) { - args.vinput = &mVertices[mPrimStart[row]]; - args.vcount = mPrimStart[row + 1] - mPrimStart[row]; - args.mode = TriangleDrawMode::Strip; - args.ccw = false; - args.uniforms.color = capcolor; - args.blendmode = TriBlendMode::Skycap; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(false); + args.SetColor(capcolor, 0); + args.SetStyle(TriBlendMode::Skycap); + args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip); } void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap) { uint32_t solid = skytex->GetSkyCapColor(bottomCap); - if (!PolyRenderer::Instance()->RenderTarget->IsBgra()) - solid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)]; + uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)]; - args.vinput = &mVertices[mPrimStart[row]]; - args.vcount = mPrimStart[row + 1] - mPrimStart[row]; - args.mode = TriangleDrawMode::Fan; - args.ccw = bottomCap; - args.uniforms.color = solid; - args.blendmode = TriBlendMode::Copy; - PolyTriangleDrawer::draw(args); + args.SetFaceCullCCW(bottomCap); + args.SetColor(solid, palsolid); + args.SetStyle(TriBlendMode::Copy); + args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan); } void PolySkyDome::CreateDome() diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 6e3c8c86c..2a98af721 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -27,7 +27,6 @@ #include "r_data/r_translate.h" #include "poly_sprite.h" #include "polyrenderer/poly_renderer.h" -#include "polyrenderer/math/poly_intersection.h" #include "polyrenderer/scene/poly_light.h" EXTERN_CVAR(Float, transsouls) @@ -65,7 +64,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right) return true; } -void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2) +void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2) { DVector2 line[2]; if (!GetLine(thing, line[0], line[1])) @@ -136,136 +135,80 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla } bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); - PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight; PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.SpriteGlobVis(foggy); - args.uniforms.flags = TriUniforms::nearest_filter; - if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - { - args.uniforms.light = 256; - args.uniforms.flags |= TriUniforms::fixed_light; - } - else - { - args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f); - } - args.uniforms.subsectorDepth = subsectorDepth; - - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = 4; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue; + args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite); + args.SetSubsectorDepth(subsectorDepth); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(stencilValue); + args.SetWriteStencil(true, stencilValue); args.SetTexture(tex, thing->Translation); - args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true)); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); + args.SetClipPlane(clipPlane); - TriBlendMode blendmode; - if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - args.uniforms.destalpha = 0; - args.uniforms.srcalpha = 256; - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 1.0, 0.0); } - else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && args.translation == nullptr) + else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation()) { - args.uniforms.destalpha = 256; - args.uniforms.srcalpha = 256; - blendmode = TriBlendMode::AddSrcColorOneMinusSrcColor; + args.SetStyle(TriBlendMode::AddSrcColorOneMinusSrcColor, 1.0, 1.0); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add]) { - args.uniforms.destalpha = (uint32_t)(1.0 * 256); - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) { - args.uniforms.destalpha = (uint32_t)(1.0 * 256); - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - blendmode = args.translation ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub, thing->Alpha, 1.0); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans]) { - args.uniforms.destalpha = (uint32_t)(256 - transsouls * 256); - args.uniforms.srcalpha = (uint32_t)(transsouls * 256); - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, transsouls, 1.0 - transsouls); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { // NYI - Fuzzy - for now, just a copy of "Shadow" - args.uniforms.destalpha = 160; - args.uniforms.srcalpha = 0; - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { - args.uniforms.destalpha = 160; - args.uniforms.srcalpha = 0; - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil]) { - args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256); - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.uniforms.color = 0xff000000 | thing->fillcolor; - blendmode = TriBlendMode::Stencil; + args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24); + args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil]) { - args.uniforms.destalpha = 256; - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.uniforms.color = 0xff000000 | thing->fillcolor; - blendmode = TriBlendMode::Stencil; + args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24); + args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded]) { - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.uniforms.destalpha = 256 - args.uniforms.srcalpha; - args.uniforms.color = 0; - blendmode = TriBlendMode::Shaded; + args.SetColor(0, 0); + args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha); + args.SetTexture(tex, thing->Translation, true); } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded]) { - args.uniforms.destalpha = 256; - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.uniforms.color = 0; - blendmode = TriBlendMode::Shaded; + args.SetColor(0, 0); + args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha); + args.SetTexture(tex, thing->Translation, true); } else { - args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256); - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0 - thing->Alpha); } - if (blendmode == TriBlendMode::Shaded) - { - args.SetTexture(tex, thing->Translation, true); - } - - if (!PolyRenderer::Instance()->RenderTarget->IsBgra()) - { - uint32_t r = (args.uniforms.color >> 16) & 0xff; - uint32_t g = (args.uniforms.color >> 8) & 0xff; - uint32_t b = args.uniforms.color & 0xff; - args.uniforms.color = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; - - if (blendmode == TriBlendMode::Sub) // Sub crashes in pal mode for some weird reason. - blendmode = TriBlendMode::Add; - } - - args.subsectorTest = true; - args.writeSubsector = false; - args.writeStencil = false; - args.blendmode = blendmode; - PolyTriangleDrawer::draw(args); + args.SetSubsectorDepthTest(true); + args.SetWriteSubsectorDepth(false); + args.SetWriteStencil(false); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } bool RenderPolySprite::IsThingCulled(AActor *thing) diff --git a/src/polyrenderer/scene/poly_sprite.h b/src/polyrenderer/scene/poly_sprite.h index a61c7f4b5..e190d9ee6 100644 --- a/src/polyrenderer/scene/poly_sprite.h +++ b/src/polyrenderer/scene/poly_sprite.h @@ -24,12 +24,10 @@ #include "polyrenderer/drawers/poly_triangle.h" -class Vec4f; - class RenderPolySprite { public: - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2); static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right); static bool IsThingCulled(AActor *thing); diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index abbfd15f8..263487f70 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -37,7 +37,7 @@ EXTERN_CVAR(Bool, r_drawmirrors) -bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals) +bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals) { PolyDrawLinePortal *polyportal = nullptr; if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors)) @@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP return polyportal != nullptr; } -void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector &translucentWallsOutput) +void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector &translucentWallsOutput) { double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1); double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1); @@ -198,7 +198,7 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce this->floor2 = floor2; } -void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull) +void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull) { bool foggy = false; FTexture *tex = GetTexture(); @@ -248,32 +248,23 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane } PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); - args.uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f); - args.uniforms.flags = TriUniforms::nearest_filter; - args.uniforms.subsectorDepth = SubsectorDepth; - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = 4; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = StencilValue; - args.stencilwritevalue = StencilValue + 1; + args.SetLight(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]), GetLightLevel(), PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); + args.SetSubsectorDepth(SubsectorDepth); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(StencilValue); + args.SetWriteStencil(true, StencilValue + 1); if (tex) args.SetTexture(tex); - args.SetColormap(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop])); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); - - //if (Side && Side->lighthead) - // args.uniforms.light = 255; // Make walls touched by a light fullbright! + args.SetClipPlane(clipPlane); if (Polyportal) { - args.stencilwritevalue = Polyportal->StencilValue; - args.writeColor = false; - args.writeSubsector = false; - PolyTriangleDrawer::draw(args); - Polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, args.uniforms.subsectorDepth }); + args.SetWriteStencil(true, Polyportal->StencilValue); + args.SetWriteColor(false); + args.SetWriteSubsectorDepth(false); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + Polyportal->Shape.push_back({ vertices, 4, true, SubsectorDepth }); angle_t angle1, angle2; if (cull.GetAnglesForLine(v1.X, v1.Y, v2.X, v2.Y, angle1, angle2)) @@ -281,21 +272,16 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane } else if (!Masked) { - args.blendmode = TriBlendMode::Copy; - PolyTriangleDrawer::draw(args); + args.SetStyle(TriBlendMode::Copy); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } else { - args.uniforms.destalpha = (Line->flags & ML_ADDTRANS) ? 256 : (uint32_t)(256 - Line->alpha * 256); - args.uniforms.srcalpha = (uint32_t)(Line->alpha * 256); - args.subsectorTest = true; - args.writeSubsector = false; - args.writeStencil = false; - if (args.uniforms.destalpha == 0 && args.uniforms.srcalpha == 256) - args.blendmode = TriBlendMode::AlphaBlend; - else - args.blendmode = TriBlendMode::Add; - PolyTriangleDrawer::draw(args); + args.SetStyle((Line->flags & ML_ADDTRANS) ? TriBlendMode::Add : TriBlendMode::AlphaBlend, Line->alpha, 1.0); + args.SetSubsectorDepthTest(true); + args.SetWriteSubsectorDepth(true); + args.SetWriteStencil(false); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, SubsectorDepth, StencilValue); diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index a435201b2..dda2cdc2a 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -27,16 +27,15 @@ class PolyTranslucentObject; class PolyDrawLinePortal; class PolyCull; -class Vec4f; class RenderPolyWall { public: - static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals); - static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector &translucentWallsOutput); + static bool RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals); + static void Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector &translucentWallsOutput); void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2); - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull); DVector2 v1; DVector2 v2; diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 75227c255..8108849b9 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -29,7 +29,7 @@ #include "polyrenderer/poly_renderer.h" #include "polyrenderer/scene/poly_light.h" -void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) +void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) { if (RenderPolySprite::IsThingCulled(thing)) return; @@ -97,35 +97,18 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &cli } bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); - PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight; PolyDrawArgs args; - args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); - if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) - { - args.uniforms.light = 256; - args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter; - } - else - { - args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f); - args.uniforms.flags = TriUniforms::nearest_filter; - } - args.uniforms.subsectorDepth = subsectorDepth; - - args.objectToClip = &worldToClip; - args.vinput = vertices; - args.vcount = 4; - args.mode = TriangleDrawMode::Fan; - args.ccw = true; - args.stenciltestvalue = stencilValue; - args.stencilwritevalue = stencilValue; + args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite); + args.SetTransform(&worldToClip); + args.SetFaceCullCCW(true); + args.SetStencilTestValue(stencilValue); args.SetTexture(tex); - args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true)); - args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); - args.subsectorTest = true; - args.writeSubsector = false; - args.writeStencil = false; - args.blendmode = TriBlendMode::AlphaBlend; - PolyTriangleDrawer::draw(args); + args.SetClipPlane(clipPlane); + args.SetSubsectorDepthTest(true); + args.SetWriteSubsectorDepth(false); + args.SetWriteStencil(false); + args.SetStyle(TriBlendMode::AlphaBlend); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_wallsprite.h b/src/polyrenderer/scene/poly_wallsprite.h index 75a550748..c0c0005b8 100644 --- a/src/polyrenderer/scene/poly_wallsprite.h +++ b/src/polyrenderer/scene/poly_wallsprite.h @@ -24,10 +24,8 @@ #include "polyrenderer/drawers/poly_triangle.h" -class Vec4f; - class RenderPolyWallSprite { public: - void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); + void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); }; diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index e00f137a7..01457c012 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -84,6 +84,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad); int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad); #endif +double PerfToSec, PerfToMillisec; uint32_t LanguageIDs[4]; int (*I_GetTime) (bool saveMS); diff --git a/src/st_stuff.h b/src/st_stuff.h index c95c6e801..a0434f8b4 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -26,7 +26,6 @@ struct event_t; -extern int gST_X; extern int gST_Y; bool ST_Responder(event_t* ev); diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 00d5d4860..bf8d856e9 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -99,7 +99,7 @@ namespace swrenderer v = v - floor(v); double v_step = uv_stepd / texture->GetHeight(); - if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does.. + if (isnan(v) || isnan(v_step)) // this should never happen, but it apparently does.. { uv_stepd = 0.0; v = 0.0; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index f7e318472..d06628d43 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -81,7 +81,6 @@ int CleanWidth, CleanHeight; // Above minus 1 (or 1, if they are already 1) int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; -CVAR (Bool, hud_scale, true, CVAR_ARCHIVE); DEFINE_ACTION_FUNCTION(_Screen, GetWidth) { @@ -210,33 +209,21 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double case DTA_HUDRules: case DTA_HUDRulesC: { - // Note that this has been deprecated because it cannot intelligently decide what scale - // actually needs to be used in conjunction with the active status bar. + // Note that this has been deprecated because the HUD should be drawn by the status bar. bool xright = parms->x < 0; bool ybot = parms->y < 0; + DVector2 scale = StatusBar->GetHUDScale(); - if (hud_scale) - { - parms->x *= CleanXfac; - if (parms->cleanmode == DTA_HUDRulesC) - parms->x += Width * 0.5; - else if (xright) - parms->x = Width + parms->x; - parms->y *= CleanYfac; - if (ybot) - parms->y = Height + parms->y; - parms->destwidth = parms->texwidth * CleanXfac; - parms->destheight = parms->texheight * CleanYfac; - } - else - { - if (parms->cleanmode == DTA_HUDRulesC) - parms->x += Width * 0.5; - else if (xright) - parms->x = Width + parms->x; - if (ybot) - parms->y = Height + parms->y; - } + parms->x *= scale.X; + if (parms->cleanmode == DTA_HUDRulesC) + parms->x += Width * 0.5; + else if (xright) + parms->x = Width + parms->x; + parms->y *= scale.Y; + if (ybot) + parms->y = Height + parms->y; + parms->destwidth = parms->texwidth * scale.X; + parms->destheight = parms->texheight * scale.Y; break; } } @@ -513,7 +500,7 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t case DTA_FillColor: parms->fillcolor = ListGetInt(tags); - if (parms->fillcolor != -1) + if (parms->fillcolor != ~0u) { fillcolorset = true; } diff --git a/src/version.h b/src/version.h index 8b081c14a..6b8cafe47 100644 --- a/src/version.h +++ b/src/version.h @@ -66,7 +66,7 @@ const char *GetVersionString(); // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to // be able to migrate in FGameConfigFile::DoGlobalSetup(). -#define LASTRUNVERSION "211" +#define LASTRUNVERSION "212" // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index b96164a20..08cef5fd2 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -27,6 +27,7 @@ gameinfo backpacktype = "Backpack" armoricons = "ARM1A0", 0.5, "ARM2A0" statusbar = "sbarinfo/doom.txt" + //statusbarclass = "DoomStatusBar" intermissionmusic = "$MUSIC_DM2INT" intermissioncounter = true weaponslot = 1, "Fist", "Chainsaw" diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index fbdf3d9e3..73f7c4572 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -67,6 +67,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "RavenStatusScreen" + statusbarclass = "StrifeStatusBar" } DoomEdNums diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 143057396..7f5539608 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -843,7 +843,6 @@ OptionMenu "HUDOptions" Option "$HUDMNU_NAMETAGS", "displaynametags", "DisplayTagsTypes" Option "$HUDMNU_NAMETAGCOLOR", "nametagcolor", "TextColors", "displaynametags" Option "$HUDMNU_SCALESTATBAR", "st_scale", "OnOff" - Option "$HUDMNU_SCALEFULLSCREENHUD", "hud_scale", "OnOff" Option "$HUDMNU_OLDOUCH", "st_oldouch", "OnOff" StaticText " " Option "$HUDMNU_HEXENFLASHES", "pf_hexenweaps", "ZDoomHexen" diff --git a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt index e785abdb9..d58e175d1 100644 --- a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt +++ b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt @@ -4,13 +4,10 @@ struct SBarInfo native ui native void SetScaled(bool scaled); native void Destroy(); native void AttachToPlayer(PlayerInfo player); - native void ScreenSizeChanged(); native void Draw(int state); native void NewGame(); native bool MustDrawLog(int state); - native void SetMugShotState(String state_name, bool wait_till_done, bool reset); native void Tick(); - native clearscope void ReceivedWeapon(Weapon weapon); native void FlashItem(class itemtype); native void ShowPop(int popnum); } @@ -41,12 +38,6 @@ class SBarInfoWrapper : BaseStatusBar core.AttachToPlayer(player); } - override void ScreenSizeChanged() - { - Super.ScreenSizeChanged(); - core.ScreenSizeChanged(); - } - override void Draw(int state, double TicFrac) { Super.Draw(state, TicFrac); @@ -68,22 +59,12 @@ class SBarInfoWrapper : BaseStatusBar return core.MustDrawLog(state); } - override void SetMugShotState(String state_name, bool wait_till_done, bool reset) - { - core.SetMugShotState(state_name, wait_till_done, reset); - } - override void Tick() { Super.Tick(); core.Tick(); } - override void ReceivedWeapon(Weapon weapon) - { - core.ReceivedWeapon(weapon); - } - override void FlashItem(class itemtype) { core.FlashItem(itemtype); diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 2a1b92492..97a153e4b 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -157,16 +157,20 @@ class BaseStatusBar native ui native double Displacement; native PlayerInfo CPlayer; native bool ShowLog; + native Vector2 defaultScale; // factor for fully scaled fullscreen display. // These are block properties for the drawers. A child class can set them to have a block of items use the same settings. native double Alpha; native Vector2 drawOffset; // can be set by subclasses to offset drawing operations native double drawClip[4]; // defines a clipping rectangle (not used yet) native bool fullscreenOffsets; // current screen is displayed with fullscreen behavior. - native Vector2 cleanScale; // factor for scaled fullscreen display. native void SetSize(int height, int vwidth, int vheight); + native Vector2 GetHUDScale(); + native void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); + native void BeginHUD(int resW, int resH, double Alpha, bool forcescaled = false); + virtual void Init() {} native virtual void SetScaled(bool scale, bool force = false); @@ -174,6 +178,7 @@ class BaseStatusBar native ui native virtual void Draw (int state, double TicFrac); native virtual void ScreenSizeChanged (); native virtual clearscope void ReceivedWeapon (Weapon weapn); + native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false); virtual void FlashItem (class itemtype) {} virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; } @@ -181,7 +186,6 @@ class BaseStatusBar native ui virtual void NewGame () {} virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); } virtual bool MustDrawLog(int state) { return true; } - virtual void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false) {} native void RefreshBackground () const; native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);