From 49f590c79742991b22b86599fd210a3a433ba8a2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 Mar 2018 20:04:41 +0100 Subject: [PATCH 01/37] - Use the Windows system function to determine the number of physical CPU cores. The generic version does not appear to work as intended. --- src/d_stats.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index ebec250bb..9f00d2a5c 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -185,12 +185,49 @@ static int GetOSVersion() #endif } + +#ifdef _WIN32 + +static int GetCoreInfo() +{ + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL; + DWORD returnLength = 0; + int cores = 0; + uint32_t byteOffset = 0; + + auto rc = GetLogicalProcessorInformation(buffer, &returnLength); + + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(returnLength); + if (!GetLogicalProcessorInformation(buffer, &returnLength)) return 0; + } + else + { + return 0; + } + + ptr = buffer; + + while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) + { + if (ptr->Relationship == RelationProcessorCore) cores++; + byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + ptr++; + } + free(buffer); + return cores < 2 ? 0 : cores < 4 ? 1 : cores < 6 ? 2 : cores < 8 ? 3 : 4; +} + +#else static int GetCoreInfo() { int cores = std::thread::hardware_concurrency(); if (CPU.HyperThreading) cores /= 2; return cores < 2? 0 : cores < 4? 1 : cores < 6? 2 : cores < 8? 3 : 4; } +#endif static int GetRenderInfo() { From bdeae23a56609dabdefa5908417e242b80bc4a0e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 14 Mar 2018 10:20:46 +0200 Subject: [PATCH 02/37] Added native UI dialog to confirm stats collection Implemented only for Windows so far Need good message to explain purpose of this feature --- src/d_main.cpp | 3 +++ src/d_stats.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 6338f9b04..007af39d5 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2352,6 +2352,9 @@ void D_DoomMain (void) D_DoomInit(); + extern void D_ConfirmSendStats(); + D_ConfirmSendStats(); + // [RH] Make sure zdoom.pk3 is always loaded, // as it contains magic stuff we need. wad = BaseFileSearch (BASEWAD, NULL, true); diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 9f00d2a5c..73db23740 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -20,6 +20,8 @@ extern int sys_ostype; EXTERN_CVAR(Bool, vid_glswfb) extern int currentrenderer; + +CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) @@ -264,6 +266,11 @@ static void D_DoHTTPRequest(const char *request) void D_DoAnonStats() { + if (sys_statsenabled != 1) + { + return; + } + static bool done = false; // do this only once per session. if (done) return; done = true; @@ -279,3 +286,26 @@ void D_DoAnonStats() std::thread t1(D_DoHTTPRequest, requeststring); t1.detach(); } + +void D_ConfirmSendStats() +{ + if (sys_statsenabled >= 0) + { + return; + } + + // TODO: texts + static const char *const MESSAGE_TEXT = "send stats?"; + static const char *const TITLE_TEXT = GAMENAME; + + UCVarValue enabled = { 0 }; + +#ifdef _WIN32 + extern HWND Window; + enabled = { MessageBox(Window, MESSAGE_TEXT, TITLE_TEXT, MB_ICONQUESTION | MB_YESNO) == IDYES }; +#else + // TODO +#endif + + sys_statsenabled.ForceSet(enabled, CVAR_Int); +} From 549a290a2f6c193d75f5514289abd3f5b6370a4c Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Wed, 14 Mar 2018 11:40:47 -0400 Subject: [PATCH 03/37] - add 'renderconfig' for the stats script to easily differentiate between OpenGL and software --- src/d_stats.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 9f00d2a5c..330fa75ec 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -273,8 +273,8 @@ void D_DoAnonStats() if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return; static char requeststring[1024]; - sprintf(requeststring, "GET /stats.php?render=%i&cores=%i&os=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", - GetRenderInfo(), GetCoreInfo(), GetOSVersion(), sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); + sprintf(requeststring, "GET /stats.php?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", + GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); std::thread t1(D_DoHTTPRequest, requeststring); t1.detach(); From f1bfc3514dd2809bfed60849652f4918d3936e31 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 Mar 2018 19:52:30 +0100 Subject: [PATCH 04/37] - fixed: For proper recognition of optional function arguments, the argflags must also be copied from the parent function to ensure they are itdentical on the override. --- src/scripting/zscript/zcc_compile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 279d9adda..4d530c8a5 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2743,6 +2743,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool if (parentfunc->Variants[0].Implementation->DefaultArgs.Size() > 0) { sym->Variants[0].Implementation->DefaultArgs = parentfunc->Variants[0].Implementation->DefaultArgs; + sym->Variants[0].ArgFlags = parentfunc->Variants[0].ArgFlags; } } } From a9802f82f41e8918a997798733b88073fcfef4cc Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 14 Mar 2018 22:19:33 +0200 Subject: [PATCH 05/37] Replaced usages of sprintf() in stats sender --- src/d_stats.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 330fa75ec..5886d4cef 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -113,18 +113,15 @@ bool I_HTTPRequest(const char* request) return false; } - char buffer[1024]; - sprintf(buffer, "%s", request); - Printf("Buffer: %s", buffer); - n = write(sockfd, (char*)buffer, (int)strlen(request)); + n = write(sockfd, request, strlen(request)); if (n<0) { DPrintf(DMSG_ERROR, "Error writing to socket.\n"); close(sockfd); return false; } - bzero(buffer, 1024); + char buffer[1024] = {}; n = read(sockfd, buffer, 1023); close(sockfd); DPrintf(DMSG_NOTIFY, "Stats send successful.\n"); @@ -273,7 +270,7 @@ void D_DoAnonStats() if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return; static char requeststring[1024]; - sprintf(requeststring, "GET /stats.php?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", + mysnprintf(requeststring, sizeof requeststring, "GET /stats.php?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); std::thread t1(D_DoHTTPRequest, requeststring); From 9a737a06226e44dd295231b500f9418d3d5104fc Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 16 Mar 2018 15:47:23 +0200 Subject: [PATCH 06/37] Added ability to turn off sending of stats in CMake configuration --- src/CMakeLists.txt | 6 ++++++ src/d_stats.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 58ca6a9ba..e75798a54 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -639,6 +639,12 @@ elseif( FLUIDSYNTH_FOUND ) add_definitions( -DHAVE_FLUIDSYNTH ) endif() +option( SEND_ANON_STATS "Enable sending of anonymous hardware statistics" ON ) + +if( NOT SEND_ANON_STATS ) + add_definitions( -DNO_SEND_STATS ) +endif() + # Project files should be aware of the header files. We can GLOB these since # there's generally a new cpp for every header so this file will get changed if( WIN32 ) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 5886d4cef..9ea3e80b5 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -1,3 +1,12 @@ + +#ifdef NO_SEND_STATS + +void D_DoAnonStats() +{ +} + +#else // !NO_SEND_STATS + #if defined(_WIN32) #define _WIN32_WINNT 0x0501 #define WIN32_LEAN_AND_MEAN @@ -276,3 +285,5 @@ void D_DoAnonStats() std::thread t1(D_DoHTTPRequest, requeststring); t1.detach(); } + +#endif // NO_SEND_STATS From a2b9a70835aaac8613c1903e44865c94c8c21ef0 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 17 Mar 2018 00:09:43 +0100 Subject: [PATCH 07/37] - Fix crash when reloading a map --- src/polyrenderer/scene/poly_cull.cpp | 31 +++++++++------------------ src/polyrenderer/scene/poly_cull.h | 4 ++-- src/polyrenderer/scene/poly_scene.cpp | 9 ++++---- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index a3361fd62..d53e0e1bf 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -33,26 +33,15 @@ void PolyCull::CullScene(const PolyClipPlane &portalClipPlane) ClearSolidSegments(); MarkViewFrustum(); - if (level.LevelName != lastLevelName) // Is this the best way to detect a level change? - { - lastLevelName = level.LevelName; - SubsectorDepths.clear(); - SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); - SectorSeen.clear(); - SectorSeen.resize(level.sectors.Size()); - } - else - { - for (const auto &sub : PvsSectors) - SubsectorDepths[sub->Index()] = 0xffffffff; - SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); + for (uint32_t sub : PvsSubsectors) + SubsectorDepths[sub] = 0xffffffff; + SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); - for (const auto §or : SeenSectors) - SectorSeen[sector->Index()] = false; - SectorSeen.resize(level.sectors.Size()); - } + for (uint32_t sector : SeenSectors) + SectorSeen[sector] = false; + SectorSeen.resize(level.sectors.Size()); - PvsSectors.clear(); + PvsSubsectors.clear(); SeenSectors.clear(); NextPvsLineStart = 0; @@ -125,10 +114,10 @@ void PolyCull::CullSubsector(subsector_t *sub) FirstSkyHeight = false; } - uint32_t subsectorDepth = (uint32_t)PvsSectors.size(); + uint32_t subsectorDepth = (uint32_t)PvsSubsectors.size(); // Mark that we need to render this - PvsSectors.push_back(sub); + PvsSubsectors.push_back(sub->Index()); PvsLineStart.push_back(NextPvsLineStart); DVector3 viewpos = PolyRenderer::Instance()->Viewpoint.Pos; @@ -169,7 +158,7 @@ void PolyCull::CullSubsector(subsector_t *sub) if (!SectorSeen[sub->sector->Index()]) { SectorSeen[sub->sector->Index()] = true; - SeenSectors.push_back(sub->sector); + SeenSectors.push_back(sub->sector->Index()); } SubsectorDepths[sub->Index()] = subsectorDepth; diff --git a/src/polyrenderer/scene/poly_cull.h b/src/polyrenderer/scene/poly_cull.h index 474a33bb6..4b851373e 100644 --- a/src/polyrenderer/scene/poly_cull.h +++ b/src/polyrenderer/scene/poly_cull.h @@ -36,11 +36,11 @@ public: return PvsLineVisible[PvsLineStart[subsectorDepth] + lineIndex]; } - std::vector PvsSectors; + std::vector PvsSubsectors; double MaxCeilingHeight = 0.0; double MinFloorHeight = 0.0; - std::vector SeenSectors; + std::vector SeenSectors; std::vector SectorSeen; std::vector SubsectorDepths; diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 02ad1842e..42f6e815b 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -69,8 +69,8 @@ void RenderPolyScene::RenderSectors() { PolyRenderThread *mainthread = PolyRenderer::Instance()->Threads.MainThread(); - int totalcount = (int)Cull.PvsSectors.size(); - auto subsectors = Cull.PvsSectors.data(); + int totalcount = (int)Cull.PvsSubsectors.size(); + uint32_t *subsectors = Cull.PvsSubsectors.data(); TranslucentObjects.resize(PolyRenderer::Instance()->Threads.NumThreads()); @@ -82,7 +82,7 @@ void RenderPolyScene::RenderSectors() int end = thread->End; for (int i = start; i < end; i++) { - RenderSubsector(thread, subsectors[i], i); + RenderSubsector(thread, &level.subsectors[subsectors[i]], i); } }, [&](PolyRenderThread *thread) { @@ -372,8 +372,9 @@ void RenderPolyScene::RenderTranslucent(int portalDepth) } const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; - for (sector_t *sector : Cull.SeenSectors) + for (uint32_t sectorIndex : Cull.SeenSectors) { + sector_t *sector = &level.sectors[sectorIndex]; for (AActor *thing = sector->thinglist; thing != nullptr; thing = thing->snext) { DVector2 left, right; From b4d37153452f9b63156d907eb92d5225dc66400e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 17 Mar 2018 12:29:55 +0200 Subject: [PATCH 08/37] Fixed status bar chain wiggling when paused Made ZScript implementation of chain wiggling in Heretic status bar as close as possible to C++ SBARINFO one https://forum.zdoom.org/viewtopic.php?t=59840 --- wadsrc/static/zscript/statusbar/heretic_sbar.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/statusbar/heretic_sbar.txt b/wadsrc/static/zscript/statusbar/heretic_sbar.txt index 691a89e33..8d490444e 100644 --- a/wadsrc/static/zscript/statusbar/heretic_sbar.txt +++ b/wadsrc/static/zscript/statusbar/heretic_sbar.txt @@ -6,6 +6,7 @@ class HereticStatusBar : BaseStatusBar HUDFont mBigFont; InventoryBarState diparms; InventoryBarState diparms_sbar; + private int wiggle; override void Init() @@ -40,6 +41,12 @@ class HereticStatusBar : BaseStatusBar { Super.Tick(); mHealthInterpolator.Update(CPlayer.health); + + // wiggle the chain if it moves + if (level.time & 1) + { + wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && Random[ChainWiggle](0, 1); + } } override void Draw (int state, double TicFrac) @@ -73,7 +80,6 @@ class HereticStatusBar : BaseStatusBar DrawImage("CHAINCAC", (0, 190), DI_ITEM_OFFSETS); // wiggle the chain if it moves int inthealth = mHealthInterpolator.GetValue(); - int wiggle = (inthealth != CPlayer.health) && Random[ChainWiggle](0, 1); DrawGem("CHAIN", "LIFEGEM2",inthealth, CPlayer.mo.GetMaxHealth(true), (2, 191 + wiggle), 15, 25, 16, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP); DrawImage("LTFACE", (0, 190), DI_ITEM_OFFSETS); DrawImage("RTFACE", (276, 190), DI_ITEM_OFFSETS); From ecff13ac2eecaf7cc6fe0dbfb8759ca59d8cae20 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 17 Mar 2018 22:38:41 +0200 Subject: [PATCH 09/37] Fixed crash on attempt to send stats without network connection https://forum.zdoom.org/viewtopic.php?t=59844 --- src/d_stats.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 9ea3e80b5..58c83dfae 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -57,6 +57,11 @@ bool I_HTTPRequest(const char* request) SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct hostent *host; host = gethostbyname(sys_statshost.GetHumanString()); + if (host == nullptr) + { + DPrintf(DMSG_ERROR, "Error looking up hostname.\n"); + return false; + } SOCKADDR_IN SockAddr; SockAddr.sin_port = htons(sys_statsport); SockAddr.sin_family = AF_INET; From 75782e6b349e12ebfdf43b43090747fdc7655d54 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 18 Mar 2018 11:02:21 +0200 Subject: [PATCH 10/37] Exported Inventory.AltHUDIcon field to ZScript https://forum.zdoom.org/viewtopic.php?t=59842 --- src/g_inventory/a_pickups.cpp | 2 ++ wadsrc/static/zscript/inventory/inventory.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index ff98ea421..2ed33954b 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -82,6 +82,7 @@ DEFINE_FIELD(AInventory, MaxAmount) DEFINE_FIELD(AInventory, InterHubAmount) DEFINE_FIELD(AInventory, RespawnTics) DEFINE_FIELD(AInventory, Icon) +DEFINE_FIELD(AInventory, AltHUDIcon) DEFINE_FIELD(AInventory, DropTime) DEFINE_FIELD(AInventory, SpawnPointClass) DEFINE_FIELD(AInventory, PickupFlash) @@ -147,6 +148,7 @@ void AInventory::Serialize(FSerializer &arc) ("respawntics", RespawnTics, def->RespawnTics) ("itemflags", ItemFlags, def->ItemFlags) ("icon", Icon, def->Icon) + ("althudicon", AltHUDIcon, def->AltHUDIcon) ("pickupsound", PickupSound, def->PickupSound) ("spawnpointclass", SpawnPointClass, def->SpawnPointClass) ("droptime", DropTime, def->DropTime); diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index e7786059b..1bc3f42a6 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -16,6 +16,7 @@ class Inventory : Actor native native int InterHubAmount; // Amount of item that can be kept between hubs or levels native int RespawnTics; // Tics from pickup time to respawn time native TextureID Icon; // Icon to show on status bar or HUD + native TextureID AltHUDIcon; native int DropTime; // Countdown after dropping native Class SpawnPointClass; // For respawning like Heretic's mace native Class PickupFlash; // actor to spawn as pickup flash From 341a9bcf91054dd2c6346126d2418f8e0d1692c1 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 18 Mar 2018 11:23:24 +0200 Subject: [PATCH 11/37] Added target and last enemy to linetarget CCMD output https://forum.zdoom.org/viewtopic.php?t=59716 --- src/p_mobj.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 371e3f977..e27ab198c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -8516,5 +8516,7 @@ void PrintMiscActorInfo(AActor *query) query->Speed, query->Vel.X, query->Vel.Y, query->Vel.Z, query->Vel.Length()); Printf("Scale: x:%f, y:%f\n", query->Scale.X, query->Scale.Y); Printf("FriendlySeeBlocks: %d\n", query->friendlyseeblocks); + Printf("Target: %s\n", query->target ? query->target->GetClass()->TypeName.GetChars() : "-"); + Printf("Last enemy: %s\n", query->lastenemy ? query->lastenemy->GetClass()->TypeName.GetChars() : "-"); } } From 102d2647d36b20f5685ce118d65904b20ed125ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 11:57:41 +0100 Subject: [PATCH 12/37] - removed support for loading Build palettes as the main game palette. This was implemented in a way that made it entirely impossible to load Build resources and make them usable for modding. ZDoom had Build texture support for many years but the limitations the palette handling imposed made it impossible to use them. It wasn't usable for anything more than to load Build maps and have them display properly - a feature that had to be removed because it was irreparably broken already. With the forced palette override out of the way it should now be possible to implement loading of Build ART files as actually usable resources. --- src/v_palette.cpp | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 11e3f6945..436fe84dc 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -377,32 +377,16 @@ void InitPalette () bool usingBuild = false; int lump; - if ((lump = Wads.CheckNumForFullName ("palette.dat")) >= 0 && Wads.LumpLength (lump) >= 768) - { - usingBuild = FixBuildPalette (pal, lump, false); - } - else if ((lump = Wads.CheckNumForFullName ("blood.pal")) >= 0 && Wads.LumpLength (lump) >= 768) - { - usingBuild = FixBuildPalette (pal, lump, true); - } - - if (!usingBuild) - { - ReadPalette(Wads.CheckNumForName("PLAYPAL"), pal); - } + ReadPalette(Wads.CheckNumForName("PLAYPAL"), pal); GPalette.SetPalette (pal); GPalette.MakeGoodRemap (); ColorMatcher.SetPalette ((uint32_t *)GPalette.BaseColors); - // The BUILD engine already has a transparent color, so it doesn't need any remapping. - if (!usingBuild) - { - if (GPalette.Remap[0] == 0) - { // No duplicates, so settle for something close to color 0 - GPalette.Remap[0] = BestColor ((uint32_t *)GPalette.BaseColors, - GPalette.BaseColors[0].r, GPalette.BaseColors[0].g, GPalette.BaseColors[0].b, 1, 255); - } + if (GPalette.Remap[0] == 0) + { // No duplicates, so settle for something close to color 0 + GPalette.Remap[0] = BestColor ((uint32_t *)GPalette.BaseColors, + GPalette.BaseColors[0].r, GPalette.BaseColors[0].g, GPalette.BaseColors[0].b, 1, 255); } // Colormaps have to be initialized before actors are loaded, From 832fc42e07caff1a4f09503cdc23cb1d3195366f Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 18 Mar 2018 13:26:04 +0200 Subject: [PATCH 13/37] Added native UI dialog to confirm stats collection --- src/d_main.cpp | 3 +++ src/d_stats.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 6338f9b04..007af39d5 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2352,6 +2352,9 @@ void D_DoomMain (void) D_DoomInit(); + extern void D_ConfirmSendStats(); + D_ConfirmSendStats(); + // [RH] Make sure zdoom.pk3 is always loaded, // as it contains magic stuff we need. wad = BaseFileSearch (BASEWAD, NULL, true); diff --git a/src/d_stats.cpp b/src/d_stats.cpp index 58c83dfae..6205bf60f 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -5,6 +5,10 @@ void D_DoAnonStats() { } +void D_ConfirmSendStats() +{ +} + #else // !NO_SEND_STATS #if defined(_WIN32) @@ -14,6 +18,11 @@ void D_DoAnonStats() #include extern int sys_ostype; #else +#ifdef __APPLE__ +#include +#else // !__APPLE__ +#include +#endif // __APPLE__ #include #include #include @@ -29,6 +38,7 @@ extern int sys_ostype; EXTERN_CVAR(Bool, vid_glswfb) extern int currentrenderer; +CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) @@ -275,6 +285,11 @@ static void D_DoHTTPRequest(const char *request) void D_DoAnonStats() { + if (sys_statsenabled != 1) + { + return; + } + static bool done = false; // do this only once per session. if (done) return; done = true; @@ -291,4 +306,55 @@ void D_DoAnonStats() t1.detach(); } +void D_ConfirmSendStats() +{ + if (sys_statsenabled >= 0) + { + return; + } + + // TODO: texts + static const char *const MESSAGE_TEXT = "send stats?"; + static const char *const TITLE_TEXT = GAMENAME; + + UCVarValue enabled = { 0 }; + +#ifdef _WIN32 + extern HWND Window; + enabled.Int = MessageBox(Window, MESSAGE_TEXT, TITLE_TEXT, MB_ICONQUESTION | MB_YESNO) == IDYES; +#elif defined __APPLE__ + const CFStringRef messageString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, MESSAGE_TEXT, kCFStringEncodingASCII, kCFAllocatorNull); + const CFStringRef titleString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, TITLE_TEXT, kCFStringEncodingASCII, kCFAllocatorNull); + if (messageString != nullptr && titleString != nullptr) + { + CFOptionFlags response; + const SInt32 result = CFUserNotificationDisplayAlert(0, kCFUserNotificationNoteAlertLevel, nullptr, nullptr, nullptr, + titleString, messageString, CFSTR("Yes"), CFSTR("No"), nullptr, &response); + enabled.Int = result == 0 && (response & 3) == kCFUserNotificationDefaultResponse; + CFRelease(titleString); + CFRelease(messageString); + } +#else // !__APPLE__ + const SDL_MessageBoxButtonData buttons[] = + { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" }, + }; + const SDL_MessageBoxData messageboxdata = + { + SDL_MESSAGEBOX_INFORMATION, + nullptr, + TITLE_TEXT, + MESSAGE_TEXT, + SDL_arraysize(buttons), + buttons, + nullptr + }; + int buttonid; + enabled.Int = SDL_ShowMessageBox(&messageboxdata, &buttonid) == 0 && buttonid == 0; +#endif // _WIN32 + + sys_statsenabled.ForceSet(enabled, CVAR_Int); +} + #endif // NO_SEND_STATS From 7e169eb76fbe41900e7496cb3fa133d872b88256 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 12:36:14 +0100 Subject: [PATCH 14/37] - split out the span generation from most texture classes Until now each subclass of FTexture had to implement the entire span generation itself, presumably so that a few classes can use simpler structures. This does not work if a texture can have more than one pixel buffer as is needed for alpha textures. Even though it means that some classes will allocate more data now, it's the only way to do it properly. In addition this removes a significant amount of mostly redundant code from the texture classes. - added alpha texture processing to all converted classes As of now this is not active and not tested. Note that as part of the conversion even those textures that were working as alphatextures will not look correct until the higher level code gets adjusted. --- src/CMakeLists.txt | 1 + src/gl/textures/gl_texture.cpp | 21 +- src/gl/textures/gl_texture.h | 14 +- src/r_data/models/models_voxel.cpp | 75 ++----- src/swrenderer/line/r_walldraw.cpp | 1 - src/textures/automaptexture.cpp | 93 +-------- src/textures/bitmap.cpp | 3 +- src/textures/bitmap.h | 10 + src/textures/ddstexture.cpp | 230 ++++++++------------ src/textures/emptytexture.cpp | 47 +---- src/textures/flattexture.cpp | 103 +-------- src/textures/imgztexture.cpp | 111 +--------- src/textures/jpegtexture.cpp | 325 ++++++++++++----------------- src/textures/multipatchtexture.cpp | 147 ++++--------- src/textures/patchtexture.cpp | 163 +++------------ src/textures/pcxtexture.cpp | 110 ++-------- src/textures/pngtexture.cpp | 205 ++++++------------ src/textures/rawpagetexture.cpp | 98 +-------- src/textures/texture.cpp | 9 +- src/textures/textures.h | 34 ++- src/textures/tgatexture.cpp | 126 ++--------- 21 files changed, 497 insertions(+), 1429 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e75798a54..cfd970d6d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1110,6 +1110,7 @@ set (PCH_SOURCES textures/tgatexture.cpp textures/warptexture.cpp textures/skyboxtexture.cpp + textures/worldtexture.cpp xlat/parse_xlat.cpp fragglescript/t_func.cpp fragglescript/t_load.cpp diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 0d3e84e4b..0680ccdd6 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -523,24 +523,11 @@ FBrightmapTexture::FBrightmapTexture (FTexture *source) SourceLump = -1; } -FBrightmapTexture::~FBrightmapTexture () -{ -} - -const uint8_t *FBrightmapTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - // not needed - return NULL; -} - -const uint8_t *FBrightmapTexture::GetPixels () -{ - // not needed - return NULL; -} - -void FBrightmapTexture::Unload () +uint8_t *FBrightmapTexture::MakeTexture(FRenderStyle style) { + // This function is only necessary to satisfy the parent class's interface. + // This will never be called. + return nullptr; } int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) diff --git a/src/gl/textures/gl_texture.h b/src/gl/textures/gl_texture.h index 80eede02f..44016f181 100644 --- a/src/gl/textures/gl_texture.h +++ b/src/gl/textures/gl_texture.h @@ -4,23 +4,17 @@ #include "r_defs.h" #include "textures/textures.h" -class FBrightmapTexture : public FTexture +class FBrightmapTexture : public FWorldTexture { public: FBrightmapTexture (FTexture *source); - ~FBrightmapTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); - bool UseBasePalette() { return false; } + uint8_t *MakeTexture(FRenderStyle style) override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + bool UseBasePalette() override { return false; } protected: FTexture *SourcePic; - //uint8_t *Pixels; - //Span **Spans; }; diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 848f5a54d..9533aca69 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -53,23 +53,17 @@ // //=========================================================================== -class FVoxelTexture : public FTexture +class FVoxelTexture : public FWorldTexture { public: - FVoxelTexture(FVoxel *voxel); - ~FVoxelTexture(); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); - bool UseBasePalette() { return false; } + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + bool UseBasePalette() override { return false; } + uint8_t *MakeTexture(FRenderStyle style) override; protected: FVoxel *SourceVox; - uint8_t *Pixels; - }; //=========================================================================== @@ -86,7 +80,6 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) WidthBits = 4; HeightBits = 4; WidthMask = 15; - Pixels = NULL; gl_info.bNoFilter = true; gl_info.bNoCompress = true; } @@ -97,54 +90,32 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -FVoxelTexture::~FVoxelTexture() -{ -} - -const uint8_t *FVoxelTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - // not needed - return NULL; -} - -const uint8_t *FVoxelTexture::GetPixels () +uint8_t *FVoxelTexture::MakeTexture (FRenderStyle style) { // GetPixels gets called when a translated palette is used so we still need to implement it here. - if (Pixels == NULL) + auto Pixels = new uint8_t[256]; + uint8_t *pp = SourceVox->Palette; + + if(pp != NULL) { - Pixels = new uint8_t[256]; - - uint8_t *pp = SourceVox->Palette; - - if(pp != NULL) + for(int i=0;i<256;i++, pp+=3) { - for(int i=0;i<256;i++, pp+=3) - { - PalEntry pe; - pe.r = (pp[0] << 2) | (pp[0] >> 4); - pe.g = (pp[1] << 2) | (pp[1] >> 4); - pe.b = (pp[2] << 2) | (pp[2] >> 4); - Pixels[i] = ColorMatcher.Pick(pe); - } + PalEntry pe; + pe.r = (pp[0] << 2) | (pp[0] >> 4); + pe.g = (pp[1] << 2) | (pp[1] >> 4); + pe.b = (pp[2] << 2) | (pp[2] >> 4); + // Alphatexture handling is just for completeness, but rather unlikely to be used ever. + Pixels[i] = (style.Flags & STYLEF_RedIsAlpha)? pe.r : ColorMatcher.Pick(pe); } - else - { - for(int i=0;i<256;i++, pp+=3) - { - Pixels[i] = (uint8_t)i; - } - } } - return Pixels; -} - -void FVoxelTexture::Unload () -{ - if (Pixels != NULL) + else { - delete[] Pixels; - Pixels = NULL; - } + for(int i=0;i<256;i++, pp+=3) + { + Pixels[i] = (uint8_t)i; + } + } + return Pixels; } //=========================================================================== diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 5b7518440..ac277a0ae 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -330,7 +330,6 @@ namespace swrenderer if (rw_pic->UseType == FTexture::TEX_Null) return; - rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set int fracbits = 32 - rw_pic->HeightBits; if (fracbits == 32) { // Hack for one pixel tall textures diff --git a/src/textures/automaptexture.cpp b/src/textures/automaptexture.cpp index 3bd16f5bc..27080669e 100644 --- a/src/textures/automaptexture.cpp +++ b/src/textures/automaptexture.cpp @@ -38,6 +38,7 @@ #include "doomtype.h" #include "files.h" #include "w_wad.h" +#include "v_palette.h" #include "textures/textures.h" //========================================================================== @@ -46,21 +47,12 @@ // //========================================================================== -class FAutomapTexture : public FTexture +class FAutomapTexture : public FWorldTexture { public: + FAutomapTexture(int lumpnum); ~FAutomapTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - void MakeTexture (); - - FAutomapTexture (int lumpnum); - -private: - uint8_t *Pixels; - Span DummySpan[2]; + uint8_t *MakeTexture (FRenderStyle style); }; @@ -86,16 +78,11 @@ FTexture *AutomapTexture_TryCreate(FileReader &data, int lumpnum) //========================================================================== FAutomapTexture::FAutomapTexture (int lumpnum) -: FTexture(NULL, lumpnum), Pixels(NULL) +: FWorldTexture(NULL, lumpnum) { Width = 320; Height = uint16_t(Wads.LumpLength(lumpnum) / 320); CalcBitSize (); - - DummySpan[0].TopOffset = 0; - DummySpan[0].Length = Height; - DummySpan[1].TopOffset = 0; - DummySpan[1].Length = 0; } //========================================================================== @@ -104,84 +91,22 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -FAutomapTexture::~FAutomapTexture () -{ - Unload (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FAutomapTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FAutomapTexture::MakeTexture () +uint8_t *FAutomapTexture::MakeTexture (FRenderStyle style) { int x, y; FMemLump data = Wads.ReadLump (SourceLump); const uint8_t *indata = (const uint8_t *)data.GetMem(); - Pixels = new uint8_t[Width * Height]; + auto Pixels = new uint8_t[Width * Height]; for (x = 0; x < Width; ++x) { for (y = 0; y < Height; ++y) { - Pixels[x*Height+y] = indata[x+320*y]; + auto p = indata[x + 320 * y]; + Pixels[x*Height + y] = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p]; } } -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FAutomapTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } return Pixels; } -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FAutomapTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - column %= Width; - } - if (spans_out != NULL) - { - *spans_out = DummySpan; - } - return Pixels + column*Height; -} diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index cdeb645e3..33cfe2141 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -193,13 +193,14 @@ typedef void (*CopyFunc)(uint8_t *pout, const uint8_t *pin, int count, int step, iCopyColors, \ iCopyColors, \ iCopyColors, \ + iCopyColors, \ iCopyColors, \ iCopyColors, \ iCopyColors, \ iCopyColors, \ iCopyColors \ } -static const CopyFunc copyfuncs[][10]={ +static const CopyFunc copyfuncs[][11]={ COPY_FUNCS(bCopy), COPY_FUNCS(bBlend), COPY_FUNCS(bAdd), diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 0811eaa70..51d857ac4 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -235,6 +235,15 @@ struct cCMYK static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; } }; +struct cYCbCr +{ + static __forceinline unsigned char R(const unsigned char * p) { return clamp((int)(p[0] + 1.40200 * (int(p[2]) - 0x80)), 0, 255); } + static __forceinline unsigned char G(const unsigned char * p) { return clamp((int)(p[0] - 0.34414 * (int(p[1] - 0x80)) - 0.71414 * (int(p[2]) - 0x80)), 0, 255); } + static __forceinline unsigned char B(const unsigned char * p) { return clamp((int)(p[0] + 1.77200 * (int(p[1]) - 0x80)), 0, 255); } + static __forceinline unsigned char A(const unsigned char * p, uint8_t x, uint8_t y, uint8_t z) { return 255; } + static __forceinline int Gray(const unsigned char * p) { return (R(p) * 77 + G(p) * 143 + B(p) * 36) >> 8; } +}; + struct cBGR { static __forceinline unsigned char R(const unsigned char * p) { return p[2]; } @@ -310,6 +319,7 @@ enum ColorType CF_RGBA, CF_IA, CF_CMYK, + CF_YCbCr, CF_BGR, CF_BGRA, CF_I16, diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 9cde88ced..313682f14 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -153,22 +153,21 @@ struct DDSFileHeader // //========================================================================== -class FDDSTexture : public FTexture +class FDDSTexture : public FWorldTexture { + enum + { + PIX_Palette = 0, + PIX_Alphatex = 1, + PIX_ARGB = 2 + }; public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - ~FDDSTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - FTextureFormat GetFormat (); + FTextureFormat GetFormat () override; + uint8_t *MakeTexture(FRenderStyle style) override; protected: - - uint8_t *Pixels; - Span **Spans; - uint32_t Format; uint32_t RMask, GMask, BMask, AMask; @@ -180,11 +179,10 @@ protected: static void CalcBitShift (uint32_t mask, uint8_t *lshift, uint8_t *rshift); - void MakeTexture (); - void ReadRGB (FileReader &lump, uint8_t *tcbuf = NULL); - void DecompressDXT1 (FileReader &lump, uint8_t *tcbuf = NULL); - void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *tcbuf = NULL); - void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *tcbuf = NULL); + void ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode); + void DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmode); + void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); + void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); bool UseBasePalette(); @@ -287,7 +285,7 @@ FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum) //========================================================================== FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc) -: FTexture(NULL, lumpnum), Pixels(0), Spans(0) +: FWorldTexture(NULL, lumpnum) { DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc; @@ -381,38 +379,6 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -FDDSTexture::~FDDSTexture () -{ - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDDSTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - FTextureFormat FDDSTexture::GetFormat() { #if 0 @@ -437,88 +403,41 @@ FTextureFormat FDDSTexture::GetFormat() // //========================================================================== -const uint8_t *FDDSTexture::GetColumn (unsigned int column, const Span **spans_out) +uint8_t *FDDSTexture::MakeTexture (FRenderStyle style) { - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} + auto lump = Wads.OpenLumpReader (SourceLump); -//========================================================================== -// -// -// -//========================================================================== + auto Pixels = new uint8_t[Width*Height]; -const uint8_t *FDDSTexture::GetPixels () -{ - if (Pixels == NULL) + lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); + + int pmode = (style.Flags & STYLEF_RedIsAlpha) ? PIX_Alphatex : PIX_Palette; + if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel { - MakeTexture (); + ReadRGB (lump, Pixels, pmode); + } + else if (Format == ID_DXT1) + { + DecompressDXT1 (lump, Pixels, pmode); + } + else if (Format == ID_DXT3 || Format == ID_DXT2) + { + DecompressDXT3 (lump, Format == ID_DXT2, Pixels, pmode); + } + else if (Format == ID_DXT5 || Format == ID_DXT4) + { + DecompressDXT5 (lump, Format == ID_DXT4, Pixels, pmode); } return Pixels; } //========================================================================== // -// +// Note that pixel size == 8 is column-major, but 32 is row-major! // //========================================================================== -void FDDSTexture::MakeTexture () -{ - auto lump = Wads.OpenLumpReader (SourceLump); - - Pixels = new uint8_t[Width*Height]; - - lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); - - if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel - { - ReadRGB (lump); - } - else if (Format == ID_DXT1) - { - DecompressDXT1 (lump); - } - else if (Format == ID_DXT3 || Format == ID_DXT2) - { - DecompressDXT3 (lump, Format == ID_DXT2); - } - else if (Format == ID_DXT5 || Format == ID_DXT4) - { - DecompressDXT5 (lump, Format == ID_DXT4); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf) +void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode) { uint32_t x, y; uint32_t amask = AMask == 0 ? 0 : 0x80000000 >> AShiftL; @@ -527,7 +446,7 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf) for (y = Height; y > 0; --y) { uint8_t *buffp = linebuff; - uint8_t *pixelp = tcbuf? tcbuf + 4*y*Height : Pixels + y; + uint8_t *pixelp = pixelmode == PIX_ARGB? buffer + 4*y*Height : buffer + y; lump.Read (linebuff, Pitch); for (x = Width; x > 0; --x) { @@ -548,14 +467,21 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf) { c = *buffp++; } - if (!tcbuf) + if (pixelmode != PIX_ARGB) { if (amask == 0 || (c & amask)) { uint32_t r = (c & RMask) << RShiftL; r |= r >> RShiftR; - uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR; - uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR; - *pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26]; + if (pixelmode == PIX_Palette) + { + uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR; + uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR; + *pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26]; + } + else + { + *pixelp = uint8_t(r >> 24); + } } else { @@ -587,13 +513,13 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *tcbuf) // //========================================================================== -void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf) +void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmode) { const long blocklinelen = ((Width + 3) >> 2) << 3; uint8_t *blockbuff = new uint8_t[blocklinelen]; uint8_t *block; PalEntry color[4]; - uint8_t palcol[4]; + uint8_t palcol[4] = { 0,0,0,0 }; // shut up compiler warnings. int ox, oy, x, y, i; color[0].a = 255; @@ -639,9 +565,12 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf) bMasked = true; } // Pick colors from the palette for each of the four colors. - /*if (!tcbuf)*/ for (i = 3; i >= 0; --i) + if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0; + if (pixelmode == PIX_Palette) + palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0; + else + palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer. } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) @@ -658,13 +587,13 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf) break; } int ci = (yslice >> (x + x)) & 3; - if (!tcbuf) + if (pixelmode != PIX_ARGB) { - Pixels[oy + y + (ox + x) * Height] = palcol[ci]; + buffer[oy + y + (ox + x) * Height] = palcol[ci]; } else { - uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; + uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; tcp[0] = color[ci].r; tcp[1] = color[ci].g; tcp[2] = color[ci].b; @@ -685,13 +614,13 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *tcbuf) // //========================================================================== -void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *tcbuf) +void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode) { const long blocklinelen = ((Width + 3) >> 2) << 4; uint8_t *blockbuff = new uint8_t[blocklinelen]; uint8_t *block; PalEntry color[4]; - uint8_t palcol[4]; + uint8_t palcol[4] = { 0,0,0,0 }; int ox, oy, x, y, i; for (oy = 0; oy < Height; oy += 4) @@ -719,10 +648,14 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3; // Pick colors from the palette for each of the four colors. - if (!tcbuf) for (i = 3; i >= 0; --i) + if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2]; + if (pixelmode == PIX_Palette) + palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0; + else + palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer. } + // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) { @@ -738,14 +671,14 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t { break; } - if (!tcbuf) + if (pixelmode != PIX_ARGB) { - Pixels[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ? + buffer[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ? (bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3]; } else { - uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; + uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; tcp[0] = color[c].r; tcp[1] = color[c].g; @@ -767,13 +700,13 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t // //========================================================================== -void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *tcbuf) +void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode) { const long blocklinelen = ((Width + 3) >> 2) << 4; uint8_t *blockbuff = new uint8_t[blocklinelen]; uint8_t *block; PalEntry color[4]; - uint8_t palcol[4]; + uint8_t palcol[4] = { 0,0,0,0 }; uint32_t yalphaslice = 0; int ox, oy, x, y, i; @@ -824,9 +757,12 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3; // Pick colors from the palette for each of the four colors. - if (!tcbuf) for (i = 3; i >= 0; --i) + if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2]; + if (pixelmode == PIX_Palette) + palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0; + else + palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer. } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) @@ -851,14 +787,14 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t { break; } - if (!tcbuf) + if (pixelmode == 8) { - Pixels[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ? + buffer[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ? (bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3]; } else { - uint8_t * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; + uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; tcp[0] = color[c].r; tcp[1] = color[c].g; @@ -889,19 +825,19 @@ int FDDSTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel { - ReadRGB (lump, TexBuffer); + ReadRGB (lump, TexBuffer, PIX_ARGB); } else if (Format == ID_DXT1) { - DecompressDXT1 (lump, TexBuffer); + DecompressDXT1 (lump, TexBuffer, PIX_ARGB); } else if (Format == ID_DXT3 || Format == ID_DXT2) { - DecompressDXT3 (lump, Format == ID_DXT2, TexBuffer); + DecompressDXT3 (lump, Format == ID_DXT2, TexBuffer, PIX_ARGB); } else if (Format == ID_DXT5 || Format == ID_DXT4) { - DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer); + DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer, PIX_ARGB); } // All formats decompress to RGBA. diff --git a/src/textures/emptytexture.cpp b/src/textures/emptytexture.cpp index 45039cae2..19698551f 100644 --- a/src/textures/emptytexture.cpp +++ b/src/textures/emptytexture.cpp @@ -1,7 +1,8 @@ /* -** flattexture.cpp +** emptytexture.cpp ** Texture class for empty placeholder textures ** (essentially patches with dimensions and offsets of (0,0) ) +** These need special treatment because a texture size of 0 is illegal ** **--------------------------------------------------------------------------- ** Copyright 2009 Christoph Oelckers @@ -41,30 +42,21 @@ //========================================================================== // -// A texture defined between F_START and F_END markers +// // //========================================================================== -class FEmptyTexture : public FTexture +class FEmptyTexture : public FWorldTexture { + uint8_t Pixel = 0; public: FEmptyTexture (int lumpnum); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload() {} - -protected: - uint8_t Pixels[1]; - Span DummySpans[1]; + uint8_t *MakeTexture(FRenderStyle style) override; }; - - //========================================================================== // -// Since there is no way to detect the validity of a flat -// they can't be used anywhere else but between F_START and F_END +// // //========================================================================== @@ -86,15 +78,13 @@ FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FEmptyTexture::FEmptyTexture (int lumpnum) -: FTexture(NULL, lumpnum) +: FWorldTexture(NULL, lumpnum) { bMasked = true; WidthBits = HeightBits = 1; Width = Height = 1; WidthMask = 0; - DummySpans[0].TopOffset = 0; - DummySpans[0].Length = 0; - Pixels[0] = 0; + PixelsAreStatic = 3; } //========================================================================== @@ -103,23 +93,8 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -const uint8_t *FEmptyTexture::GetColumn (unsigned int column, const Span **spans_out) +uint8_t *FEmptyTexture::MakeTexture(FRenderStyle style) { - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FEmptyTexture::GetPixels () -{ - return Pixels; + return &Pixel; } diff --git a/src/textures/flattexture.cpp b/src/textures/flattexture.cpp index 408acb099..7581b3a6e 100644 --- a/src/textures/flattexture.cpp +++ b/src/textures/flattexture.cpp @@ -45,24 +45,11 @@ // //========================================================================== -class FFlatTexture : public FTexture +class FFlatTexture : public FWorldTexture { public: FFlatTexture (int lumpnum); - ~FFlatTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - -protected: - uint8_t *Pixels; - Span DummySpans[2]; - - - void MakeTexture (); - - friend class FTexture; + uint8_t *MakeTexture (FRenderStyle style) override; }; @@ -86,7 +73,7 @@ FTexture *FlatTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FFlatTexture::FFlatTexture (int lumpnum) -: FTexture(NULL, lumpnum), Pixels(0) +: FWorldTexture(NULL, lumpnum) { int area; int bits; @@ -108,10 +95,6 @@ FFlatTexture::FFlatTexture (int lumpnum) WidthBits = HeightBits = bits; Width = Height = 1 << bits; WidthMask = (1 << bits) - 1; - DummySpans[0].TopOffset = 0; - DummySpans[0].Length = Height; - DummySpans[1].TopOffset = 0; - DummySpans[1].Length = 0; } //========================================================================== @@ -120,87 +103,17 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -FFlatTexture::~FFlatTexture () -{ - Unload (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FFlatTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FFlatTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatTexture::MakeTexture () +uint8_t *FFlatTexture::MakeTexture (FRenderStyle style) { auto lump = Wads.OpenLumpReader (SourceLump); - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; auto numread = lump.Read (Pixels, Width*Height); if (numread < Width*Height) { memset (Pixels + numread, 0xBB, Width*Height - numread); } - FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap); + if (!(style.Flags & STYLEF_RedIsAlpha)) FTexture::FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap); + else FTexture::FlipSquareBlock(Pixels, Width, Height); + return Pixels; } diff --git a/src/textures/imgztexture.cpp b/src/textures/imgztexture.cpp index 1f623d084..e21074055 100644 --- a/src/textures/imgztexture.cpp +++ b/src/textures/imgztexture.cpp @@ -36,6 +36,7 @@ #include "doomtype.h" #include "files.h" #include "w_wad.h" +#include "v_palette.h" #include "textures/textures.h" @@ -47,7 +48,7 @@ // //========================================================================== -class FIMGZTexture : public FTexture +class FIMGZTexture : public FWorldTexture { struct ImageHeader { @@ -62,18 +63,7 @@ class FIMGZTexture : public FTexture public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t); - ~FIMGZTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - -protected: - - uint8_t *Pixels; - Span **Spans; - - void MakeTexture (); + uint8_t *MakeTexture (FRenderStyle style) override; }; @@ -106,7 +96,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t) - : FTexture(NULL, lumpnum), Pixels(0), Spans(0) + : FWorldTexture(NULL, lumpnum) { Wads.GetLumpName (Name, lumpnum); Width = w; @@ -122,88 +112,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -FIMGZTexture::~FIMGZTexture () -{ - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FIMGZTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FIMGZTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FIMGZTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -void FIMGZTexture::MakeTexture () +uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style) { FMemLump lump = Wads.ReadLump (SourceLump); const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); @@ -222,7 +131,7 @@ void FIMGZTexture::MakeTexture () int dest_rew = Width * Height - 1; CalcBitSize (); - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; dest_p = Pixels; // Convert the source image from row-major to column-major format @@ -232,7 +141,8 @@ void FIMGZTexture::MakeTexture () { for (int x = Width; x != 0; --x) { - *dest_p = *data; + auto p = *data; + *dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p]; dest_p += dest_adv; data++; } @@ -251,8 +161,8 @@ void FIMGZTexture::MakeTexture () { if (runlen != 0) { - uint8_t color = *data; - *dest_p = color; + auto p = *data; + *dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p]; dest_p += dest_adv; data++; x--; @@ -282,5 +192,6 @@ void FIMGZTexture::MakeTexture () dest_p -= dest_rew; } } + return Pixels; } diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index c9f19c1da..abf1e34ec 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -179,27 +179,16 @@ void JPEG_OutputMessage (j_common_ptr cinfo) // //========================================================================== -class FJPEGTexture : public FTexture +class FJPEGTexture : public FWorldTexture { public: FJPEGTexture (int lumpnum, int width, int height); ~FJPEGTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - FTextureFormat GetFormat (); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - bool UseBasePalette(); - -protected: - - uint8_t *Pixels; - Span DummySpans[2]; - - void MakeTexture (); - - friend class FTexture; + FTextureFormat GetFormat () override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + bool UseBasePalette() override; + uint8_t *MakeTexture (FRenderStyle style) override; }; //========================================================================== @@ -259,7 +248,7 @@ FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum) //========================================================================== FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) -: FTexture(NULL, lumpnum), Pixels(0) +: FWorldTexture(NULL, lumpnum) { UseType = TEX_MiscPatch; LeftOffset = 0; @@ -269,35 +258,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) Width = width; Height = height; CalcBitSize (); - - DummySpans[0].TopOffset = 0; - DummySpans[0].Length = Height; - DummySpans[1].TopOffset = 0; - DummySpans[1].Length = 0; -} - -//========================================================================== -// -// -// -//========================================================================== - -FJPEGTexture::~FJPEGTexture () -{ - Unload (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FJPEGTexture::Unload () -{ - delete[] Pixels; - Pixels = NULL; - FTexture::Unload(); } //========================================================================== @@ -317,142 +277,123 @@ FTextureFormat FJPEGTexture::GetFormat() // //========================================================================== -const uint8_t *FJPEGTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FJPEGTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -void FJPEGTexture::MakeTexture () +uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) { auto lump = Wads.OpenLumpReader (SourceLump); JSAMPLE *buff = NULL; + bool doalpha = !!(style.Flags & STYLEF_RedIsAlpha); jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; - Pixels = new uint8_t[Width * Height]; + auto Pixels = new uint8_t[Width * Height]; memset (Pixels, 0xBA, Width * Height); cinfo.err = jpeg_std_error(&jerr); cinfo.err->output_message = JPEG_OutputMessage; cinfo.err->error_exit = JPEG_ErrorExit; jpeg_create_decompress(&cinfo); + + FLumpSourceMgr sourcemgr(&lump, &cinfo); try { - FLumpSourceMgr sourcemgr(&lump, &cinfo); jpeg_read_header(&cinfo, TRUE); if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) + (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || + (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || + (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf (TEXTCOLOR_ORANGE "Unsupported color format\n"); - throw -1; + Printf(TEXTCOLOR_ORANGE, "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } - - jpeg_start_decompress(&cinfo); - - int y = 0; - buff = new uint8_t[cinfo.output_width * cinfo.output_components]; - - while (cinfo.output_scanline < cinfo.output_height) + else { - int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1); - uint8_t *in = buff; - uint8_t *out = Pixels + y; - switch (cinfo.out_color_space) + jpeg_start_decompress(&cinfo); + + int y = 0; + buff = new uint8_t[cinfo.output_width * cinfo.output_components]; + + while (cinfo.output_scanline < cinfo.output_height) { - case JCS_RGB: - for (int x = Width; x > 0; --x) + int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1); + uint8_t *in = buff; + uint8_t *out = Pixels + y; + switch (cinfo.out_color_space) { - *out = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; - out += Height; - in += 3; - } - break; + case JCS_RGB: + for (int x = Width; x > 0; --x) + { + *out = !doalpha? RGB256k.RGB[in[0] >> 2][in[1] >> 2][in[2] >> 2] : in[0]; + out += Height; + in += 3; + } + break; - case JCS_GRAYSCALE: - for (int x = Width; x > 0; --x) - { - *out = GrayMap[in[0]]; - out += Height; - in += 1; - } - break; + case JCS_GRAYSCALE: + for (int x = Width; x > 0; --x) + { + *out = !doalpha ? FTexture::GrayMap[in[0]] : in[0]; + out += Height; + in += 1; + } + break; - case JCS_CMYK: - // What are you doing using a CMYK image? :) - for (int x = Width; x > 0; --x) - { - // To be precise, these calculations should use 255, but - // 256 is much faster and virtually indistinguishable. - int r = in[3] - (((256-in[0])*in[3]) >> 8); - int g = in[3] - (((256-in[1])*in[3]) >> 8); - int b = in[3] - (((256-in[2])*in[3]) >> 8); - *out = RGB256k.RGB[r >> 2][g >> 2][b >> 2]; - out += Height; - in += 4; - } - break; + case JCS_CMYK: + // What are you doing using a CMYK image? :) + for (int x = Width; x > 0; --x) + { + // To be precise, these calculations should use 255, but + // 256 is much faster and virtually indistinguishable. + int r = in[3] - (((256 - in[0])*in[3]) >> 8); + if (!doalpha) + { + int g = in[3] - (((256 - in[1])*in[3]) >> 8); + int b = in[3] - (((256 - in[2])*in[3]) >> 8); + *out = RGB256k.RGB[r >> 2][g >> 2][b >> 2]; + } + else *out = (uint8_t)r; + out += Height; + in += 4; + } + break; - default: - // The other colorspaces were considered above and discarded, - // but GCC will complain without a default for them here. - break; + case JCS_YCbCr: + // Probably useless but since I had the formula available... + for (int x = Width; x > 0; --x) + { + double Y = in[0], Cb = in[1], Cr = in[2]; + int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255); + if (!doalpha) + { + int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255); + int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255); + *out = RGB256k.RGB[r >> 2][g >> 2][b >> 2]; + } + else *out = (uint8_t)r; + out += Height; + in += 4; + } + break; + + default: + // The other colorspaces were considered above and discarded, + // but GCC will complain without a default for them here. + break; + } + y++; } - y++; + jpeg_finish_decompress(&cinfo); } - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); } catch (int) { - Printf (TEXTCOLOR_ORANGE " in texture %s\n", Name.GetChars()); - jpeg_destroy_decompress(&cinfo); + Printf(TEXTCOLOR_ORANGE, "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } + jpeg_destroy_decompress(&cinfo); if (buff != NULL) { delete[] buff; } + return Pixels; } @@ -479,58 +420,66 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC cinfo.err->error_exit = JPEG_ErrorExit; jpeg_create_decompress(&cinfo); + FLumpSourceMgr sourcemgr(&lump, &cinfo); try { - FLumpSourceMgr sourcemgr(&lump, &cinfo); jpeg_read_header(&cinfo, TRUE); if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) + (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || + (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || + (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf (TEXTCOLOR_ORANGE "Unsupported color format\n"); - throw -1; + Printf(TEXTCOLOR_ORANGE, "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } - jpeg_start_decompress(&cinfo); - - int yc = 0; - buff = new uint8_t[cinfo.output_height * cinfo.output_width * cinfo.output_components]; - - - while (cinfo.output_scanline < cinfo.output_height) + else { - uint8_t * ptr = buff + cinfo.output_width * cinfo.output_components * yc; - jpeg_read_scanlines(&cinfo, &ptr, 1); - yc++; + jpeg_start_decompress(&cinfo); + + int yc = 0; + buff = new uint8_t[cinfo.output_height * cinfo.output_width * cinfo.output_components]; + + + while (cinfo.output_scanline < cinfo.output_height) + { + uint8_t * ptr = buff + cinfo.output_width * cinfo.output_components * yc; + jpeg_read_scanlines(&cinfo, &ptr, 1); + yc++; + } + + switch (cinfo.out_color_space) + { + case JCS_RGB: + bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, + 3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB, inf); + break; + + case JCS_GRAYSCALE: + for (int i = 0; i < 256; i++) pe[i] = PalEntry(255, i, i, i); // default to a gray map + bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height, + 1, cinfo.output_width, rotate, pe, inf); + break; + + case JCS_CMYK: + bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, + 4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK, inf); + break; + + case JCS_YCbCr: + bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, + 4, cinfo.output_width * cinfo.output_components, rotate, CF_YCbCr, inf); + break; + + default: + assert(0); + break; + } + jpeg_finish_decompress(&cinfo); } - - switch (cinfo.out_color_space) - { - case JCS_RGB: - bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, - 3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB, inf); - break; - - case JCS_GRAYSCALE: - for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // default to a gray map - bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height, - 1, cinfo.output_width, rotate, pe, inf); - break; - - case JCS_CMYK: - bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK, inf); - break; - - default: - assert(0); - break; - } - jpeg_finish_decompress(&cinfo); } - catch(int) + catch (int) { - Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name.GetChars()); + Printf(TEXTCOLOR_ORANGE, "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } jpeg_destroy_decompress(&cinfo); if (buff != NULL) delete [] buff; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index e5beb246f..e2bf932e9 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -148,24 +148,21 @@ struct FPatchLookup // //========================================================================== -class FMultiPatchTexture : public FTexture +class FMultiPatchTexture : public FWorldTexture { public: FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); FMultiPatchTexture (FScanner &sc, int usetype); ~FMultiPatchTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - FTextureFormat GetFormat(); - bool UseBasePalette() ; - void Unload (); - virtual void SetFrontSkyLayer (); + FTextureFormat GetFormat() override; + bool UseBasePalette() override; + virtual void SetFrontSkyLayer () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - int GetSourceLump() { return DefinitionLump; } - FTexture *GetRedirect(bool wantwarped); - FTexture *GetRawTexture(); + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int GetSourceLump() override { return DefinitionLump; } + FTexture *GetRedirect(bool wantwarped) override; + FTexture *GetRawTexture() override; void ResolvePatches(); protected: @@ -201,7 +198,7 @@ protected: bool bRedirect:1; bool bTranslucentPatches:1; - void MakeTexture (); + uint8_t *MakeTexture (FRenderStyle style); private: void CheckForHacks (); @@ -323,11 +320,6 @@ FMultiPatchTexture::~FMultiPatchTexture () delete[] Inits; Inits = nullptr; } - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } } //========================================================================== @@ -345,80 +337,6 @@ void FMultiPatchTexture::SetFrontSkyLayer () bNoRemap0 = true; } -//========================================================================== -// -// FMultiPatchTexture :: Unload -// -//========================================================================== - -void FMultiPatchTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// FMultiPatchTexture :: GetPixels -// -//========================================================================== - -const uint8_t *FMultiPatchTexture::GetPixels () -{ - if (bRedirect) - { - return Parts->Texture->GetPixels (); - } - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetColumn -// -//========================================================================== - -const uint8_t *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (bRedirect) - { - return Parts->Texture->GetColumn (column, spans_out); - } - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - - //========================================================================== // // GetBlendMap @@ -427,7 +345,6 @@ const uint8_t *FMultiPatchTexture::GetColumn (unsigned int column, const Span ** uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) { - switch (blend.a==0 ? int(blend) : -1) { case BLEND_ICEMAP: @@ -480,39 +397,54 @@ uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) // //========================================================================== -void FMultiPatchTexture::MakeTexture () +uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style) { // Add a little extra space at the end if the texture's height is not // a power of 2, in case somebody accidentally makes it repeat vertically. int numpix = Width * Height + (1 << HeightBits) - Height; uint8_t blendwork[256]; - bool hasTranslucent = false; + bool buildrgb = bComplex; - Pixels = new uint8_t[numpix]; + auto Pixels = new uint8_t[numpix]; memset (Pixels, 0, numpix); - for (int i = 0; i < NumParts; ++i) + if (style.Flags & STYLEF_RedIsAlpha) { - if (Parts[i].op != OP_COPY) + // The rules here are as follows: + // A texture uses its palette index as alpha only if it reports to use the base palette. + // In summary this means: + // If a texture is marked 'complex', it will use the red channel. + // If a texture uses non-base-palette patches, it will use the red channel for all pixels, even those coming from a base palette patch. + // If a texture only uses base-palette patches and no compositing effects it will use the palette index. + // + buildrgb = !UseBasePalette(); + } + else + { + // For regular textures we can use paletted compositing if all patches are just being copied because they all can create a paletted buffer. + if (!buildrgb) for (int i = 0; i < NumParts; ++i) { - hasTranslucent = true; + if (Parts[i].op != OP_COPY) + { + buildrgb = true; + } } } - if (!hasTranslucent) - { + if (!buildrgb) + { for (int i = 0; i < NumParts; ++i) { if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - uint8_t *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL; + uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr; { if (Parts[i].Blend != 0) { trans = GetBlendMap(Parts[i].Blend, blendwork); } Parts[i].Texture->CopyToBlock (Pixels, Width, Height, - Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans); + Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style); } } } @@ -531,7 +463,7 @@ void FMultiPatchTexture::MakeTexture () { if (*out == 0 && in[3] != 0) { - *out = RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2]; + *out = (style.Flags & STYLEF_RedIsAlpha)? in[2]*in[3] : RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2]; } out += Height; in += 4; @@ -539,6 +471,7 @@ void FMultiPatchTexture::MakeTexture () } delete [] buffer; } + return Pixels; } //=========================================================================== @@ -755,14 +688,6 @@ void FMultiPatchTexture::CheckForHacks () break; } } - - if (i == NumParts) - { - for (i = 0; i < NumParts; ++i) - { - Parts[i].Texture->HackHack(256); - } - } } } diff --git a/src/textures/patchtexture.cpp b/src/textures/patchtexture.cpp index c964b9a53..b4a8e3909 100644 --- a/src/textures/patchtexture.cpp +++ b/src/textures/patchtexture.cpp @@ -39,6 +39,7 @@ #include "templates.h" #include "v_palette.h" #include "textures/textures.h" +#include "r_data/r_translate.h" // posts are runs of non masked source pixels @@ -55,24 +56,13 @@ struct column_t // //========================================================================== -class FPatchTexture : public FTexture +class FPatchTexture : public FWorldTexture { + bool badflag = false; public: FPatchTexture (int lumpnum, patch_t *header); - ~FPatchTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - -protected: - uint8_t *Pixels; - Span **Spans; - bool hackflag; - - - virtual void MakeTexture (); - void HackHack (int newheight); + uint8_t *MakeTexture (FRenderStyle style) override; + void DetectBadPatches(); }; //========================================================================== @@ -149,12 +139,13 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FPatchTexture::FPatchTexture (int lumpnum, patch_t * header) -: FTexture(NULL, lumpnum), Pixels(0), Spans(0), hackflag(false) +: FWorldTexture(NULL, lumpnum) { Width = header->width; Height = header->height; LeftOffset = header->leftoffset; TopOffset = header->topoffset; + DetectBadPatches(); CalcBitSize (); } @@ -164,89 +155,7 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header) // //========================================================================== -FPatchTexture::~FPatchTexture () -{ - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FPatchTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FPatchTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FPatchTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans(Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FPatchTexture::MakeTexture () +uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) { uint8_t *remap, remaptable[256]; int numspans; @@ -258,23 +167,11 @@ void FPatchTexture::MakeTexture () maxcol = (const column_t *)((const uint8_t *)patch + Wads.LumpLength (SourceLump) - 3); - // Check for badly-sized patches -#if 0 // Such textures won't be created so there's no need to check here - if (LittleShort(patch->width) <= 0 || LittleShort(patch->height) <= 0) + if (style.Flags & STYLEF_RedIsAlpha) { - lump = Wads.ReadLump ("-BADPATC"); - patch = (const patch_t *)lump.GetMem(); - Printf (PRINT_BOLD, "Patch %s has a non-positive size.\n", Name); + remap = translationtables[TRANSLATION_Standard][8]->Remap; } - else if (LittleShort(patch->width) > 2048 || LittleShort(patch->height) > 2048) - { - lump = Wads.ReadLump ("-BADPATC"); - patch = (const patch_t *)lump.GetMem(); - Printf (PRINT_BOLD, "Patch %s is too big.\n", Name); - } -#endif - - if (bNoRemap0) + else if (bNoRemap0) { memcpy (remaptable, GPalette.Remap, 256); remaptable[0] = 0; @@ -286,9 +183,9 @@ void FPatchTexture::MakeTexture () } - if (hackflag) + if (badflag) { - Pixels = new uint8_t[Width * Height]; + auto Pixels = new uint8_t[Width * Height]; uint8_t *out; // Draw the image to the buffer @@ -302,7 +199,7 @@ void FPatchTexture::MakeTexture () out++, in++; } } - return; + return Pixels; } // Add a little extra space at the end if the texture's height is not @@ -311,7 +208,7 @@ void FPatchTexture::MakeTexture () numspans = Width; - Pixels = new uint8_t[numpix]; + auto Pixels = new uint8_t[numpix]; memset (Pixels, 0, numpix); // Draw the image to the buffer @@ -355,6 +252,7 @@ void FPatchTexture::MakeTexture () column = (const column_t *)((const uint8_t *)column + column->length + 4); } } + return Pixels; } @@ -364,8 +262,11 @@ void FPatchTexture::MakeTexture () // //========================================================================== -void FPatchTexture::HackHack (int newheight) +void FPatchTexture::DetectBadPatches () { + // The patch must look like it is large enough for the rules to apply to avoid using this on truly empty patches. + if (Wads.LumpLength(SourceLump) < Width * Height / 2) return; + // Check if this patch is likely to be a problem. // It must be 256 pixels tall, and all its columns must have exactly // one post, where each post has a supposed length of 0. @@ -381,29 +282,17 @@ void FPatchTexture::HackHack (int newheight) const column_t *col = (column_t*)((uint8_t*)realpatch+LittleLong(cofs[x])); if (col->topdelta != 0 || col->length != 0) { - break; // It's not bad! + return; // It's not bad! } col = (column_t *)((uint8_t *)col + 256 + 4); if (col->topdelta != 0xFF) { - break; // More than one post in a column! + return; // More than one post in a column! } } - if (x == x2) - { - // If all the columns were checked, it needs fixing. - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - } - - Height = newheight; - LeftOffset = 0; - TopOffset = 0; - - hackflag = true; - bMasked = false; // Hacked textures don't have transparent parts. - } + LeftOffset = 0; + TopOffset = 0; + badflag = true; + bMasked = false; // Hacked textures don't have transparent parts. } } diff --git a/src/textures/pcxtexture.cpp b/src/textures/pcxtexture.cpp index 75331caa5..efe12e3c2 100644 --- a/src/textures/pcxtexture.cpp +++ b/src/textures/pcxtexture.cpp @@ -81,32 +81,24 @@ struct PCXHeader // //========================================================================== -class FPCXTexture : public FTexture +class FPCXTexture : public FWorldTexture { public: FPCXTexture (int lumpnum, PCXHeader &); ~FPCXTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - FTextureFormat GetFormat (); + FTextureFormat GetFormat () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - bool UseBasePalette(); + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + bool UseBasePalette() override; protected: - uint8_t *Pixels; - Span DummySpans[2]; - void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - virtual void MakeTexture (); - - friend class FTexture; + uint8_t *MakeTexture (FRenderStyle style) override; }; @@ -154,44 +146,12 @@ FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FPCXTexture::FPCXTexture(int lumpnum, PCXHeader & hdr) -: FTexture(NULL, lumpnum), Pixels(0) +: FWorldTexture(NULL, lumpnum) { bMasked = false; Width = LittleShort(hdr.xmax) - LittleShort(hdr.xmin) + 1; Height = LittleShort(hdr.ymax) - LittleShort(hdr.ymin) + 1; CalcBitSize(); - - DummySpans[0].TopOffset = 0; - DummySpans[0].Length = Height; - DummySpans[1].TopOffset = 0; - DummySpans[1].Length = 0; -} - -//========================================================================== -// -// -// -//========================================================================== - -FPCXTexture::~FPCXTexture () -{ - Unload (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FPCXTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); } //========================================================================== @@ -211,51 +171,6 @@ FTextureFormat FPCXTexture::GetFormat() // //========================================================================== -const uint8_t *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FPCXTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr) { int y, i, bytes; @@ -457,18 +372,19 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -void FPCXTexture::MakeTexture() +uint8_t *FPCXTexture::MakeTexture(FRenderStyle style) { uint8_t PaletteMap[256]; PCXHeader header; int bitcount; + bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); auto lump = Wads.OpenLumpReader(SourceLump); lump.Read(&header, sizeof(header)); bitcount = header.bitsPerPixel * header.numColorPlanes; - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; if (bitcount < 24) { @@ -476,7 +392,8 @@ void FPCXTexture::MakeTexture() { for (int i=0;i<16;i++) { - PaletteMap[i] = ColorMatcher.Pick(header.palette[i*3],header.palette[i*3+1],header.palette[i*3+2]); + if (!alphatex) PaletteMap[i] = ColorMatcher.Pick(header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]); + else PaletteMap[i] = header.palette[i * 3]; } switch (bitcount) @@ -502,7 +419,7 @@ void FPCXTexture::MakeTexture() uint8_t r = lump.ReadUInt8(); uint8_t g = lump.ReadUInt8(); uint8_t b = lump.ReadUInt8(); - PaletteMap[i] = ColorMatcher.Pick(r,g,b); + PaletteMap[i] = !alphatex? ColorMatcher.Pick(r,g,b) : r; } lump.Seek(sizeof(header), FileReader::SeekSet); ReadPCX8bits (Pixels, lump, &header); @@ -529,12 +446,13 @@ void FPCXTexture::MakeTexture() { for(int x=0; x < Width; x++) { - Pixels[y+Height*x] = RGB256k.RGB[row[0]>>2][row[1]>>2][row[2]>>2]; + Pixels[y + Height * x] = !alphatex? RGB256k.RGB[row[0] >> 2][row[1] >> 2][row[2] >> 2] : row[0]; row+=3; } } delete [] buffer; } + return Pixels; } //=========================================================================== diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 480502c33..00a7ba701 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -48,24 +48,21 @@ // //========================================================================== -class FPNGTexture : public FTexture +class FPNGTexture : public FWorldTexture { public: FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); - ~FPNGTexture (); + ~FPNGTexture(); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - FTextureFormat GetFormat (); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - bool UseBasePalette(); + FTextureFormat GetFormat () override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + bool UseBasePalette() override; + uint8_t *MakeTexture(FRenderStyle style) override; protected: + void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); FString SourceFile; - uint8_t *Pixels; - Span **Spans; FileReader fr; uint8_t BitDepth; @@ -74,13 +71,10 @@ protected: bool HaveTrans; uint16_t NonPaletteTrans[3]; - uint8_t *PaletteMap; - int PaletteSize; - uint32_t StartOfIDAT; - - void MakeTexture (); - - friend class FTexture; + uint8_t *PaletteMap = nullptr; + int PaletteSize = 0; + uint32_t StartOfIDAT = 0; + uint32_t StartOfPalette = 0; }; @@ -200,9 +194,8 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename) FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t depth, uint8_t colortype, uint8_t interlace) -: FTexture(NULL, lumpnum), SourceFile(filename), Pixels(0), Spans(0), - BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false), - PaletteMap(0), PaletteSize(0), StartOfIDAT(0) +: FWorldTexture(NULL, lumpnum), SourceFile(filename), + BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false) { union { @@ -265,6 +258,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename case MAKE_ID('P','L','T','E'): PaletteSize = MIN (len / 3, 256); + StartOfPalette = (uint32_t)lump.Tell(); lump.Read (p.pngpal, PaletteSize * 3); if (PaletteSize * 3 != (int)len) { @@ -284,11 +278,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename NonPaletteTrans[1] = uint16_t(trans[2] * 256 + trans[3]); NonPaletteTrans[2] = uint16_t(trans[4] * 256 + trans[5]); break; - - case MAKE_ID('a','l','P','h'): - bAlphaTexture = true; - bMasked = true; - break; } lump.Seek(4, FileReader::SeekCur); // Skip CRC lump.Read(&len, 4); @@ -304,20 +293,17 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename // intentional fall-through case 0: // Grayscale - if (!bAlphaTexture) + if (colortype == 0 && HaveTrans && NonPaletteTrans[0] < 256) { - if (colortype == 0 && HaveTrans && NonPaletteTrans[0] < 256) - { - bMasked = true; - PaletteSize = 256; - PaletteMap = new uint8_t[256]; - memcpy (PaletteMap, GrayMap, 256); - PaletteMap[NonPaletteTrans[0]] = 0; - } - else - { - PaletteMap = GrayMap; - } + bMasked = true; + PaletteSize = 256; + PaletteMap = new uint8_t[256]; + memcpy (PaletteMap, GrayMap, 256); + PaletteMap[NonPaletteTrans[0]] = 0; + } + else + { + PaletteMap = GrayMap; } break; @@ -354,16 +340,10 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename FPNGTexture::~FPNGTexture () { - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } - if (PaletteMap != NULL && PaletteMap != GrayMap) + if (PaletteMap != nullptr && PaletteMap != FTexture::GrayMap) { delete[] PaletteMap; - PaletteMap = NULL; + PaletteMap = nullptr; } } @@ -373,19 +353,6 @@ FPNGTexture::~FPNGTexture () // //========================================================================== -void FPNGTexture::Unload () -{ - delete[] Pixels; - Pixels = NULL; - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - FTextureFormat FPNGTexture::GetFormat() { #if 0 @@ -407,32 +374,18 @@ FTextureFormat FPNGTexture::GetFormat() // //========================================================================== -const uint8_t *FPNGTexture::GetColumn (unsigned int column, const Span **spans_out) +void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) { - if (Pixels == NULL) + auto p = lump->Tell(); + lump->Seek(StartOfPalette, FileReader::SeekSet); + for (int i = 0; i < PaletteSize; i++) { - MakeTexture (); + uint8_t r = lump->ReadUInt8(); + lump->ReadUInt8(); // Skip g and b. + lump->ReadUInt8(); + alpharemap[i] = PaletteMap[i] == 0? 0 : r; } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; + lump->Seek(p, FileReader::SeekSet); } //========================================================================== @@ -441,26 +394,11 @@ const uint8_t *FPNGTexture::GetColumn (unsigned int column, const Span **spans_o // //========================================================================== -const uint8_t *FPNGTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FPNGTexture::MakeTexture () +uint8_t *FPNGTexture::MakeTexture (FRenderStyle style) { FileReader *lump; FileReader lfr; + bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); if (SourceLump >= 0) { @@ -472,7 +410,7 @@ void FPNGTexture::MakeTexture () lump = &fr; } - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; if (StartOfIDAT == 0) { memset (Pixels, 0x99, Width*Height); @@ -490,25 +428,37 @@ void FPNGTexture::MakeTexture () if (Width == Height) { - if (PaletteMap != NULL) + if (!alphatex) { - FlipSquareBlockRemap (Pixels, Width, Height, PaletteMap); + FTexture::FlipSquareBlockRemap (Pixels, Width, Height, PaletteMap); + } + else if (ColorType == 0) + { + FTexture::FlipSquareBlock (Pixels, Width, Height); } else { - FlipSquareBlock (Pixels, Width, Height); + uint8_t alpharemap[256]; + ReadAlphaRemap(lump, alpharemap); + FTexture::FlipSquareBlockRemap(Pixels, Width, Height, alpharemap); } } else { uint8_t *newpix = new uint8_t[Width*Height]; - if (PaletteMap != NULL) + if (!alphatex) { - FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap); + FTexture::FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap); + } + else if (ColorType == 0) + { + FTexture::FlipNonSquareBlock (newpix, Pixels, Width, Height, Width); } else { - FlipNonSquareBlock (newpix, Pixels, Width, Height, Width); + uint8_t alpharemap[256]; + ReadAlphaRemap(lump, alpharemap); + FTexture::FlipNonSquareBlockRemap(newpix, Pixels, Width, Height, Width, alpharemap); } uint8_t *oldpix = Pixels; Pixels = newpix; @@ -537,22 +487,13 @@ void FPNGTexture::MakeTexture () { for (y = Height; y > 0; --y) { - if (!HaveTrans) + if (HaveTrans && in[0] == NonPaletteTrans[0] && in[1] == NonPaletteTrans[1] && in[2] == NonPaletteTrans[2]) { - *out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; + *out++ = 0; } else { - if (in[0] == NonPaletteTrans[0] && - in[1] == NonPaletteTrans[1] && - in[2] == NonPaletteTrans[2]) - { - *out++ = 0; - } - else - { - *out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; - } + *out++ = alphatex? in[0] : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; } in += pitch; } @@ -563,29 +504,14 @@ void FPNGTexture::MakeTexture () case 4: // Grayscale + Alpha pitch = Width * 2; backstep = Height * pitch - 2; - if (PaletteMap != NULL) + for (x = Width; x > 0; --x) { - for (x = Width; x > 0; --x) + for (y = Height; y > 0; --y) { - for (y = Height; y > 0; --y) - { - *out++ = in[1] < 128 ? 0 : PaletteMap[in[0]]; - in += pitch; - } - in -= backstep; - } - } - else - { - for (x = Width; x > 0; --x) - { - for (y = Height; y > 0; --y) - { - *out++ = in[1] < 128 ? 0 : in[0]; - in += pitch; - } - in -= backstep; + *out++ = alphatex? ((in[0] * in[1]) >> 8) : in[1] < 128 ? 0 : PaletteMap[in[0]]; + in += pitch; } + in -= backstep; } break; @@ -596,7 +522,7 @@ void FPNGTexture::MakeTexture () { for (y = Height; y > 0; --y) { - *out++ = in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; + *out++ = alphatex? ((in[0] * in[3]) >> 8) : in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; in += pitch; } in -= backstep; @@ -606,6 +532,7 @@ void FPNGTexture::MakeTexture () delete[] tempix; } } + return Pixels; } //=========================================================================== diff --git a/src/textures/rawpagetexture.cpp b/src/textures/rawpagetexture.cpp index 99354bb66..7e9268c6e 100644 --- a/src/textures/rawpagetexture.cpp +++ b/src/textures/rawpagetexture.cpp @@ -46,21 +46,12 @@ // //========================================================================== -class FRawPageTexture : public FTexture +class FRawPageTexture : public FWorldTexture { public: FRawPageTexture (int lumpnum); ~FRawPageTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - -protected: - uint8_t *Pixels; - static const Span DummySpans[2]; - - void MakeTexture (); + uint8_t *MakeTexture (FRenderStyle style) override; }; //========================================================================== @@ -155,17 +146,6 @@ FTexture *RawPageTexture_TryCreate(FileReader & file, int lumpnum) } -//========================================================================== -// -// -// -//========================================================================== - -const FTexture::Span FRawPageTexture::DummySpans[2] = -{ - { 0, 200 }, { 0, 0 } -}; - //========================================================================== // // @@ -173,7 +153,7 @@ const FTexture::Span FRawPageTexture::DummySpans[2] = //========================================================================== FRawPageTexture::FRawPageTexture (int lumpnum) -: FTexture(NULL, lumpnum), Pixels(0) +: FWorldTexture(NULL, lumpnum) { Width = 320; Height = 200; @@ -188,79 +168,14 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -FRawPageTexture::~FRawPageTexture () -{ - Unload (); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FRawPageTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FRawPageTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - column %= 320; - } - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FRawPageTexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -void FRawPageTexture::MakeTexture () +uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style) { FMemLump lump = Wads.ReadLump (SourceLump); const uint8_t *source = (const uint8_t *)lump.GetMem(); const uint8_t *source_p = source; uint8_t *dest_p; - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; dest_p = Pixels; // Convert the source image from row-major to column-major format @@ -268,11 +183,12 @@ void FRawPageTexture::MakeTexture () { for (int x = 320; x != 0; --x) { - *dest_p = GPalette.Remap[*source_p]; + *dest_p = (style.Flags & STYLEF_RedIsAlpha)? *source_p : GPalette.Remap[*source_p]; dest_p += 200; source_p++; } dest_p -= 200*320-1; } + return Pixels; } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 212f53a03..154efb222 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -248,10 +248,6 @@ void FTexture::CalcBitSize () HeightBits = i; } -void FTexture::HackHack (int newheight) -{ -} - FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const { Span **spans, *span; @@ -554,14 +550,15 @@ void FTexture::GenerateBgraMipmapsFast() } } -void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation) +void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { - const uint8_t *pixels = GetPixels(); + const uint8_t *pixels = GetPixels(/*style*/); int srcwidth = Width; int srcheight = Height; int step_x = Height; int step_y = 1; FClipRect cr = {0, 0, dwidth, dheight}; + if (style.Flags & STYLEF_RedIsAlpha) translation = nullptr; // do not apply translations to alpha textures. if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate)) { diff --git a/src/textures/textures.h b/src/textures/textures.h index 006d24bb7..0aede4562 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -37,6 +37,7 @@ #include "doomtype.h" #include "vectors.h" +#include "r_data/renderstyle.h" #include struct FloatRect @@ -225,13 +226,15 @@ public: }; // Returns a single column of the texture - virtual const uint8_t *GetColumn (unsigned int column, const Span **spans_out) = 0; + virtual const uint8_t *GetColumn(unsigned int column, const Span **spans_out) = 0;// delete; + //virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0; // Returns a single column of the texture, in BGRA8 format virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out); // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels () = 0; + virtual const uint8_t *GetPixels() = 0;// delete; + //virtual const uint8_t *GetPixels(FRenderStyle style) = 0; // Returns the whole texture, stored in column-major order, in BGRA8 format virtual const uint32_t *GetPixelsBgra(); @@ -277,12 +280,7 @@ public: virtual void SetFrontSkyLayer(); - void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, const uint8_t *translation=NULL) - { - CopyToBlock(dest, dwidth, dheight, x, y, 0, translation); - } - - void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation=NULL); + void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, FRenderStyle style); // Returns true if the next call to GetPixels() will return an image different from the // last call to GetPixels(). This should be considered valid only if a call to CheckModified() @@ -307,8 +305,6 @@ public: PalEntry GetSkyCapColor(bool bottom); static PalEntry averageColor(const uint32_t *data, int size, int maxout); - virtual void HackHack (int newheight); // called by FMultipatchTexture to discover corrupt patches. - protected: uint16_t Width, Height, WidthMask; static uint8_t GrayMap[256]; @@ -585,6 +581,24 @@ public: }; }; +// base class for everything that can be used as a world texture. +// This intermediate class encapsulates the buffers for the software renderer. +class FWorldTexture : public FTexture +{ +protected: + uint8_t *Pixeldata[2] = { nullptr, nullptr }; + Span **Spandata[2] = { nullptr, nullptr }; + + FWorldTexture(const char *name = nullptr, int lumpnum = -1); + ~FWorldTexture(); + // These should not be overridden. If that is needed, a class should inherit from something else + const uint8_t *GetColumn(unsigned int column, const Span **spans_out) override final; + const uint8_t *GetPixels() override final; + void Unload() override final; // should be removed after refactoring. + virtual void MakeTexture() = delete; + virtual uint8_t *MakeTexture(FRenderStyle style) = 0; +}; + // A texture that doesn't really exist class FDummyTexture : public FTexture { diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index 97e381e6b..4b6430837 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -76,29 +76,18 @@ struct TGAHeader // //========================================================================== -class FTGATexture : public FTexture +class FTGATexture : public FWorldTexture { public: FTGATexture (int lumpnum, TGAHeader *); - ~FTGATexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); - void Unload (); - FTextureFormat GetFormat (); - - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - bool UseBasePalette(); + FTextureFormat GetFormat () override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + bool UseBasePalette() override; protected: - uint8_t *Pixels; - Span **Spans; - void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - - virtual void MakeTexture (); - - friend class FTexture; + uint8_t *MakeTexture (FRenderStyle style) override; }; //========================================================================== @@ -142,7 +131,7 @@ FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) -: FTexture(NULL, lumpnum), Pixels(0), Spans(0) +: FWorldTexture(NULL, lumpnum) { Wads.GetLumpName (Name, lumpnum); Width = hdr->width; @@ -158,38 +147,6 @@ FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) // //========================================================================== -FTGATexture::~FTGATexture () -{ - Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FTGATexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - FTextureFormat FTGATexture::GetFormat() { return TEX_RGB; @@ -201,55 +158,6 @@ FTextureFormat FTGATexture::GetFormat() // //========================================================================== -const uint8_t *FTGATexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FTGATexture::GetPixels () -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel) { uint8_t data[4]; @@ -286,7 +194,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -void FTGATexture::MakeTexture () +uint8_t *FTGATexture::MakeTexture (FRenderStyle style) { uint8_t PaletteMap[256]; auto lump = Wads.OpenLumpReader (SourceLump); @@ -294,8 +202,9 @@ void FTGATexture::MakeTexture () uint16_t w; uint8_t r,g,b,a; uint8_t * buffer; + bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); - Pixels = new uint8_t[Width*Height]; + auto Pixels = new uint8_t[Width*Height]; lump.Read(&hdr, sizeof(hdr)); lump.Seek(hdr.id_len, FileReader::SeekCur); @@ -339,7 +248,7 @@ void FTGATexture::MakeTexture () r=g=b=a=0; break; } - PaletteMap[i] = a>=128? ColorMatcher.Pick(r, g, b) : 0; + PaletteMap[i] = !alphatex? (a>=128? ColorMatcher.Pick(r, g, b) : 0) : (r * a) >> 8; } } @@ -397,8 +306,8 @@ void FTGATexture::MakeTexture () uint16_t * p = (uint16_t*)(ptr + y * Pitch); for(int x=0;x>10) & 0x1f)*2][((v>>5) & 0x1f)*2][(v & 0x1f)*2]; + int v = LittleShort(*p); + Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[((v >> 10) & 0x1f) * 2][((v >> 5) & 0x1f) * 2][(v & 0x1f) * 2] : ((v >> 10) & 0x1f) * 8; p+=step_x; } } @@ -410,7 +319,7 @@ void FTGATexture::MakeTexture () uint8_t * p = ptr + y * Pitch; for(int x=0;x>2][p[1]>>2][p[0]>>2]; + Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2]; p+=step_x; } } @@ -424,7 +333,7 @@ void FTGATexture::MakeTexture () uint8_t * p = ptr + y * Pitch; for(int x=0;x>2][p[1]>>2][p[0]>>2]; + Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2]; p+=step_x; } } @@ -436,7 +345,7 @@ void FTGATexture::MakeTexture () uint8_t * p = ptr + y * Pitch; for(int x=0;x= 128? RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2] : 0; + Pixels[x*Height + y] = !alphatex ? (p[3] >= 128 ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : 0) : (p[2] * p[3]) >> 8; p+=step_x; } } @@ -457,7 +366,7 @@ void FTGATexture::MakeTexture () uint8_t * p = ptr + y * Pitch; for(int x=0;x Date: Sun, 18 Mar 2018 12:54:14 +0100 Subject: [PATCH 15/37] - added worldtexture.cpp --- src/textures/worldtexture.cpp | 133 ++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/textures/worldtexture.cpp diff --git a/src/textures/worldtexture.cpp b/src/textures/worldtexture.cpp new file mode 100644 index 000000000..0370bf3e8 --- /dev/null +++ b/src/textures/worldtexture.cpp @@ -0,0 +1,133 @@ +/* +** worldtexture.cpp +** Intermediate class for some common code for several classes +** +**--------------------------------------------------------------------------- +** Copyright 2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "textures.h" + + +//========================================================================== +// +// +// +//========================================================================== + +FWorldTexture::FWorldTexture(const char *name, int lumpnum) + : FTexture(name, lumpnum) +{ +} + +//========================================================================== +// +// +// +//========================================================================== + +FWorldTexture::~FWorldTexture() +{ + Unload(); + for(int i = 0; i < 2; i++) + { + if (Spandata[i] != nullptr) + { + FreeSpans (Spandata[i]); + Spandata[i] = nullptr; + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FWorldTexture::Unload () +{ + for(int i = 0; i < 2; i++) + { + if (!(PixelsAreStatic & (1 << i))) + { + delete[] Pixeldata[i]; + } + Pixeldata[i] = nullptr; + } + FTexture::Unload(); +} + +//========================================================================== +// +// +// +//========================================================================== + +const uint8_t *FWorldTexture::GetColumn (unsigned int column, const Span **spans_out) +{ + GetPixels(); + if ((unsigned)column >= (unsigned)Width) + { + if (WidthMask + 1 == Width) + { + column &= WidthMask; + } + else + { + column %= Width; + } + } + if (spans_out != nullptr) + { + if (Spandata[0] == nullptr) + { + Spandata[0] = CreateSpans (Pixeldata[0]); + } + *spans_out = Spandata[0][column]; + } + return Pixeldata[0] + column*Height; +} + +//========================================================================== +// +// +// +//========================================================================== + +const uint8_t *FWorldTexture::GetPixels () +{ + if (Pixeldata[0] == nullptr) + { + Pixeldata[0] = MakeTexture (LegacyRenderStyles[STYLE_Normal]); + } + return Pixeldata[0]; +} + From 494504229f8accc15f10241edce72e19c3151ca6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 12:54:40 +0100 Subject: [PATCH 16/37] - fixed the BarShader texture. Even though unlikely, this should work as a regular texture because it can be used as such. As a result of the above, true color generation needs to be done explicitly now. --- src/r_data/renderstyle.h | 7 +++--- src/textures/shadertexture.cpp | 44 ++++++++++++++++++++++++---------- src/textures/textures.h | 1 + 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index b1fd98a5c..68bc9a242 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -139,10 +139,9 @@ union FRenderStyle bool IsVisible(double alpha) const throw(); private: // Code that compares an actor's render style with a legacy render - // style value should be updated. Making these conversion operators - // private will catch those cases. - operator ERenderStyle() const { return STYLE_Normal; } - operator int() const { return STYLE_Normal; } + // style value should be updated. + operator ERenderStyle() = delete; + operator int() const = delete; }; extern FRenderStyle LegacyRenderStyles[STYLE_Count]; diff --git a/src/textures/shadertexture.cpp b/src/textures/shadertexture.cpp index 93e423470..2834c9318 100644 --- a/src/textures/shadertexture.cpp +++ b/src/textures/shadertexture.cpp @@ -49,9 +49,11 @@ #include "r_defs.h" #include "r_state.h" #include "r_data/r_translate.h" +#include "r_data/renderstyle.h" +#include "bitmap.h" -class FBarShader : public FTexture +class FBarShader : public FWorldTexture { public: FBarShader(bool vertical, bool reverse) @@ -62,6 +64,7 @@ public: Width = vertical ? 2 : 256; Height = vertical ? 256 : 2; CalcBitSize(); + PixelsAreStatic = 2; // The alpha buffer is static, but if this gets used as a regular texture, a separate buffer needs to be made. // Fill the column/row with shading values. // Vertical shaders have have minimum alpha at the top @@ -106,24 +109,41 @@ public: } } } - DummySpan[0].TopOffset = 0; - DummySpan[0].Length = vertical ? 256 : 2; - DummySpan[1].TopOffset = 0; - DummySpan[1].Length = 0; } - const uint8_t *GetColumn(unsigned int column, const Span **spans_out) + + uint8_t *MakeTexture(FRenderStyle style) override { - if (spans_out != NULL) + if (style.Flags & STYLEF_RedIsAlpha) { - *spans_out = DummySpan; + return Pixels; + } + else + { + // Since this presents itself to the game as a regular named texture + // it can easily be used on walls and flats and should work as such, + // even if it makes little sense. + auto Pix = new uint8_t[512]; + for (int i = 0; i < 512; i++) + { + Pix[i] = GrayMap[Pixels[i]]; + } + return Pix; } - return Pixels + ((column & WidthMask) << HeightBits); } - const uint8_t *GetPixels() { return Pixels; } - void Unload() {} + + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override + { + bmp->CopyPixelData(x, y, Pixels, Width, Height, Height, 1, rotate, translationtables[TRANSLATION_Standard][8]->Palette, inf); + } + + bool UseBasePalette() override + { + return false; + } + + private: uint8_t Pixels[512]; - Span DummySpan[2]; }; diff --git a/src/textures/textures.h b/src/textures/textures.h index 0aede4562..675a9d4a3 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -588,6 +588,7 @@ class FWorldTexture : public FTexture protected: uint8_t *Pixeldata[2] = { nullptr, nullptr }; Span **Spandata[2] = { nullptr, nullptr }; + uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers. FWorldTexture(const char *name = nullptr, int lumpnum = -1); ~FWorldTexture(); From de8db297a6e04c02dc4772c6a239fe33160994ca Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 13:12:25 +0100 Subject: [PATCH 17/37] - made the backdrop texture also inherit from FWorldTexture. In this case the only benefit is one less piece of GetColumn duplication - this texture is simply not usable in-game, unlike the BarShader. --- src/textures/backdroptexture.cpp | 47 ++++++-------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/src/textures/backdroptexture.cpp b/src/textures/backdroptexture.cpp index aec95cc2e..05d3f2541 100644 --- a/src/textures/backdroptexture.cpp +++ b/src/textures/backdroptexture.cpp @@ -56,7 +56,7 @@ // //============================================================================= -struct FBackdropTexture : public FTexture +class FBackdropTexture : public FWorldTexture { enum { @@ -77,15 +77,12 @@ struct FBackdropTexture : public FTexture public: FBackdropTexture(); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels(); - void Unload(); - bool CheckModified(); + bool CheckModified() override; + uint8_t *MakeTexture(FRenderStyle style) override; protected: uint32_t costab[COS_SIZE]; - uint8_t *Pixels; - static const Span DummySpan[2]; + uint8_t Pixels[160*144]; int LastRenderTic; uint32_t time1, time2, time3, time4; @@ -170,8 +167,6 @@ static uint8_t pattern2[1024] = 7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5, }; -const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } }; - //============================================================================= // // @@ -180,7 +175,7 @@ const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } }; FBackdropTexture::FBackdropTexture() { - Pixels = nullptr; + PixelsAreStatic = 3; Width = 144; Height = 160; WidthBits = 8; @@ -214,39 +209,14 @@ bool FBackdropTexture::CheckModified() return LastRenderTic != gametic; } -void FBackdropTexture::Unload() -{ - if (Pixels != nullptr) delete[] Pixels; - Pixels = nullptr; -} - //============================================================================= // -// +// There's no point making this work as a regular texture as it is made to +// work with special translations. As an alpha texture it should be fine. // //============================================================================= -const uint8_t *FBackdropTexture::GetColumn(unsigned int column, const Span **spans_out) -{ - if (LastRenderTic != gametic) - { - Render(); - } - column = clamp(column, 0u, 143u); - if (spans_out != nullptr) - { - *spans_out = DummySpan; - } - return Pixels + column*160; -} - -//============================================================================= -// -// -// -//============================================================================= - -const uint8_t *FBackdropTexture::GetPixels() +uint8_t *FBackdropTexture::MakeTexture(FRenderStyle style) { if (LastRenderTic != gametic) { @@ -266,7 +236,6 @@ void FBackdropTexture::Render() uint8_t *from; int width, height, pitch; - if (Pixels == nullptr) Pixels = new uint8_t[160 * 144]; width = 160; height = 144; pitch = width; From 94eadb1a8c1aee1b83d7ccab059158e8b21601be Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 13:47:40 +0100 Subject: [PATCH 18/37] - made it compile again. --- src/am_map.cpp | 2 +- src/r_data/renderstyle.h | 1 - src/textures/automaptexture.cpp | 1 - src/textures/jpegtexture.cpp | 1 - src/textures/pcxtexture.cpp | 1 - src/textures/rawpagetexture.cpp | 1 - src/textures/shadertexture.cpp | 1 + src/v_palette.cpp | 4 +--- 8 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index c6e6ba19b..2f6c04c6d 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -3088,7 +3088,7 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust, DTA_TranslationIndex, translation, DTA_Alpha, alpha, DTA_FillColor, fillcolor, - DTA_RenderStyle, uint32_t(renderstyle), + DTA_RenderStyle, renderstyle.AsDWORD, TAG_DONE); } diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index 68bc9a242..21c41278a 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -133,7 +133,6 @@ union FRenderStyle uint32_t AsDWORD; inline FRenderStyle &operator= (ERenderStyle legacy); - operator uint32_t() const { return AsDWORD; } bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; } void CheckFuzz(); bool IsVisible(double alpha) const throw(); diff --git a/src/textures/automaptexture.cpp b/src/textures/automaptexture.cpp index 27080669e..c07eded6e 100644 --- a/src/textures/automaptexture.cpp +++ b/src/textures/automaptexture.cpp @@ -51,7 +51,6 @@ class FAutomapTexture : public FWorldTexture { public: FAutomapTexture(int lumpnum); - ~FAutomapTexture (); uint8_t *MakeTexture (FRenderStyle style); }; diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index abf1e34ec..93aac09ca 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -183,7 +183,6 @@ class FJPEGTexture : public FWorldTexture { public: FJPEGTexture (int lumpnum, int width, int height); - ~FJPEGTexture (); FTextureFormat GetFormat () override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; diff --git a/src/textures/pcxtexture.cpp b/src/textures/pcxtexture.cpp index efe12e3c2..f5635c7a3 100644 --- a/src/textures/pcxtexture.cpp +++ b/src/textures/pcxtexture.cpp @@ -85,7 +85,6 @@ class FPCXTexture : public FWorldTexture { public: FPCXTexture (int lumpnum, PCXHeader &); - ~FPCXTexture (); FTextureFormat GetFormat () override; diff --git a/src/textures/rawpagetexture.cpp b/src/textures/rawpagetexture.cpp index 7e9268c6e..adf8abfff 100644 --- a/src/textures/rawpagetexture.cpp +++ b/src/textures/rawpagetexture.cpp @@ -50,7 +50,6 @@ class FRawPageTexture : public FWorldTexture { public: FRawPageTexture (int lumpnum); - ~FRawPageTexture (); uint8_t *MakeTexture (FRenderStyle style) override; }; diff --git a/src/textures/shadertexture.cpp b/src/textures/shadertexture.cpp index 2834c9318..67d4db683 100644 --- a/src/textures/shadertexture.cpp +++ b/src/textures/shadertexture.cpp @@ -134,6 +134,7 @@ public: int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override { bmp->CopyPixelData(x, y, Pixels, Width, Height, Height, 1, rotate, translationtables[TRANSLATION_Standard][8]->Palette, inf); + return 0; } bool UseBasePalette() override diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 436fe84dc..af4aae4fb 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -374,9 +374,7 @@ static bool FixBuildPalette (uint8_t *opal, int lump, bool blood) void InitPalette () { uint8_t pal[768]; - bool usingBuild = false; - int lump; - + ReadPalette(Wads.CheckNumForName("PLAYPAL"), pal); GPalette.SetPalette (pal); From 47bfbb5e0825c01a80c813f3f08f0f5a86674e98 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 14:18:19 +0100 Subject: [PATCH 19/37] - Make BuildTexture inherit from worldtexture. - handle WorldTextures that can change their content automatically. --- src/textures/buildtexture.cpp | 67 +++-------------------------------- src/textures/worldtexture.cpp | 6 +++- 2 files changed, 9 insertions(+), 64 deletions(-) diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index dd9545553..722328667 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -48,18 +48,14 @@ // //========================================================================== -class FBuildTexture : public FTexture +class FBuildTexture : public FWorldTexture { public: FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top); - ~FBuildTexture (); - - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + uint8_t *MakeTexture(FRenderStyle style) override { return const_cast(Pixels); } // This is only to make it compile for now and will be changed later. protected: const uint8_t *Pixels; - Span **Spans; }; @@ -70,8 +66,9 @@ protected: //========================================================================== FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top) -: Pixels (pixels), Spans (NULL) +: Pixels (pixels) { + PixelsAreStatic = 3; Width = width; Height = height; LeftOffset = left; @@ -81,62 +78,6 @@ FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int UseType = TEX_Build; } -//========================================================================== -// -// -// -//========================================================================== - -FBuildTexture::~FBuildTexture () -{ - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FBuildTexture::GetPixels () -{ - return Pixels; -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FBuildTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (column >= Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - //=========================================================================== // // AddTiles diff --git a/src/textures/worldtexture.cpp b/src/textures/worldtexture.cpp index 0370bf3e8..896890236 100644 --- a/src/textures/worldtexture.cpp +++ b/src/textures/worldtexture.cpp @@ -91,7 +91,7 @@ void FWorldTexture::Unload () // //========================================================================== -const uint8_t *FWorldTexture::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FWorldTexture::GetColumn(unsigned int column, const Span **spans_out) { GetPixels(); if ((unsigned)column >= (unsigned)Width) @@ -124,6 +124,10 @@ const uint8_t *FWorldTexture::GetColumn (unsigned int column, const Span **spans const uint8_t *FWorldTexture::GetPixels () { + if (CheckModified()) + { + Unload(); + } if (Pixeldata[0] == nullptr) { Pixeldata[0] = MakeTexture (LegacyRenderStyles[STYLE_Normal]); From a399d79f8a3a211b5a2404d4b9ccb5100a8a8ae8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 14:18:42 +0100 Subject: [PATCH 20/37] - minor reformatting. --- src/textures/canvastexture.cpp | 2 +- src/textures/skyboxtexture.cpp | 2 +- src/textures/skyboxtexture.h | 2 +- src/textures/texture.cpp | 12 +++--------- src/textures/textures.h | 9 ++++----- src/textures/warptexture.cpp | 2 +- src/v_font.cpp | 10 +++++----- src/v_video.cpp | 2 +- 8 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index d2530017b..bb6b3d685 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -65,7 +65,7 @@ FCanvasTexture::~FCanvasTexture () Unload (); } -const uint8_t *FCanvasTexture::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FCanvasTexture::GetColumn(unsigned int column, const Span **spans_out) { bNeedsUpdate = true; if (Canvas == NULL) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 9c3b21b67..7f19e7f85 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -59,7 +59,7 @@ FSkyBox::~FSkyBox() // //----------------------------------------------------------------------------- -const uint8_t *FSkyBox::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FSkyBox::GetColumn(unsigned int column, const Span **spans_out) { if (faces[0]) return faces[0]->GetColumn(column, spans_out); return NULL; diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 3a4edd042..74fc68bbe 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -17,7 +17,7 @@ public: FSkyBox(); ~FSkyBox(); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(unsigned int column, const Span **spans_out); const uint8_t *GetPixels (); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 154efb222..c81b691c4 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -961,15 +961,9 @@ void FDummyTexture::SetSize (int width, int height) } // This must never be called -const uint8_t *FDummyTexture::GetColumn (unsigned int column, const Span **spans_out) +uint8_t *FDummyTexture::MakeTexture (FRenderStyle) { - return NULL; -} - -// And this also must never be called -const uint8_t *FDummyTexture::GetPixels () -{ - return NULL; + return nullptr; } //========================================================================== @@ -996,7 +990,7 @@ CCMD (printspans) { const FTexture::Span *spans; Printf ("%4d:", x); - tex->GetColumn (x, &spans); + tex->GetColumn(x, &spans); while (spans->Length != 0) { Printf (" (%4d,%4d)", spans->TopOffset, spans->TopOffset+spans->Length-1); diff --git a/src/textures/textures.h b/src/textures/textures.h index 675a9d4a3..17cef6e1c 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -601,12 +601,11 @@ protected: }; // A texture that doesn't really exist -class FDummyTexture : public FTexture +class FDummyTexture : public FWorldTexture { public: FDummyTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + uint8_t *MakeTexture(FRenderStyle); void SetSize (int width, int height); }; @@ -618,7 +617,7 @@ public: ~FWarpTexture (); virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(unsigned int column, const Span **spans_out); const uint8_t *GetPixels (); const uint32_t *GetPixelsBgra() override; void Unload (); @@ -653,7 +652,7 @@ public: FCanvasTexture (const char *name, int width, int height); ~FCanvasTexture (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(unsigned int column, const Span **spans_out); const uint8_t *GetPixels (); const uint32_t *GetPixelsBgra() override; void Unload (); diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 2e073c186..41920849d 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -117,7 +117,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra() return PixelsBgra.data(); } -const uint8_t *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FWarpTexture::GetColumn(unsigned int column, const Span **spans_out) { uint64_t time =screen->FrameTime; diff --git a/src/v_font.cpp b/src/v_font.cpp index a8afa079c..1b36c2219 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -177,7 +177,7 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(unsigned int column, const Span **spans_out); const uint8_t *GetPixels (); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -198,7 +198,7 @@ public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); - const uint8_t *GetColumn (unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(unsigned int column, const Span **spans_out); const uint8_t *GetPixels (); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -559,7 +559,7 @@ void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) for (x = pic->GetWidth() - 1; x >= 0; x--) { const FTexture::Span *spans; - const uint8_t *column = pic->GetColumn (x, &spans); + const uint8_t *column = pic->GetColumn(x, &spans); while (spans->Length != 0) { @@ -1692,7 +1692,7 @@ void FFontChar1::MakeTexture () // //========================================================================== -const uint8_t *FFontChar1::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FFontChar1::GetColumn(unsigned int column, const Span **spans_out) { if (Pixels == NULL) { @@ -1814,7 +1814,7 @@ const uint8_t *FFontChar2::GetPixels () // //========================================================================== -const uint8_t *FFontChar2::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FFontChar2::GetColumn(unsigned int column, const Span **spans_out) { if (Pixels == NULL) { diff --git a/src/v_video.cpp b/src/v_video.cpp index ca2e8b62a..77f83b285 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1008,7 +1008,7 @@ void FPaletteTester::SetTranslation(int num) // //========================================================================== -const uint8_t *FPaletteTester::GetColumn (unsigned int column, const Span **spans_out) +const uint8_t *FPaletteTester::GetColumn(unsigned int column, const Span **spans_out) { if (CurTranslation != WantTranslation) { From f4d9ad1123d912c63d300aa8965043330d6f8a66 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 Mar 2018 21:33:44 +0100 Subject: [PATCH 21/37] - extended FTexture::GetPixels and FTexture::GetColumn by a RenderStyle parameter. Now it is no longer necessary to provide specially set up textures for rendering shaded decals, they can use any PNG texture now that contains a proper red channel. Handling of the alPh chunk has been removed as a result as it in no longer needed. --- src/gl/textures/gl_material.cpp | 5 +- src/gl/textures/gl_texture.cpp | 2 +- src/polyrenderer/drawers/poly_draw_args.cpp | 41 +++++---- src/polyrenderer/drawers/poly_draw_args.h | 10 +-- src/polyrenderer/poly_renderthread.cpp | 6 +- src/polyrenderer/poly_renderthread.h | 2 +- src/polyrenderer/scene/poly_model.cpp | 4 +- src/polyrenderer/scene/poly_plane.cpp | 4 +- src/polyrenderer/scene/poly_sky.cpp | 2 +- src/polyrenderer/scene/poly_wall.cpp | 2 +- src/polyrenderer/scene/poly_wallsprite.cpp | 2 +- src/r_data/renderstyle.h | 10 +++ src/swrenderer/line/r_renderdrawsegment.cpp | 5 +- src/swrenderer/line/r_walldraw.cpp | 4 +- src/swrenderer/plane/r_skyplane.cpp | 4 +- src/swrenderer/r_renderthread.cpp | 6 +- src/swrenderer/r_renderthread.h | 2 +- src/swrenderer/r_swcanvas.cpp | 2 +- src/swrenderer/r_swrenderer.cpp | 8 +- src/swrenderer/things/r_decal.cpp | 8 +- src/swrenderer/things/r_decal.h | 2 +- src/swrenderer/things/r_model.cpp | 4 +- src/swrenderer/things/r_playersprite.cpp | 4 +- src/swrenderer/things/r_sprite.cpp | 4 +- src/swrenderer/things/r_wallsprite.cpp | 8 +- src/swrenderer/things/r_wallsprite.h | 2 +- src/swrenderer/viewport/r_skydrawer.cpp | 4 +- src/swrenderer/viewport/r_spandrawer.cpp | 4 +- src/swrenderer/viewport/r_spritedrawer.cpp | 4 +- src/swrenderer/viewport/r_spritedrawer.h | 2 +- src/textures/backdroptexture.cpp | 4 +- src/textures/canvastexture.cpp | 12 +-- src/textures/multipatchtexture.cpp | 10 ++- src/textures/skyboxtexture.cpp | 8 +- src/textures/skyboxtexture.h | 4 +- src/textures/texture.cpp | 39 +++++---- src/textures/textures.h | 52 ++++++----- src/textures/warptexture.cpp | 97 ++++----------------- src/textures/worldtexture.cpp | 35 +++++--- src/v_font.cpp | 28 +++--- src/v_video.cpp | 12 +-- 41 files changed, 218 insertions(+), 250 deletions(-) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 859706772..98f0559d9 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -31,6 +31,7 @@ #include "r_utility.h" #include "templates.h" #include "sc_man.h" +#include "r_data/renderstyle.h" #include "colormatcher.h" #include "textures/warpbuffer.h" #include "textures/bitmap.h" @@ -297,7 +298,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (hwtex) { // Texture has become invalid - if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified()) + if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified(DefaultRenderStyle())) { Clean(true); hwtex = CreateHwTexture(); @@ -323,7 +324,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla WarpBuffer((uint32_t*)warpbuffer, (const uint32_t*)buffer, w, h, wt->WidthOffsetMultiplier, wt->HeightOffsetMultiplier, screen->FrameTime, wt->Speed, tex->bWarped); delete[] buffer; buffer = warpbuffer; - wt->GenTime = screen->FrameTime; + wt->GenTime[0] = screen->FrameTime; } tex->ProcessData(buffer, w, h, false); } diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 0680ccdd6..f228d2123 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -238,7 +238,7 @@ void FTexture::CreateDefaultBrightmap() ) { // May have one - let's check when we use this texture - const uint8_t *texbuf = GetPixels(); + const uint8_t *texbuf = GetPixels(DefaultRenderStyle()); const int white = ColorMatcher.Pick(255,255,255); int size = GetWidth() * GetHeight(); diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 466a39f4a..312cb3e32 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -46,20 +46,21 @@ void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height) mTranslation = nullptr; } -void PolyDrawArgs::SetTexture(FTexture *texture) +void PolyDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) { mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); mTranslation = nullptr; } -void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal) +void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style) { - if (translationID != 0xffffffff && translationID != 0) + // Alphatexture overrides translations. + if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha)) { FRemapTable *table = TranslationToTable(translationID); if (table != nullptr && !table->Inactive) @@ -71,20 +72,20 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); return; } } - if (forcePal) + if (style.Flags & STYLEF_RedIsAlpha) { mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); } else { - SetTexture(texture); + SetTexture(texture, style); } } @@ -164,8 +165,7 @@ void PolyDrawArgs::DrawElements(PolyRenderThread *thread, const TriVertex *verti void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) { - bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]); - SetTexture(tex, translationID, forcePal); + SetTexture(tex, translationID, renderstyle); if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { @@ -232,20 +232,20 @@ void RectDrawArgs::SetTexture(const uint8_t *texels, int width, int height) mTranslation = nullptr; } -void RectDrawArgs::SetTexture(FTexture *texture) +void RectDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) { mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); mTranslation = nullptr; } -void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal) +void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style) { - if (translationID != 0xffffffff && translationID != 0) + if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha)) { FRemapTable *table = TranslationToTable(translationID); if (table != nullptr && !table->Inactive) @@ -257,20 +257,20 @@ void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); return; } } - if (forcePal) + if (style.Flags & STYLEF_RedIsAlpha) { mTextureWidth = texture->GetWidth(); mTextureHeight = texture->GetHeight(); - mTexturePixels = texture->GetPixels(); + mTexturePixels = texture->GetPixels(style); } else { - SetTexture(texture); + SetTexture(texture, style); } } @@ -315,10 +315,9 @@ void RectDrawArgs::Draw(PolyRenderThread *thread, double x0, double x1, double y thread->DrawQueue->Push(*this); } -void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) +void RectDrawArgs::SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) { - bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]); - SetTexture(tex, translationID, forcePal); + SetTexture(tex, translationID, renderstyle); if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy])) { diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index eb543bbbf..05ad0862d 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -67,8 +67,8 @@ class PolyDrawArgs public: void SetClipPlane(int index, const PolyClipPlane &plane) { mClipPlane[index] = plane; } void SetTexture(const uint8_t *texels, int width, int height); - void SetTexture(FTexture *texture); - void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false); + void SetTexture(FTexture *texture, FRenderStyle style); + void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed); void SetDepthTest(bool enable) { mDepthTest = enable; } void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; } @@ -186,11 +186,11 @@ class RectDrawArgs { public: void SetTexture(const uint8_t *texels, int width, int height); - void SetTexture(FTexture *texture); - void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false); + void SetTexture(FTexture *texture, FRenderStyle style); + void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel); 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 SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); + void SetStyle(FRenderStyle renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1); diff --git a/src/polyrenderer/poly_renderthread.cpp b/src/polyrenderer/poly_renderthread.cpp index 9c3b33122..55d1c8469 100644 --- a/src/polyrenderer/poly_renderthread.cpp +++ b/src/polyrenderer/poly_renderthread.cpp @@ -74,7 +74,7 @@ void PolyRenderThread::FlushDrawQueue() } } -void PolyRenderThread::PrepareTexture(FTexture *texture) +void PolyRenderThread::PrepareTexture(FTexture *texture, FRenderStyle style) { if (texture == nullptr) return; @@ -91,9 +91,9 @@ void PolyRenderThread::PrepareTexture(FTexture *texture) std::unique_lock lock(loadmutex); - texture->GetPixels(); + texture->GetPixels(style); const FTexture::Span *spans; - texture->GetColumn(0, &spans); + texture->GetColumn(style, 0, &spans); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) { texture->GetPixelsBgra(); diff --git a/src/polyrenderer/poly_renderthread.h b/src/polyrenderer/poly_renderthread.h index af10fd45c..afed28b19 100644 --- a/src/polyrenderer/poly_renderthread.h +++ b/src/polyrenderer/poly_renderthread.h @@ -47,7 +47,7 @@ public: DrawerCommandQueuePtr DrawQueue; // Make sure texture can accessed safely - void PrepareTexture(FTexture *texture); + void PrepareTexture(FTexture *texture, FRenderStyle style); // Setup poly object in a threadsafe manner void PreparePolyObject(subsector_t *sub); diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index c952625c3..b2ce178cc 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -147,7 +147,7 @@ void PolyModelRenderer::DrawArrays(int start, int count) args.SetStencilTestValue(StencilValue); args.SetClipPlane(0, PolyClipPlane()); args.SetStyle(TriBlendMode::TextureOpaque); - args.SetTexture(SkinTexture); + args.SetTexture(SkinTexture, DefaultRenderStyle()); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); @@ -181,7 +181,7 @@ void PolyModelRenderer::DrawElements(int numIndices, size_t offset) args.SetStencilTestValue(StencilValue); args.SetClipPlane(0, PolyClipPlane()); args.SetStyle(TriBlendMode::TextureOpaque); - args.SetTexture(SkinTexture); + args.SetTexture(SkinTexture, DefaultRenderStyle()); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index f5485d096..874fe2630 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -81,7 +81,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const TriMatrix &wo args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); args.SetClipPlane(0, clipPlane); - args.SetTexture(tex); + args.SetTexture(tex, DefaultRenderStyle()); args.SetStyle(TriBlendMode::TextureOpaque); args.DrawArray(thread, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan); } @@ -572,7 +572,7 @@ void Render3DFloorPlane::Render(PolyRenderThread *thread, const TriMatrix &world args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); - args.SetTexture(tex); + args.SetTexture(tex, DefaultRenderStyle()); args.SetClipPlane(0, clipPlane); args.DrawArray(thread, vertices, sub->numlines, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 06cb7a8ec..eafa4c94c 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -91,7 +91,7 @@ void PolySkyDome::Render(PolyRenderThread *thread, const TriMatrix &worldToClip) RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, 0, false); RenderCapColorRow(thread, args, mCurrentSetup.frontskytex, rc, true); - args.SetTexture(mCurrentSetup.frontskytex); + args.SetTexture(mCurrentSetup.frontskytex, DefaultRenderStyle()); uint32_t topcapcolor = mCurrentSetup.frontskytex->GetSkyCapColor(false); uint32_t bottomcapcolor = mCurrentSetup.frontskytex->GetSkyCapColor(true); diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 20b9a1ade..fb75f7bf4 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -327,7 +327,7 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const TriMatrix &worldToCl args.SetStencilTestValue(StencilValue); args.SetWriteStencil(true, StencilValue + 1); if (Texture && !Polyportal) - args.SetTexture(Texture); + args.SetTexture(Texture, DefaultRenderStyle()); args.SetClipPlane(0, clipPlane); SetDynLights(thread, args); diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 846524f9d..7da68c5e5 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -105,7 +105,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, const TriMatrix &wor args.SetTransform(&worldToClip); args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); - args.SetTexture(tex); + args.SetTexture(tex, thing->RenderStyle); args.SetClipPlane(0, clipPlane); args.SetDepthTest(true); args.SetWriteDepth(false); diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index 21c41278a..afb82d380 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -145,6 +145,16 @@ private: extern FRenderStyle LegacyRenderStyles[STYLE_Count]; +inline FRenderStyle DefaultRenderStyle() +{ + return LegacyRenderStyles[STYLE_Normal]; +} + +inline FRenderStyle BadRenderStyle() // This is just a marker to find places where work is still needed. +{ + return LegacyRenderStyles[STYLE_Normal]; +} + inline FRenderStyle &FRenderStyle::operator= (ERenderStyle legacy) { if (legacy < STYLE_None || legacy >= STYLE_Count) diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 86f86c2cb..f46fbc133 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -155,6 +155,7 @@ namespace swrenderer bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade) { + auto renderstyle = DefaultRenderStyle(); auto viewport = Thread->Viewport.get(); Clip3DFloors *clip3d = Thread->Clip3D.get(); @@ -314,7 +315,7 @@ namespace swrenderer // draw the columns one at a time if (visible) { - Thread->PrepareTexture(tex); + Thread->PrepareTexture(tex, renderstyle); for (int x = x1; x < x2; ++x) { if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) @@ -329,7 +330,7 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, renderstyle); rw_light += rw_lightstep; spryscale += rw_scalestep; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index ac277a0ae..0b9c9131d 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -97,7 +97,7 @@ namespace swrenderer col = width + (col % width); } - source = texture->GetColumn(col, nullptr); + source = texture->GetColumn(DefaultRenderStyle(), col, nullptr); source2 = nullptr; texturefracx = 0; } @@ -530,7 +530,7 @@ namespace swrenderer this->rw_pic = pic; this->mask = mask; - Thread->PrepareTexture(pic); + Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here. if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) { diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index ef7a6b898..e95abbd46 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -172,8 +172,8 @@ namespace swrenderer drawerargs.SetLight(&NormalLight, 0, 0); } - Thread->PrepareTexture(frontskytex); - Thread->PrepareTexture(backskytex); + Thread->PrepareTexture(frontskytex, DefaultRenderStyle()); + Thread->PrepareTexture(backskytex, DefaultRenderStyle()); DrawSky(pl); } diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index bb2816a94..986879618 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -89,7 +89,7 @@ namespace swrenderer return pal_drawers.get(); } - void RenderThread::PrepareTexture(FTexture *texture) + void RenderThread::PrepareTexture(FTexture *texture, FRenderStyle style) { if (texture == nullptr) return; @@ -106,9 +106,9 @@ namespace swrenderer std::unique_lock lock(loadmutex); - texture->GetPixels(); + texture->GetPixels(style); const FTexture::Span *spans; - texture->GetColumn(0, &spans); + texture->GetColumn(style, 0, &spans); if (Viewport->RenderTarget->IsBgra()) { texture->GetPixelsBgra(); diff --git a/src/swrenderer/r_renderthread.h b/src/swrenderer/r_renderthread.h index 3e559155b..34beab6ae 100644 --- a/src/swrenderer/r_renderthread.h +++ b/src/swrenderer/r_renderthread.h @@ -84,7 +84,7 @@ namespace swrenderer SWPixelFormatDrawers *Drawers(RenderViewport *viewport); // Make sure texture can accessed safely - void PrepareTexture(FTexture *texture); + void PrepareTexture(FTexture *texture, FRenderStyle style); // Setup poly object in a threadsafe manner void PreparePolyObject(subsector_t *sub); diff --git a/src/swrenderer/r_swcanvas.cpp b/src/swrenderer/r_swcanvas.cpp index 0330d4d6e..5522d89dc 100644 --- a/src/swrenderer/r_swcanvas.cpp +++ b/src/swrenderer/r_swcanvas.cpp @@ -196,7 +196,7 @@ void SWCanvas::DrawTexture(DCanvas *canvas, FTexture *img, DrawParms &parms) while (x < x2_i) { - drawerargs.DrawMaskedColumn(&thread, x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked); + drawerargs.DrawMaskedColumn(&thread, x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, parms.style, !parms.masked); x++; frac += xiscale_i; } diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 3c18e6218..c31908a17 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -105,14 +105,14 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) if (isbgra) tex->GetColumnBgra(0, &spanp); else - tex->GetColumn(0, &spanp); + tex->GetColumn(DefaultRenderStyle(), 0, &spanp); } else if (cache != 0) { if (isbgra) tex->GetPixelsBgra(); else - tex->GetPixels (); + tex->GetPixels (DefaultRenderStyle()); } else { @@ -282,7 +282,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin cameraViewpoint = r_viewpoint; cameraViewwindow = r_viewwindow; - uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(); + uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle()); DSimpleCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas(); // curse Doom's overuse of global variables in the renderer. @@ -328,7 +328,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin // We need to make sure that both pixel buffers contain data: int width = tex->GetWidth(); int height = tex->GetHeight(); - uint8_t *palbuffer = (uint8_t *)tex->GetPixels(); + uint8_t *palbuffer = (uint8_t *)tex->GetPixels(DefaultRenderStyle()); uint32_t *bgrabuffer = (uint32_t*)tex->GetPixelsBgra(); for (int x = 0; x < width; x++) { diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index b1711d9e3..8361a8061 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -312,14 +312,14 @@ namespace swrenderer if (visible) { - thread->PrepareTexture(WallSpriteTile); + thread->PrepareTexture(WallSpriteTile, decal->RenderStyle); while (x < x2) { if (calclighting) { // calculate lighting drawerargs.SetLight(usecolormap, light, wallshade); } - DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); + DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); light += lightstep; x++; } @@ -333,7 +333,7 @@ namespace swrenderer } while (needrepeat--); } - void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) + void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) { auto viewport = thread->Viewport.get(); @@ -345,6 +345,6 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style); } } diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index 712e82900..e617b04a6 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -16,6 +16,6 @@ namespace swrenderer private: static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass); - static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); + static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); }; } diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 4b68db219..b6f5fe0c7 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -199,7 +199,7 @@ namespace swrenderer if (Thread->Viewport->RenderTarget->IsBgra()) args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); else - args.SetTexture(SkinTexture->GetPixels(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); + args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight()); args.SetDepthTest(true); args.SetWriteDepth(true); @@ -237,7 +237,7 @@ namespace swrenderer if (Thread->Viewport->RenderTarget->IsBgra()) args.SetTexture((const uint8_t *)SkinTexture->GetPixelsBgra(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); else - args.SetTexture(SkinTexture->GetPixels(), SkinTexture->GetWidth(), SkinTexture->GetHeight()); + args.SetTexture(SkinTexture->GetPixels(DefaultRenderStyle()), SkinTexture->GetWidth(), SkinTexture->GetHeight()); args.SetDepthTest(true); args.SetWriteDepth(true); diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 41ec47239..924c7a7d8 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -545,10 +545,10 @@ namespace swrenderer short *mceilingclip = zeroarray; fixed_t frac = startfrac; - thread->PrepareTexture(pic); + thread->PrepareTexture(pic, RenderStyle); for (int x = x1; x < x2; x++) { - drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac + xiscale / 2, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); + drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac + xiscale / 2, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, RenderStyle, false); frac += xiscale; } diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index 74a76a79f..be26ad7c2 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -361,11 +361,11 @@ namespace swrenderer { RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); - thread->PrepareTexture(tex); + thread->PrepareTexture(tex, vis->RenderStyle); while (x < x2) { if (!translucentPass->ClipSpriteColumnWithPortals(x, vis)) - drawerargs.DrawMaskedColumn(thread, x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); + drawerargs.DrawMaskedColumn(thread, x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, vis->RenderStyle, false); x++; frac += xiscale; } diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index be4c4195e..f44d88e2a 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -239,7 +239,7 @@ namespace swrenderer { RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); - thread->PrepareTexture(WallSpriteTile); + thread->PrepareTexture(WallSpriteTile, spr->RenderStyle); while (x < x2) { if (calclighting) @@ -247,14 +247,14 @@ namespace swrenderer drawerargs.SetLight(usecolormap, light, shade); } if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) - DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); + DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle); light += lightstep; x++; } } } - void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) + void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) { auto viewport = thread->Viewport.get(); @@ -266,6 +266,6 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style); } } diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index c248c6c8c..fa127ccf4 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -17,7 +17,7 @@ namespace swrenderer void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: - static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); + static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); FWallCoords wallc; uint32_t Translation = 0; diff --git a/src/swrenderer/viewport/r_skydrawer.cpp b/src/swrenderer/viewport/r_skydrawer.cpp index 16e2d2ab3..c134a46e2 100644 --- a/src/swrenderer/viewport/r_skydrawer.cpp +++ b/src/swrenderer/viewport/r_skydrawer.cpp @@ -56,7 +56,7 @@ namespace swrenderer } else { - dc_source = texture->GetColumn(column, nullptr); + dc_source = texture->GetColumn(DefaultRenderStyle(), column, nullptr); dc_sourceheight = texture->GetHeight(); } } @@ -75,7 +75,7 @@ namespace swrenderer } else { - dc_source2 = texture->GetColumn(column, nullptr); + dc_source2 = texture->GetColumn(DefaultRenderStyle(), column, nullptr); dc_sourceheight2 = texture->GetHeight(); } } diff --git a/src/swrenderer/viewport/r_spandrawer.cpp b/src/swrenderer/viewport/r_spandrawer.cpp index ffc4dfc5f..e5adf5409 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -32,7 +32,7 @@ namespace swrenderer void SpanDrawerArgs::SetTexture(RenderThread *thread, FTexture *tex) { - thread->PrepareTexture(tex); + thread->PrepareTexture(tex, DefaultRenderStyle()); ds_texwidth = tex->GetWidth(); ds_texheight = tex->GetHeight(); @@ -47,7 +47,7 @@ namespace swrenderer ds_ybits--; } - ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(); + ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(DefaultRenderStyle()); // Get correct render style? Shaded won't get here. ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1; } diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index 0dbb38716..20abfca51 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -43,7 +43,7 @@ namespace swrenderer colfunc = &SWPixelFormatDrawers::DrawColumn; } - void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked) + void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked) { if (x < thread->X1 || x >= thread->X2) return; @@ -67,7 +67,7 @@ namespace swrenderer if (viewport->RenderTarget->IsBgra() && !drawer_needs_pal_input) column = (const uint8_t *)tex->GetColumnBgra(col >> FRACBITS, &span); else - column = tex->GetColumn(col >> FRACBITS, &span); + column = tex->GetColumn(style, col >> FRACBITS, &span); FTexture::Span unmaskedSpan[2]; if (unmasked) diff --git a/src/swrenderer/viewport/r_spritedrawer.h b/src/swrenderer/viewport/r_spritedrawer.h index e1df5e926..f6a3aae79 100644 --- a/src/swrenderer/viewport/r_spritedrawer.h +++ b/src/swrenderer/viewport/r_spritedrawer.h @@ -33,7 +33,7 @@ namespace swrenderer void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; } void SetDynamicLight(uint32_t color) { dynlightcolor = color; } - void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false); + void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false); void FillColumn(RenderThread *thread); void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount); diff --git a/src/textures/backdroptexture.cpp b/src/textures/backdroptexture.cpp index 05d3f2541..9d9049fae 100644 --- a/src/textures/backdroptexture.cpp +++ b/src/textures/backdroptexture.cpp @@ -77,7 +77,7 @@ class FBackdropTexture : public FWorldTexture public: FBackdropTexture(); - bool CheckModified() override; + bool CheckModified(FRenderStyle style) override; uint8_t *MakeTexture(FRenderStyle style) override; protected: @@ -204,7 +204,7 @@ FBackdropTexture::FBackdropTexture() // //============================================================================= -bool FBackdropTexture::CheckModified() +bool FBackdropTexture::CheckModified(FRenderStyle) { return LastRenderTic != gametic; } diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index bb6b3d685..e13dd6d3d 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -65,12 +65,12 @@ FCanvasTexture::~FCanvasTexture () Unload (); } -const uint8_t *FCanvasTexture::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) { bNeedsUpdate = true; if (Canvas == NULL) { - MakeTexture (); + MakeTexture (style); } if ((unsigned)column >= (unsigned)Width) { @@ -90,12 +90,12 @@ const uint8_t *FCanvasTexture::GetColumn(unsigned int column, const Span **spans return Pixels + column*Height; } -const uint8_t *FCanvasTexture::GetPixels () +const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style) { bNeedsUpdate = true; if (Canvas == NULL) { - MakeTexture (); + MakeTexture (style); } return Pixels; } @@ -110,7 +110,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra() return PixelsBgra; } -void FCanvasTexture::MakeTexture () +void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical. { Canvas = new DSimpleCanvas (Width, Height, false); Canvas->Lock (); @@ -183,7 +183,7 @@ void FCanvasTexture::Unload () FTexture::Unload(); } -bool FCanvasTexture::CheckModified () +bool FCanvasTexture::CheckModified (FRenderStyle) { if (bDidUpdate) { diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index e2bf932e9..8571f820b 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -195,11 +195,17 @@ protected: int NumParts; TexPart *Parts; TexInit *Inits; - bool bRedirect:1; - bool bTranslucentPatches:1; + bool bRedirect; + bool bTranslucentPatches; uint8_t *MakeTexture (FRenderStyle style); + // The getters must optionally redirect if it's a simple one-patch texture. + const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); } + const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const Span **out) override + { return bRedirect ? Parts->Texture->GetColumn(style, col, out) : FWorldTexture::GetColumn(style, col, out); } + + private: void CheckForHacks (); void ParsePatch(FScanner &sc, TexPart & part, TexInit &init); diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 7f19e7f85..5270af937 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -59,9 +59,9 @@ FSkyBox::~FSkyBox() // //----------------------------------------------------------------------------- -const uint8_t *FSkyBox::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) { - if (faces[0]) return faces[0]->GetColumn(column, spans_out); + if (faces[0]) return faces[0]->GetColumn(style, column, spans_out); return NULL; } @@ -71,9 +71,9 @@ const uint8_t *FSkyBox::GetColumn(unsigned int column, const Span **spans_out) // //----------------------------------------------------------------------------- -const uint8_t *FSkyBox::GetPixels () +const uint8_t *FSkyBox::GetPixels (FRenderStyle style) { - if (faces[0]) return faces[0]->GetPixels(); + if (faces[0]) return faces[0]->GetPixels(style); return NULL; } diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 74fc68bbe..a6048ce58 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -17,8 +17,8 @@ public: FSkyBox(); ~FSkyBox(); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetPixels (FRenderStyle style); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); void Unload (); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index c81b691c4..2b6ec321c 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -183,19 +183,20 @@ void FTexture::Unload() const uint32_t *FTexture::GetColumnBgra(unsigned int column, const Span **spans_out) { const uint32_t *pixels = GetPixelsBgra(); + if (pixels == nullptr) return nullptr; column %= Width; if (spans_out != nullptr) - GetColumn(column, spans_out); + GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans. return pixels + column * Height; } const uint32_t *FTexture::GetPixelsBgra() { - if (PixelsBgra.empty() || CheckModified()) + if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle())) { - if (!GetColumn(0, nullptr)) + if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) return nullptr; FBitmap bitmap; @@ -206,7 +207,7 @@ const uint32_t *FTexture::GetPixelsBgra() return PixelsBgra.data(); } -bool FTexture::CheckModified () +bool FTexture::CheckModified (FRenderStyle) { return false; } @@ -282,6 +283,7 @@ FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const newspan = true; for (y = numrows; y > 0; --y) { + if (*data_p++ == 0) { if (!newspan) @@ -552,7 +554,7 @@ void FTexture::GenerateBgraMipmapsFast() void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { - const uint8_t *pixels = GetPixels(/*style*/); + const uint8_t *pixels = GetPixels(style); int srcwidth = Width; int srcheight = Height; int step_x = Height; @@ -720,7 +722,7 @@ FNativeTexture *FTexture::GetNative(bool wrapping) } else { - if (CheckModified()) + if (CheckModified(DefaultRenderStyle())) { Native->Update(); } @@ -740,12 +742,6 @@ void FTexture::KillNative() } } -// For this generic implementation, we just call GetPixels and copy that data -// to the buffer. Texture formats that can do better than paletted images -// should provide their own implementation that may preserve the original -// color data. Note that the buffer expects row-major data, since that's -// generally more convenient for any non-Doom image formats, and it doesn't -// need to be used by any of Doom's column drawing routines. void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt) { const uint8_t *pix; @@ -758,7 +754,7 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f { case TEX_Pal: case TEX_Gray: - pix = GetPixels(); + pix = GetPixels(DefaultRenderStyle()); stride = pitch - w; for (y = 0; y < h; ++y) { @@ -802,14 +798,14 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI { PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf); + bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, palette, inf); for(int i=1;i<256;i++) palette[i].a = 0; return 0; } int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) { - bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, remap, inf); + bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, remap, inf); return 0; } @@ -920,7 +916,7 @@ int FTexture::CheckRealHeight() for (int i = 0; i < GetWidth(); ++i) { - GetColumn(i, &span); + GetColumn(DefaultRenderStyle(), i, &span); while (span->Length != 0) { if (span->TopOffset < miny) @@ -960,8 +956,13 @@ void FDummyTexture::SetSize (int width, int height) CalcBitSize (); } -// This must never be called -uint8_t *FDummyTexture::MakeTexture (FRenderStyle) +// These only get called from the texture precacher which discards the result. +const uint8_t *FDummyTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +{ + return nullptr; +} + +const uint8_t *FDummyTexture::GetPixels(FRenderStyle style) { return nullptr; } @@ -990,7 +991,7 @@ CCMD (printspans) { const FTexture::Span *spans; Printf ("%4d:", x); - tex->GetColumn(x, &spans); + tex->GetColumn(DefaultRenderStyle(), x, &spans); while (spans->Length != 0) { Printf (" (%4d,%4d)", spans->TopOffset, spans->TopOffset+spans->Length-1); diff --git a/src/textures/textures.h b/src/textures/textures.h index 17cef6e1c..3b517ddf1 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -226,15 +226,15 @@ public: }; // Returns a single column of the texture - virtual const uint8_t *GetColumn(unsigned int column, const Span **spans_out) = 0;// delete; - //virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0; + virtual const uint8_t *GetColumn(unsigned int column, const Span **spans_out) = delete; + virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0; // Returns a single column of the texture, in BGRA8 format virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out); // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels() = 0;// delete; - //virtual const uint8_t *GetPixels(FRenderStyle style) = 0; + virtual const uint8_t *GetPixels() = delete; + virtual const uint8_t *GetPixels(FRenderStyle style) = 0; // Returns the whole texture, stored in column-major order, in BGRA8 format virtual const uint32_t *GetPixelsBgra(); @@ -285,7 +285,7 @@ public: // Returns true if the next call to GetPixels() will return an image different from the // last call to GetPixels(). This should be considered valid only if a call to CheckModified() // is immediately followed by a call to GetPixels(). - virtual bool CheckModified (); + virtual bool CheckModified (FRenderStyle style); static void InitGrayMap(); @@ -592,52 +592,50 @@ protected: FWorldTexture(const char *name = nullptr, int lumpnum = -1); ~FWorldTexture(); - // These should not be overridden. If that is needed, a class should inherit from something else - const uint8_t *GetColumn(unsigned int column, const Span **spans_out) override final; - const uint8_t *GetPixels() override final; - void Unload() override final; // should be removed after refactoring. + + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override; + const uint8_t *GetPixels(FRenderStyle style) override; + void Unload() override; virtual void MakeTexture() = delete; virtual uint8_t *MakeTexture(FRenderStyle style) = 0; + void FreeAllSpans(); }; // A texture that doesn't really exist -class FDummyTexture : public FWorldTexture +class FDummyTexture : public FTexture { public: FDummyTexture (); - uint8_t *MakeTexture(FRenderStyle); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override; + const uint8_t *GetPixels(FRenderStyle style) override; void SetSize (int width, int height); }; // A texture that returns a wiggly version of another texture. -class FWarpTexture : public FTexture +class FWarpTexture : public FWorldTexture { public: FWarpTexture (FTexture *source, int warptype); ~FWarpTexture (); + void Unload() override; - virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override; const uint32_t *GetPixelsBgra() override; - void Unload (); - bool CheckModified (); + bool CheckModified (FRenderStyle) override; float GetSpeed() const { return Speed; } int GetSourceLump() { return SourcePic->GetSourceLump(); } void SetSpeed(float fac) { Speed = fac; } FTexture *GetRedirect(bool wantwarped); - uint64_t GenTime; - uint64_t GenTimeBgra; - float Speed; + uint64_t GenTime[2] = { 0, 0 }; + uint64_t GenTimeBgra = 0; + float Speed = 1.f; int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] protected: FTexture *SourcePic; - uint8_t *Pixels; - Span **Spans; - virtual void MakeTexture (uint64_t time); + uint8_t *MakeTexture (FRenderStyle style) override; int NextPo2 (int v); // [mxd] void SetupMultipliers (int width, int height); // [mxd] }; @@ -652,17 +650,17 @@ public: FCanvasTexture (const char *name, int width, int height); ~FCanvasTexture (); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetPixels (FRenderStyle style); const uint32_t *GetPixelsBgra() override; void Unload (); - bool CheckModified (); + bool CheckModified (FRenderStyle) override; void NeedUpdate() { bNeedsUpdate=true; } void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; } DSimpleCanvas *GetCanvas() { return Canvas; } DSimpleCanvas *GetCanvasBgra() { return CanvasBgra; } bool Mipmapped() override { return false; } - void MakeTexture (); + void MakeTexture (FRenderStyle style); void MakeTextureBgra (); protected: diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 41920849d..d78bc5249 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -44,7 +44,7 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype) -: GenTime (0), GenTimeBgra(0), Speed (1.f), SourcePic (source), Pixels (0), Spans (0) + : SourcePic (source) { CopyInfo(source); if (warptype == 2) SetupMultipliers(256, 128); @@ -55,53 +55,25 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype) FWarpTexture::~FWarpTexture () { Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } delete SourcePic; } void FWarpTexture::Unload () { - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } SourcePic->Unload (); - FTexture::Unload(); + FWorldTexture::Unload(); + FreeAllSpans(); } -bool FWarpTexture::CheckModified () +bool FWarpTexture::CheckModified (FRenderStyle style) { - return screen->FrameTime != GenTime; -} - -const uint8_t *FWarpTexture::GetPixels () -{ - uint64_t time = screen->FrameTime; - - if (Pixels == NULL || time != GenTime) - { - MakeTexture (time); - } - return Pixels; + return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)]; } const uint32_t *FWarpTexture::GetPixelsBgra() { - uint64_t time = screen->FrameTime; - if (Pixels == NULL || time != GenTime) - MakeTexture(time); - - if (PixelsBgra.empty() || time != GenTimeBgra) + auto Pixels = GetPixels(DefaultRenderStyle()); + if (PixelsBgra.empty() || GenTime[0] != GenTimeBgra) { CreatePixelsBgraWithMipmaps(); for (int i = 0; i < Width * Height; i++) @@ -112,58 +84,21 @@ const uint32_t *FWarpTexture::GetPixelsBgra() PixelsBgra[i] = 0; } GenerateBgraMipmapsFast(); - GenTimeBgra = time; + GenTimeBgra = GenTime[0]; } return PixelsBgra.data(); } -const uint8_t *FWarpTexture::GetColumn(unsigned int column, const Span **spans_out) + +uint8_t *FWarpTexture::MakeTexture(FRenderStyle style) { - uint64_t time =screen->FrameTime; - - if (Pixels == NULL || time != GenTime) - { - MakeTexture (time); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - - -void FWarpTexture::MakeTexture(uint64_t time) -{ - const uint8_t *otherpix = SourcePic->GetPixels(); - - if (Pixels == NULL) - { - Pixels = new uint8_t[Width * Height]; - } - if (Spans != NULL) - { - FreeSpans(Spans); - Spans = NULL; - } - - GenTime = time; + uint64_t time = screen->FrameTime; + const uint8_t *otherpix = SourcePic->GetPixels(style); + auto Pixels = new uint8_t[Width * Height]; WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped); + FreeAllSpans(); + GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time; + return Pixels; } // [mxd] Non power of 2 textures need different offset multipliers, otherwise warp animation won't sync across texture diff --git a/src/textures/worldtexture.cpp b/src/textures/worldtexture.cpp index 896890236..db50c7fb4 100644 --- a/src/textures/worldtexture.cpp +++ b/src/textures/worldtexture.cpp @@ -56,6 +56,17 @@ FWorldTexture::FWorldTexture(const char *name, int lumpnum) FWorldTexture::~FWorldTexture() { Unload(); + FreeAllSpans(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FWorldTexture::FreeAllSpans() +{ for(int i = 0; i < 2; i++) { if (Spandata[i] != nullptr) @@ -91,9 +102,10 @@ void FWorldTexture::Unload () // //========================================================================== -const uint8_t *FWorldTexture::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) { - GetPixels(); + int index = !!(style.Flags & STYLEF_RedIsAlpha); + GetPixels(style); if ((unsigned)column >= (unsigned)Width) { if (WidthMask + 1 == Width) @@ -107,13 +119,13 @@ const uint8_t *FWorldTexture::GetColumn(unsigned int column, const Span **spans_ } if (spans_out != nullptr) { - if (Spandata[0] == nullptr) + if (Spandata[index] == nullptr) { - Spandata[0] = CreateSpans (Pixeldata[0]); + Spandata[index] = CreateSpans (Pixeldata[index]); } - *spans_out = Spandata[0][column]; + *spans_out = Spandata[index][column]; } - return Pixeldata[0] + column*Height; + return Pixeldata[index] + column*Height; } //========================================================================== @@ -122,16 +134,17 @@ const uint8_t *FWorldTexture::GetColumn(unsigned int column, const Span **spans_ // //========================================================================== -const uint8_t *FWorldTexture::GetPixels () +const uint8_t *FWorldTexture::GetPixels (FRenderStyle style) { - if (CheckModified()) + if (CheckModified(style)) { Unload(); } - if (Pixeldata[0] == nullptr) + int index = !!(style.Flags & STYLEF_RedIsAlpha); + if (Pixeldata[index] == nullptr) { - Pixeldata[0] = MakeTexture (LegacyRenderStyles[STYLE_Normal]); + Pixeldata[index] = MakeTexture (style); } - return Pixeldata[0]; + return Pixeldata[index]; } diff --git a/src/v_font.cpp b/src/v_font.cpp index 1b36c2219..e38ecfbde 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -177,8 +177,8 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); ~FFontChar1 (); @@ -198,8 +198,8 @@ public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels (); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -559,7 +559,7 @@ void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) for (x = pic->GetWidth() - 1; x >= 0; x--) { const FTexture::Span *spans; - const uint8_t *column = pic->GetColumn(x, &spans); + const uint8_t *column = pic->GetColumn(DefaultRenderStyle(), x, &spans); // This shouldn't use the spans... while (spans->Length != 0) { @@ -1649,9 +1649,11 @@ FFontChar1::FFontChar1 (FTexture *sourcelump) // // FFontChar1 :: GetPixels // +// Render style is not relevant for fonts. This must not use it! +// //========================================================================== -const uint8_t *FFontChar1::GetPixels () +const uint8_t *FFontChar1::GetPixels (FRenderStyle) { if (Pixels == NULL) { @@ -1666,12 +1668,12 @@ const uint8_t *FFontChar1::GetPixels () // //========================================================================== -void FFontChar1::MakeTexture () +void FFontChar1::MakeTexture () { // Make the texture as normal, then remap it so that all the colors // are at the low end of the palette Pixels = new uint8_t[Width*Height]; - const uint8_t *pix = BaseTexture->GetPixels(); + const uint8_t *pix = BaseTexture->GetPixels(DefaultRenderStyle()); if (!SourceRemap) { @@ -1692,14 +1694,14 @@ void FFontChar1::MakeTexture () // //========================================================================== -const uint8_t *FFontChar1::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) { if (Pixels == NULL) { MakeTexture (); } - BaseTexture->GetColumn(column, spans_out); + BaseTexture->GetColumn(DefaultRenderStyle(), column, spans_out); return Pixels + column*Height; } @@ -1797,9 +1799,11 @@ void FFontChar2::Unload () // // FFontChar2 :: GetPixels // +// Like for FontChar1, the render style has no relevance here as well. +// //========================================================================== -const uint8_t *FFontChar2::GetPixels () +const uint8_t *FFontChar2::GetPixels (FRenderStyle) { if (Pixels == NULL) { @@ -1814,7 +1818,7 @@ const uint8_t *FFontChar2::GetPixels () // //========================================================================== -const uint8_t *FFontChar2::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) { if (Pixels == NULL) { diff --git a/src/v_video.cpp b/src/v_video.cpp index 77f83b285..5e86b915b 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -135,9 +135,9 @@ class FPaletteTester : public FTexture public: FPaletteTester (); - const uint8_t *GetColumn(unsigned int column, const Span **spans_out); - const uint8_t *GetPixels(); - bool CheckModified(); + const uint8_t *GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) override; + const uint8_t *GetPixels(FRenderStyle); + bool CheckModified(FRenderStyle); void SetTranslation(int num); protected: @@ -983,7 +983,7 @@ FPaletteTester::FPaletteTester() // //========================================================================== -bool FPaletteTester::CheckModified() +bool FPaletteTester::CheckModified(FRenderStyle) { return CurTranslation != WantTranslation; } @@ -1008,7 +1008,7 @@ void FPaletteTester::SetTranslation(int num) // //========================================================================== -const uint8_t *FPaletteTester::GetColumn(unsigned int column, const Span **spans_out) +const uint8_t *FPaletteTester::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) { if (CurTranslation != WantTranslation) { @@ -1028,7 +1028,7 @@ const uint8_t *FPaletteTester::GetColumn(unsigned int column, const Span **spans // //========================================================================== -const uint8_t *FPaletteTester::GetPixels () +const uint8_t *FPaletteTester::GetPixels (FRenderStyle) { if (CurTranslation != WantTranslation) { From 04b8a12ca46d2f86906bf79d5fdc6f7909fffcb5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Mar 2018 20:02:38 +0100 Subject: [PATCH 22/37] - Build texture work. Currently broken. --- src/resourcefiles/file_zip.cpp | 2 + src/textures/buildtexture.cpp | 238 +++++++++++++++++++------------- src/textures/texturemanager.cpp | 12 +- src/textures/textures.h | 9 +- src/v_palette.cpp | 31 ----- src/w_wad.cpp | 13 ++ src/w_wad.h | 1 + 7 files changed, 163 insertions(+), 143 deletions(-) diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index bf51cd2a4..b3bfa7a2d 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -280,6 +280,8 @@ bool FZipFile::Open(bool quiet) } } } + // If it ran through the list without finding anything it should not attempt any path remapping. + if (!foundspeciallump) name0 = ""; dirptr = (char*)directory; lump_p = Lumps; diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 722328667..9984e8a19 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -39,8 +39,13 @@ #include "templates.h" #include "cmdlib.h" #include "st_start.h" +#include "colormatcher.h" +#include "bitmap.h" #include "textures/textures.h" #include "r_data/sprites.h" +#include "r_data/r_translate.h" +#include "resourcefiles/resourcefile.h" + //========================================================================== // @@ -51,11 +56,15 @@ class FBuildTexture : public FWorldTexture { public: - FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top); - uint8_t *MakeTexture(FRenderStyle style) override { return const_cast(Pixels); } // This is only to make it compile for now and will be changed later. + FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); + uint8_t *MakeTexture(FRenderStyle style) override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + bool UseBasePalette() override { return false; } + FTextureFormat GetFormat() override { return TEX_RGB; } protected: - const uint8_t *Pixels; + const uint8_t *RawPixels; + int Translation; }; @@ -65,8 +74,8 @@ protected: // //========================================================================== -FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int height, int left, int top) -: Pixels (pixels) +FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top) +: RawPixels (pixels), Translation(translation) { PixelsAreStatic = 3; Width = width; @@ -74,8 +83,29 @@ FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int LeftOffset = left; TopOffset = top; CalcBitSize (); - Name.Format("BTIL%04d", tilenum); - UseType = TEX_Build; + Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum); + UseType = TEX_Override; + PixelsAreStatic = 3; // test +} + +uint8_t *FBuildTexture::MakeTexture(FRenderStyle style) +{ + auto Pixels = new uint8_t[Width * Height]; + auto Remap = translationtables[TRANSLATION_Standard][Translation]; + for (int i = 0; i < Width*Height; i++) + { + auto c = RawPixels[i]; + Pixels[i] = c;// (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].r : Remap->Remap[c]; + } + return (uint8_t*)RawPixels; +} + +int FBuildTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +{ + auto Remap = translationtables[TRANSLATION_Standard][Translation]->Palette; + bmp->CopyPixelData(x, y, RawPixels, Width, Height, Height, 1, rotate, Remap, inf); + return 0; + } //=========================================================================== @@ -86,15 +116,16 @@ FBuildTexture::FBuildTexture (int tilenum, const uint8_t *pixels, int width, int // //=========================================================================== -void FTextureManager::AddTiles (void *tiles) +void FTextureManager::AddTiles (const FString &pathprefix, const void *tiles, int translation) { + // int numtiles = LittleLong(((uint32_t *)tiles)[1]); // This value is not reliable int tilestart = LittleLong(((uint32_t *)tiles)[2]); int tileend = LittleLong(((uint32_t *)tiles)[3]); const uint16_t *tilesizx = &((const uint16_t *)tiles)[8]; const uint16_t *tilesizy = &tilesizx[tileend - tilestart + 1]; const uint32_t *picanm = (const uint32_t *)&tilesizy[tileend - tilestart + 1]; - uint8_t *tiledata = (uint8_t *)&picanm[tileend - tilestart + 1]; + const uint8_t *tiledata = (const uint8_t *)&picanm[tileend - tilestart + 1]; for (int i = tilestart; i <= tileend; ++i) { @@ -110,15 +141,11 @@ void FTextureManager::AddTiles (void *tiles) if (width <= 0 || height <= 0) continue; - tex = new FBuildTexture (i, tiledata, width, height, xoffs, yoffs); + tex = new FBuildTexture (pathprefix, i, tiledata, translation, width, height, xoffs, yoffs); texnum = AddTexture (tex); - while (size > 0) - { - *tiledata = 255 - *tiledata; - tiledata++; - size--; - } - StartScreen->Progress(); + + // reactivate only if the texture counter works here. + //StartScreen->Progress(); if ((picanm[pic] & 63) && (picanm[pic] & 192)) { @@ -192,7 +219,7 @@ void FTextureManager::AddTiles (void *tiles) // //=========================================================================== -int FTextureManager::CountTiles (void *tiles) +static int CountTiles (const void *tiles) { int version = LittleLong(*(uint32_t *)tiles); if (version != 1) @@ -206,6 +233,60 @@ int FTextureManager::CountTiles (void *tiles) return tileend >= tilestart ? tileend - tilestart + 1 : 0; } +//=========================================================================== +// +// Create palette data and remap table for the tile set's palette +// +//=========================================================================== + +static int BuildPaletteTranslation(int lump) +{ + if (Wads.LumpLength(lump) < 768) + { + return false; + } + + FMemLump data = Wads.ReadLump(lump); + const uint8_t *ipal = (const uint8_t *)data.GetMem(); + FRemapTable opal; + + bool blood = false; + for (int c = 0; c < 765; c++) // Build used VGA palettes (color values 0..63), Blood used full palettes (0..255) Let's hope this doesn't screw up... + { + if (ipal[c] >= 64) + { + blood = true; + break; + } + } + + for (int c = 0; c < 255; c++) + { + int r, g, b; + if (!blood) + { + r = (ipal[3*c ] << 2) | (ipal[3 * c ] >> 4); + g = (ipal[3*c + 1] << 2) | (ipal[3 * c + 1] >> 4); + b = (ipal[3*c + 2] << 2) | (ipal[3 * c + 2] >> 4); + } + else + { + r = ipal[3 * c] << 2; + g = ipal[3 * c + 1] << 2; + b = ipal[3 * c + 2] << 2; + } + opal.Palette[c] = PalEntry(r, g, b, 255); + opal.Remap[c] = ColorMatcher.Pick(r, g, b); + } + // The last entry is transparent. + opal.Palette[255] = 0; + opal.Remap[255] = 0; + // Store the remap table in the translation manager so that we do not need to keep track of it ourselves. + // Slot 0 for internal translations is a convenient location because normally it only contains a small number of translations. + return GetTranslationType(opal.StoreTranslation(TRANSLATION_Standard)); +} + + //=========================================================================== // // R_CountBuildTiles @@ -215,98 +296,59 @@ int FTextureManager::CountTiles (void *tiles) // //=========================================================================== -int FTextureManager::CountBuildTiles () +void FTextureManager::InitBuildTiles() { - int numartfiles = 0; - char artfile[] = "tilesXXX.art"; int lumpnum; int numtiles; int totaltiles = 0; - lumpnum = Wads.CheckNumForFullName ("blood.pal"); - if (lumpnum >= 0) + // The search rules are as follows: + // - scan the entire lump directory for palette.dat files. + // - if one is found, process the directory for .ART files and add textures for them. + // - once all have been found, process all directories that may contain Build data. + // - the root is not excluded which allows to read this from .GRP files as well. + // - Blood support has been removed because it is not useful for modding to have loose .ART files. + // + // Unfortunately neither the palettes nor the .ART files contain any usable identifying marker + // so this can only go by the file names. + + int numlumps = Wads.GetNumLumps(); + for (int i = 0; i < numlumps; i++) { - // Blood's tiles are external resources. (Why did they do it like that?) - FString rffpath = Wads.GetWadFullName (Wads.GetLumpFile (lumpnum)); - int slashat = rffpath.LastIndexOf ('/'); - if (slashat >= 0) + const char *name = Wads.GetLumpFullName(i); + if (Wads.CheckNumForFullName(name) != i) continue; // This palette is hidden by a later one. Do not process + FString base = ExtractFileBase(name, true); + base.ToLower(); + if (base.Compare("palette.dat") == 0 && Wads.LumpLength(i) >= 768) // must be a valid palette, i.e. at least 256 colors. { - rffpath.Truncate (slashat + 1); - } - else - { - rffpath += '/'; - } + FString path = ExtractFilePath(name); + if (path.IsNotEmpty() && path.Back() != '/') path += '/'; - for (; numartfiles < 1000; numartfiles++) - { - artfile[5] = numartfiles / 100 + '0'; - artfile[6] = numartfiles / 10 % 10 + '0'; - artfile[7] = numartfiles % 10 + '0'; - - FString artpath = rffpath; - artpath += artfile; - - FileReader fr; - - if (!fr.OpenFile(artpath)) + int translation = BuildPaletteTranslation(i); + for (int numartfiles = 0; numartfiles < 1000; numartfiles++) { - break; - } + FStringf artpath("%stiles%03d.art", path.GetChars(), numartfiles); + // only read from the same source as the palette. + // The entire format here is just too volatile to allow liberal mixing. + // An .ART set must be treated as one unit. + lumpnum = Wads.CheckNumForFullName(artpath, Wads.GetLumpFile(i)); + if (lumpnum < 0) + { + break; + } - auto len = fr.GetLength(); - uint8_t *art = new uint8_t[len]; - if (fr.Read (art, len) != len || (numtiles = CountTiles(art)) == 0) - { - delete[] art; - } - else - { - BuildTileFiles.Push (art); - totaltiles += numtiles; + BuildTileData.Reserve(1); + auto &artdata = BuildTileData.Last(); + artdata.Resize(Wads.LumpLength(lumpnum)); + Wads.ReadLump(lumpnum, &artdata[0]); + + if ((numtiles = CountTiles(&artdata[0])) > 0) + { + AddTiles(path, &artdata[0], translation); + totaltiles += numtiles; + } } } } - - for (; numartfiles < 1000; numartfiles++) - { - artfile[5] = numartfiles / 100 + '0'; - artfile[6] = numartfiles / 10 % 10 + '0'; - artfile[7] = numartfiles % 10 + '0'; - lumpnum = Wads.CheckNumForFullName (artfile); - if (lumpnum < 0) - { - break; - } - - uint8_t *art = new uint8_t[Wads.LumpLength (lumpnum)]; - Wads.ReadLump (lumpnum, art); - - if ((numtiles = CountTiles(art)) == 0) - { - delete[] art; - } - else - { - BuildTileFiles.Push (art); - totaltiles += numtiles; - } - } - return totaltiles; } -//=========================================================================== -// -// R_InitBuildTiles -// -// [RH] Support Build tiles! -// -//=========================================================================== - -void FTextureManager::InitBuildTiles () -{ - for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) - { - AddTiles (BuildTileFiles[i]); - } -} diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index cdaf17a49..b16b5bd5e 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -137,12 +137,7 @@ void FTextureManager::DeleteAll() } } mAnimatedDoors.Clear(); - - for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) - { - delete[] BuildTileFiles[i]; - } - BuildTileFiles.Clear(); + BuildTileData.Clear(); } //========================================================================== @@ -982,8 +977,7 @@ void FTextureManager::Init() { DeleteAll(); SpriteFrames.Clear(); - // Init Build Tile data if it hasn't been done already - if (BuildTileFiles.Size() == 0) CountBuildTiles (); + //if (BuildTileFiles.Size() == 0) CountBuildTiles (); FTexture::InitGrayMap(); // Texture 0 is a dummy texture used to indicate "no texture" @@ -1131,7 +1125,7 @@ int FTextureManager::GuesstimateNumTextures () } } - numtex += CountBuildTiles (); + //numtex += CountBuildTiles (); // this cannot be done with a lot of overhead so just leave it out. numtex += CountTexturesX (); return numtex; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 3b517ddf1..f9aec0b9b 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -207,7 +207,6 @@ public: TEX_Flat, TEX_Sprite, TEX_WallPatch, - TEX_Build, TEX_SkinSprite, TEX_Decal, TEX_MiscPatch, @@ -524,9 +523,8 @@ private: int CountLumpTextures (int lumpnum); // Build tiles - void AddTiles (void *tiles); - int CountTiles (void *tiles); - int CountBuildTiles (); + void AddTiles (const FString &pathprefix, const void *, int translation); + //int CountBuildTiles (); void InitBuildTiles (); // Animation stuff @@ -568,11 +566,12 @@ private: FTextureID DefaultTexture; TArray FirstTextureForFile; TMap PalettedVersions; // maps from normal -> paletted version + TArray > BuildTileData; TArray mAnimations; TArray mSwitchDefs; TArray mAnimatedDoors; - TArray BuildTileFiles; + public: short sintable[2048]; // for texture warping enum diff --git a/src/v_palette.cpp b/src/v_palette.cpp index af4aae4fb..654526a20 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -340,37 +340,6 @@ void ReadPalette(int lumpnum, uint8_t *buffer) } } -static bool FixBuildPalette (uint8_t *opal, int lump, bool blood) -{ - if (Wads.LumpLength (lump) < 768) - { - return false; - } - - FMemLump data = Wads.ReadLump (lump); - const uint8_t *ipal = (const uint8_t *)data.GetMem(); - - // Reverse the palette because BUILD used entry 255 as - // transparent, but we use 0 as transparent. - - for (int c = 0; c < 768; c += 3) - { - if (!blood) - { - opal[c] = (ipal[765-c] << 2) | (ipal[765-c] >> 4); - opal[c+1] = (ipal[766-c] << 2) | (ipal[766-c] >> 4); - opal[c+2] = (ipal[767-c] << 2) | (ipal[767-c] >> 4); - } - else - { - opal[c] = ipal[765-c]; - opal[c+1] = ipal[766-c]; - opal[c+2] = ipal[767-c]; - } - } - return true; -} - void InitPalette () { uint8_t pal[768]; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index e084d4c74..31e65cd9b 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1255,6 +1255,19 @@ int FWadCollection::GetLumpFile (int lump) const return LumpInfo[lump].wadnum; } +//========================================================================== +// +// W_GetLumpFile +// +//========================================================================== + +FResourceLump *FWadCollection::GetLumpRecord(int lump) const +{ + if ((size_t)lump >= LumpInfo.Size()) + return nullptr; + return LumpInfo[lump].lump; +} + //========================================================================== // // W_ReadLump diff --git a/src/w_wad.h b/src/w_wad.h index 114a37039..9f33ac2c1 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -170,6 +170,7 @@ public: int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to int GetLumpIndexNum (int lump) const; // Returns the RFF index number for this lump + FResourceLump *GetLumpRecord(int lump) const; // Returns the FResourceLump, in case the caller wants to have direct access to the lump cache. bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match bool IsEncryptedFile(int lump) const; From bf2003fe6abf0239e8e306b3b51d257584067ef1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Mar 2018 20:09:32 +0100 Subject: [PATCH 23/37] - fixed pixel address. Colors still need work. --- src/textures/buildtexture.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 9984e8a19..a78f7fc6e 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -143,6 +143,7 @@ void FTextureManager::AddTiles (const FString &pathprefix, const void *tiles, in tex = new FBuildTexture (pathprefix, i, tiledata, translation, width, height, xoffs, yoffs); texnum = AddTexture (tex); + tiledata += size; // reactivate only if the texture counter works here. //StartScreen->Progress(); From 16f6a8868016b7a05a9cae63149c01909ed6e515 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Mar 2018 20:56:04 +0100 Subject: [PATCH 24/37] - fixed Build tiles and removed test code. --- src/textures/buildtexture.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index a78f7fc6e..27eff0bff 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -85,24 +85,23 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 CalcBitSize (); Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum); UseType = TEX_Override; - PixelsAreStatic = 3; // test } uint8_t *FBuildTexture::MakeTexture(FRenderStyle style) { auto Pixels = new uint8_t[Width * Height]; - auto Remap = translationtables[TRANSLATION_Standard][Translation]; + FRemapTable *Remap = translationtables[TRANSLATION_Standard][Translation]; for (int i = 0; i < Width*Height; i++) { auto c = RawPixels[i]; - Pixels[i] = c;// (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].r : Remap->Remap[c]; + Pixels[i] = (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].r : Remap->Remap[c]; } return (uint8_t*)RawPixels; } int FBuildTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) { - auto Remap = translationtables[TRANSLATION_Standard][Translation]->Palette; + PalEntry *Remap = translationtables[TRANSLATION_Standard][Translation]->Palette; bmp->CopyPixelData(x, y, RawPixels, Width, Height, Height, 1, rotate, Remap, inf); return 0; @@ -276,7 +275,7 @@ static int BuildPaletteTranslation(int lump) g = ipal[3 * c + 1] << 2; b = ipal[3 * c + 2] << 2; } - opal.Palette[c] = PalEntry(r, g, b, 255); + opal.Palette[c] = PalEntry(255, r, g, b); opal.Remap[c] = ColorMatcher.Pick(r, g, b); } // The last entry is transparent. @@ -284,7 +283,7 @@ static int BuildPaletteTranslation(int lump) opal.Remap[255] = 0; // Store the remap table in the translation manager so that we do not need to keep track of it ourselves. // Slot 0 for internal translations is a convenient location because normally it only contains a small number of translations. - return GetTranslationType(opal.StoreTranslation(TRANSLATION_Standard)); + return GetTranslationIndex(opal.StoreTranslation(TRANSLATION_Standard)); } From cf67883e6a9b3b50c4a133df2f3e1420f819744d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Mar 2018 21:01:32 +0100 Subject: [PATCH 25/37] - changed copyright notice. --- src/textures/buildtexture.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 27eff0bff..96e24af21 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -1,9 +1,10 @@ /* ** buildtexture.cpp -** Handling Build textures +** Handling Build textures (now as a usable editing feature!) ** **--------------------------------------------------------------------------- ** Copyright 2004-2006 Randy Heit +** Copyright 2018 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without From 5f4e4d859eaae617d303a5543e1c1181a2ef61d5 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 20 Mar 2018 01:28:25 +0100 Subject: [PATCH 26/37] - Fix netgame freeze situation --- src/d_net.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_net.cpp b/src/d_net.cpp index 57dbb93b7..9535a4342 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1914,6 +1914,10 @@ void TryRunTics (void) // Check possible stall conditions Net_CheckLastReceived (counts); + // Update time returned by I_GetTime, but only if we are stuck in this loop + if (lowtic >= gametic + counts) + I_SetFrameTime(); + // don't stay in here forever -- give the menu a chance to work if (I_GetTime () - entertic >= 1) { From 09c0bed74fe38653c7e7c59606a2ee09d39e161a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 20 Mar 2018 01:29:43 +0100 Subject: [PATCH 27/37] - Oops, last commit had its check inverted --- src/d_net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 9535a4342..7681626d0 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1915,7 +1915,7 @@ void TryRunTics (void) Net_CheckLastReceived (counts); // Update time returned by I_GetTime, but only if we are stuck in this loop - if (lowtic >= gametic + counts) + if (lowtic < gametic + counts) I_SetFrameTime(); // don't stay in here forever -- give the menu a chance to work From 6f68b6c3520f66ae0a54346c6f357a5f53dedec0 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 20 Mar 2018 10:29:28 +0200 Subject: [PATCH 28/37] Fixed JPEG errors reporting GCC/Clang reported these warnings: src/textures/jpegtexture.cpp:305:29: warning: data argument not used by format string [-Wformat-extra-args] src/textures/jpegtexture.cpp:388:28: warning: data argument not used by format string [-Wformat-extra-args] src/textures/jpegtexture.cpp:432:29: warning: data argument not used by format string [-Wformat-extra-args] src/textures/jpegtexture.cpp:481:28: warning: data argument not used by format string [-Wformat-extra-args] --- src/textures/jpegtexture.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index 93aac09ca..33ecaf148 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -302,7 +302,7 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf(TEXTCOLOR_ORANGE, "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } else { @@ -385,7 +385,7 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) } catch (int) { - Printf(TEXTCOLOR_ORANGE, "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } jpeg_destroy_decompress(&cinfo); if (buff != NULL) @@ -429,7 +429,7 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf(TEXTCOLOR_ORANGE, "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } else { @@ -478,7 +478,7 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC } catch (int) { - Printf(TEXTCOLOR_ORANGE, "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } jpeg_destroy_decompress(&cinfo); if (buff != NULL) delete [] buff; From f242f0631b19e4fbb9991ca07c246a1c12af9615 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 20 Mar 2018 18:01:35 +0200 Subject: [PATCH 29/37] Fixed crash in when MP3 length guesstimation failed https://forum.zdoom.org/viewtopic.php?t=59881 --- src/sound/musicformats/music_libsndfile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index b87492a4e..3a44d9f56 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -298,8 +298,9 @@ SndFileSong::SndFileSong(FileReader &reader, SoundDecoder *decoder, uint32_t loo if (!startass) loop_start = Scale(loop_start, SampleRate, 1000); if (!endass) loop_end = Scale(loop_end, SampleRate, 1000); + const uint32_t sampleLength = (uint32_t)decoder->getSampleLength(); Loop_Start = loop_start; - Loop_End = clamp(loop_end, 0, (uint32_t)decoder->getSampleLength()); + Loop_End = sampleLength == 0 ? loop_end : clamp(loop_end, 0, sampleLength); Reader = std::move(reader); Decoder = decoder; Channels = iChannels == ChannelConfig_Stereo? 2:1; From b0c96ac43d5867bb35373af4a62de21cf4a5dd93 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 20 Mar 2018 18:29:54 +0100 Subject: [PATCH 30/37] - fixed uninitialized variables in files.h. --- src/files.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/files.h b/src/files.h index 096452269..89e6a091d 100644 --- a/src/files.h +++ b/src/files.h @@ -201,56 +201,56 @@ public: uint8_t ReadUInt8() { - uint8_t v; + uint8_t v = 0; Read(&v, 1); return v; } int8_t ReadInt8() { - int8_t v; + int8_t v = 0; Read(&v, 1); return v; } uint16_t ReadUInt16() { - uint16_t v; + uint16_t v = 0; Read(&v, 2); return LittleShort(v); } int16_t ReadInt16() { - uint16_t v; + uint16_t v = 0; Read(&v, 2); return LittleShort(v); } uint32_t ReadUInt32() { - uint32_t v; + uint32_t v = 0; Read(&v, 4); return LittleLong(v); } int32_t ReadInt32() { - uint32_t v; + uint32_t v = 0; Read(&v, 4); return LittleLong(v); } uint32_t ReadUInt32BE() { - uint32_t v; + uint32_t v = 0; Read(&v, 4); return BigLong(v); } int32_t ReadInt32BE() { - uint32_t v; + uint32_t v = 0; Read(&v, 4); return BigLong(v); } From 568d439c242bfac33ed85b84ee073da91621fb7a Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 20 Mar 2018 10:13:10 +0200 Subject: [PATCH 31/37] Removed deleted virtual functions This solves linking errors on macOS with missing ___cxa_deleted_virtual symbol --- src/textures/textures.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/textures/textures.h b/src/textures/textures.h index f9aec0b9b..52fd089c8 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -225,14 +225,12 @@ public: }; // Returns a single column of the texture - virtual const uint8_t *GetColumn(unsigned int column, const Span **spans_out) = delete; virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0; // Returns a single column of the texture, in BGRA8 format virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out); // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels() = delete; virtual const uint8_t *GetPixels(FRenderStyle style) = 0; // Returns the whole texture, stored in column-major order, in BGRA8 format @@ -595,7 +593,6 @@ protected: const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override; const uint8_t *GetPixels(FRenderStyle style) override; void Unload() override; - virtual void MakeTexture() = delete; virtual uint8_t *MakeTexture(FRenderStyle style) = 0; void FreeAllSpans(); }; From 4ad769572f054b7337152359e47606a7b4cf0d73 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 20 Mar 2018 22:02:18 -0400 Subject: [PATCH 32/37] - bump stats version string, send stats to new stats script instead --- src/d_stats.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index bf3855dad..47c8108c0 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -35,8 +35,8 @@ CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFI CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) // Each machine will only send two reports, one when started with hardware rendering and one when started with software rendering. -#define CHECKVERSION 330 -#define CHECKVERSIONSTR "330" +#define CHECKVERSION 331 +#define CHECKVERSIONSTR "331" CVAR(Int, sentstats_swr_done, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) CVAR(Int, sentstats_hwr_done, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) @@ -291,7 +291,7 @@ void D_DoAnonStats() if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return; static char requeststring[1024]; - mysnprintf(requeststring, sizeof requeststring, "GET /stats.php?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", + mysnprintf(requeststring, sizeof requeststring, "GET /stats.py?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); std::thread t1(D_DoHTTPRequest, requeststring); From fae6f22a2bcc313336b33f2eaa2b3b39e430b40e Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Wed, 21 Mar 2018 03:50:47 -0400 Subject: [PATCH 33/37] - fix botched merge --- src/d_stats.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/d_stats.cpp b/src/d_stats.cpp index dad85837a..e6c0e196b 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -38,7 +38,6 @@ extern int sys_ostype; EXTERN_CVAR(Bool, vid_glswfb) extern int currentrenderer; - CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) @@ -359,26 +358,3 @@ void D_ConfirmSendStats() } #endif // NO_SEND_STATS - -void D_ConfirmSendStats() -{ - if (sys_statsenabled >= 0) - { - return; - } - - // TODO: texts - static const char *const MESSAGE_TEXT = "send stats?"; - static const char *const TITLE_TEXT = GAMENAME; - - UCVarValue enabled = { 0 }; - -#ifdef _WIN32 - extern HWND Window; - enabled = { MessageBox(Window, MESSAGE_TEXT, TITLE_TEXT, MB_ICONQUESTION | MB_YESNO) == IDYES }; -#else - // TODO -#endif - - sys_statsenabled.ForceSet(enabled, CVAR_Int); -} From d58169f1b028df0b5dd36b24c14464a155c529d1 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 21 Mar 2018 12:28:12 +0200 Subject: [PATCH 34/37] Fixed crash with very short music loop https://forum.zdoom.org/viewtopic.php?t=59883 --- src/sound/musicformats/music_libsndfile.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index 3a44d9f56..61be6b56c 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -420,12 +420,17 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat // This looks a bit more complicated than necessary because libmpg123 will not read the full requested length for the last block in the file. if (currentpos + framestoread > song->Loop_End) { - size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2; - size_t endlen = song->Decoder->read(buff, endblock); + // Loop can be very short, make sure the current position doesn't exceed it + if (currentpos < song->Loop_End) + { + size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2; + size_t endlen = song->Decoder->read(buff, endblock); + + // Even if zero bytes was read give it a chance to start from the beginning + buff += endlen; + len -= endlen; + } - // Even if zero bytes was read give it a chance to start from the beginning - buff = buff + endlen; - len -= endlen; song->Decoder->seek(song->Loop_Start, false, true); } while (len > 0) From 88bebaec3999335d8d79601c9a0191ebcb450858 Mon Sep 17 00:00:00 2001 From: drfrag Date: Tue, 20 Mar 2018 18:36:00 +0100 Subject: [PATCH 35/37] - Fixed not getting the 'old and unsupported DeHackEd patch' error message for some old patch versions. --- src/d_dehacked.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 76bcc1931..75e873648 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2536,7 +2536,7 @@ static bool DoDehPatch() cont = 0; if (0 == strncmp (PatchFile, "Patch File for DeHackEd v", 25)) { - if (PatchFile[25] < '3' && PatchFile[25] != '2' && PatchFile[27] != '3') + if (PatchFile[25] < '3' && (PatchFile[25] < '2' || PatchFile[27] < '3')) { Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchName); delete[] PatchName; From 92f10febe86d0bb39de53711c5926a4609848b7e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 21 Mar 2018 13:03:44 +0200 Subject: [PATCH 36/37] Fixed crash on loading malformed DeHackEd patches Lump that contains only "Patch File for DeHackEd v3.0" (without line break at the end) caused a crash --- src/d_dehacked.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 75e873648..b7587bd2d 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -564,6 +564,8 @@ static void stripwhite (char *str) static char *igets (void) { + assert(PatchPt != nullptr); + char *line; if (*PatchPt == '\0' || PatchPt >= PatchFile + PatchSize ) @@ -2550,7 +2552,7 @@ static bool DoDehPatch() } PatchPt = strchr (PatchFile, '\n'); - while ((cont = GetLine()) == 1) + while (PatchPt != nullptr && (cont = GetLine()) == 1) { CHECKKEY ("Doom version", dversion) else CHECKKEY ("Patch format", pversion) From de0a8152153f2682bb864915557bf77462c90136 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 21 Mar 2018 13:06:41 +0200 Subject: [PATCH 37/37] Fixed error reporting on loading malformed DeHackEd patches --- src/d_dehacked.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index b7587bd2d..a3e2773af 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2559,9 +2559,9 @@ static bool DoDehPatch() } if (!cont || dversion == -1 || pversion == -1) { + Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", PatchName); delete[] PatchName; delete[] PatchFile; - Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", PatchFile); return false; } }