From d52600663dfea6f13e758087be53fc6b4a5ba3d0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 May 2020 23:12:04 +0200 Subject: [PATCH] - backend sync with GZDoom to pull in a few bugfixes and formatting corrections. --- source/common/2d/v_2ddrawer.cpp | 133 ++++++++++++-- source/common/2d/v_2ddrawer.h | 10 +- source/common/2d/v_draw.cpp | 17 +- source/common/2d/v_draw.h | 1 - source/common/audio/music/music.cpp | 97 +++++----- source/common/audio/sound/s_soundinternal.h | 1 - source/common/console/c_bind.cpp | 22 ++- source/common/engine/cycler.cpp | 160 +++++++++++++++++ source/common/engine/cycler.h | 43 +++++ source/common/engine/i_interface.h | 7 +- source/common/engine/namedef.h | 1 + source/common/engine/palettecontainer.h | 1 + source/common/engine/serializer.cpp | 2 - source/common/fonts/v_font.cpp | 41 +++-- source/common/fonts/v_font.h | 5 +- source/common/objects/dobject.h | 2 +- source/common/platform/posix/cocoa/i_input.mm | 1 + .../common/platform/posix/cocoa/i_system.mm | 2 +- source/common/platform/posix/cocoa/i_video.mm | 6 +- .../common/platform/posix/i_system_posix.cpp | 52 +++--- source/common/platform/posix/sdl/i_main.cpp | 1 - .../common/platform/posix/sdl/sdlglvideo.cpp | 9 +- .../common/platform/win32/win32basevideo.cpp | 2 +- source/common/platform/win32/win32glvideo.cpp | 2 +- source/common/platform/win32/win32polyvideo.h | 2 +- .../common/platform/win32/win32vulkanvideo.h | 2 +- source/common/scripting/backend/codegen.cpp | 9 +- source/common/scripting/core/dictionary.cpp | 4 +- source/common/scripting/core/dynarrays.cpp | 4 - source/common/scripting/core/imports.cpp | 4 - .../scripting/interface/stringformat.cpp | 4 - .../textures/formats/multipatchtexture.h | 2 +- source/common/textures/gametexture.cpp | 6 +- source/common/textures/gametexture.h | 23 ++- source/common/textures/hires/hqresize.cpp | 2 +- source/common/textures/image.cpp | 2 - source/common/textures/imagetexture.cpp | 16 +- .../textures/multipatchtexturebuilder.cpp | 30 ++-- source/common/textures/skyboxtexture.cpp | 1 - source/common/textures/textureid.h | 6 + source/common/textures/texturemanager.cpp | 6 + source/common/textures/texturemanager.h | 2 +- source/common/textures/textures.h | 9 +- source/common/textures/v_collection.cpp | 82 +++++++++ source/common/textures/v_collection.h | 58 ++++++ source/common/utility/basics.h | 3 + source/common/utility/cmdlib.cpp | 8 +- source/common/utility/findfile.cpp | 2 + source/common/utility/findfile.h | 1 + source/common/utility/intrect.h | 31 ++++ source/common/utility/m_bbox.h | 87 +++++++++ source/common/utility/r_memory.cpp | 101 +++++++++++ source/common/utility/r_memory.h | 43 +++++ source/common/utility/weightedlist.h | 166 ++++++++++++++++++ source/core/rendering/v_video.h | 30 +--- 55 files changed, 1121 insertions(+), 243 deletions(-) create mode 100644 source/common/engine/cycler.cpp create mode 100644 source/common/engine/cycler.h create mode 100644 source/common/textures/v_collection.cpp create mode 100644 source/common/textures/v_collection.h create mode 100644 source/common/utility/intrect.h create mode 100644 source/common/utility/m_bbox.h create mode 100644 source/common/utility/r_memory.cpp create mode 100644 source/common/utility/r_memory.h create mode 100644 source/common/utility/weightedlist.h diff --git a/source/common/2d/v_2ddrawer.cpp b/source/common/2d/v_2ddrawer.cpp index 704d2e1cf..b397cc88d 100644 --- a/source/common/2d/v_2ddrawer.cpp +++ b/source/common/2d/v_2ddrawer.cpp @@ -37,11 +37,15 @@ #include "vm.h" #include "c_cvars.h" #include "v_draw.h" +#include "v_video.h" #include "fcolormap.h" -F2DDrawer* twod; +static F2DDrawer drawer; +F2DDrawer* twod = &drawer; EXTERN_CVAR(Float, transsouls) +CVAR(Float, classic_scaling_factor, 1.0, CVAR_ARCHIVE) +CVAR(Float, classic_scaling_pixelaspect, 1.2f, CVAR_ARCHIVE) IMPLEMENT_CLASS(DShape2DTransform, false, false) @@ -393,6 +397,7 @@ void F2DDrawer::SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcol void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms) { if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn. + assert(img && img->isValid()); double xscale = parms.destwidth / parms.texwidth; double yscale = parms.destheight / parms.texheight; @@ -676,7 +681,20 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigne // //========================================================================== -void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin) +float F2DDrawer::GetClassicFlatScalarWidth() +{ + float ar = 4.f / 3.f / (float)ActiveRatio((float)screen->GetWidth(), (float)screen->GetHeight()); + float sw = 320.f * classic_scaling_factor / (float)screen->GetWidth() / ar; + return sw; +} + +float F2DDrawer::GetClassicFlatScalarHeight() +{ + float sh = 240.f / classic_scaling_pixelaspect * classic_scaling_factor / (float)screen->GetHeight(); + return sh; +} + +void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin, double flatscale) { float fU1, fU2, fV1, fV2; @@ -689,27 +707,100 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu dg.mTexture = src; dg.mFlags = DTF_Wrap; - // scaling is not used here. - if (!local_origin) - { - fU1 = float(left) / (float)src->GetDisplayWidth(); - fV1 = float(top) / (float)src->GetDisplayHeight(); - fU2 = float(right) / (float)src->GetDisplayWidth(); - fV2 = float(bottom) / (float)src->GetDisplayHeight(); - } - else + float fs = 1.f / float(flatscale); + bool flipc = false; + + float sw = GetClassicFlatScalarWidth(); + float sh = GetClassicFlatScalarHeight(); + + switch (local_origin) { + case 0: + fU1 = float(left) / (float)src->GetDisplayWidth() * fs; + fV1 = float(top) / (float)src->GetDisplayHeight() * fs; + fU2 = float(right) / (float)src->GetDisplayWidth() * fs; + fV2 = float(bottom) / (float)src->GetDisplayHeight() * fs; + break; + + case 1: fU1 = 0; fV1 = 0; - fU2 = float(right - left) / (float)src->GetDisplayWidth(); - fV2 = float(bottom - top) / (float)src->GetDisplayHeight(); + fU2 = float(right - left) / (float)src->GetDisplayWidth() * fs; + fV2 = float(bottom - top) / (float)src->GetDisplayHeight() * fs; + break; + + // The following are for drawing frames with elements of pnly one orientation + case 2: // flip vertically + fU1 = 0; + fV2 = 0; + fU2 = float(right - left) / (float)src->GetDisplayWidth() * fs; + fV1 = float(bottom - top) / (float)src->GetDisplayHeight() * fs; + break; + + case 3: // flip horizontally + fU2 = 0; + fV1 = 0; + fU1 = float(right - left) / (float)src->GetDisplayWidth() * fs; + fV2 = float(bottom - top) / (float)src->GetDisplayHeight() * fs; + break; + + case 4: // flip vertically and horizontally + fU2 = 0; + fV2 = 0; + fU1 = float(right - left) / (float)src->GetDisplayWidth() * fs; + fV1 = float(bottom - top) / (float)src->GetDisplayHeight() * fs; + break; + + + case 5: // flip coordinates + fU1 = 0; + fV1 = 0; + fU2 = float(bottom - top) / (float)src->GetDisplayWidth() * fs; + fV2 = float(right - left) / (float)src->GetDisplayHeight() * fs; + break; + + case 6: // flip coordinates and vertically + fU2 = 0; + fV1 = 0; + fU1 = float(bottom - top) / (float)src->GetDisplayWidth() * fs; + fV2 = float(right - left) / (float)src->GetDisplayHeight() * fs; + break; + + case 7: // flip coordinates and horizontally + fU1 = 0; + fV2 = 0; + fU2 = float(bottom - top) / (float)src->GetDisplayWidth() * fs; + fV1 = float(right - left) / (float)src->GetDisplayHeight() * fs; + break; + + case -1: // classic flat scaling + fU1 = float(left) / (float)src->GetDisplayWidth() * fs * sw; + fV1 = float(top) / (float)src->GetDisplayHeight() * fs * sh; + fU2 = float(right) / (float)src->GetDisplayWidth() * fs * sw; + fV2 = float(bottom) / (float)src->GetDisplayHeight() * fs * sh; + break; + + case -2: // classic scaling for screen bevel + fU1 = 0; + fV1 = 0; + fU2 = float(right - left) / (float)src->GetDisplayWidth() * fs * sw; + fV2 = float(bottom - top) / (float)src->GetDisplayHeight() * fs * sh; + break; } dg.mVertIndex = (int)mVertices.Reserve(4); auto ptr = &mVertices[dg.mVertIndex]; ptr->Set(left, top, 0, fU1, fV1, 0xffffffff); ptr++; - ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++; - ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++; + if (local_origin < 4) + { + ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++; + ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++; + } + else + { + ptr->Set(left, bottom, 0, fU2, fV1, 0xffffffff); ptr++; + ptr->Set(right, top, 0, fU1, fV2, 0xffffffff); ptr++; + } ptr->Set(right, bottom, 0, fU2, fV2, 0xffffffff); ptr++; dg.mIndexIndex = mIndices.Size(); dg.mIndexCount += 6; @@ -720,11 +811,11 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu //=========================================================================== // -// +// // //=========================================================================== -void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style) +void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style, bool prepend) { RenderCommand dg; @@ -740,7 +831,13 @@ void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, F dg.mIndexIndex = mIndices.Size(); dg.mIndexCount += 6; AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2); - AddCommand(&dg); + if (!prepend) AddCommand(&dg); + else + { + // Only needed by Raze's fullscreen blends because they are being calculated late when half of the 2D content has already been submitted, + // This ensures they are below the HUD, not above it. + mData.Insert(0, dg); + } } void F2DDrawer::ClearScreen(PalEntry color) diff --git a/source/common/2d/v_2ddrawer.h b/source/common/2d/v_2ddrawer.h index 7e410a11e..bd8797d4c 100644 --- a/source/common/2d/v_2ddrawer.h +++ b/source/common/2d/v_2ddrawer.h @@ -174,6 +174,8 @@ private: void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor); public: + float GetClassicFlatScalarWidth(); + float GetClassicFlatScalarHeight(); void AddTexture(FGameTexture* img, DrawParms& parms); void AddShape(FGameTexture *img, DShape2D *shape, DrawParms &parms); void AddPoly(FGameTexture *texture, FVector2 *points, int npoints, @@ -182,13 +184,13 @@ public: void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2); void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex, int clipx1, int clipy1, int clipx2, int clipy2); - void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, bool local_origin = false); + void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0); - void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr); + void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr, bool prepend = false); void ClearScreen(PalEntry color = 0xff000000); void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h); void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - + void AddLine(double x1, double y1, double x2, double y2, int cx, int cy, int cx2, int cy2, uint32_t color, uint8_t alpha = 255); void AddThickLine(int x1, int y1, int x2, int y2, double thickness, uint32_t color, uint8_t alpha = 255); @@ -198,7 +200,7 @@ public: int GetWidth() const { return Width; } int GetHeight() const { return Height; } void SetSize(int w, int h) { Width = w; Height = h; } - void Begin() { isIn2D = true; } + void Begin(int w, int h) { isIn2D = true; Width = w; Height = h; } void End() { isIn2D = false; } bool HasBegun2D() { return isIn2D; } diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index bf33d6f6a..4a5853a34 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -43,6 +43,7 @@ EXTERN_CVAR(Int, vid_aspect) EXTERN_CVAR(Int, uiscale) +CVAR(Bool, ui_screenborder_classic_scaling, true, CVAR_ARCHIVE) // Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none. int ActiveFakeRatio(int width, int height) @@ -1161,10 +1162,11 @@ void FillBorder (F2DDrawer *drawer, FGameTexture *img) if (img != NULL) { - drawer->AddFlatFill(0, 0, Width, bordtop, img); // Top - drawer->AddFlatFill(0, bordtop, bordleft, Height - bordbottom, img); // Left - drawer->AddFlatFill(Width - bordright, bordtop, Width, Height - bordbottom, img); // Right - drawer->AddFlatFill(0, Height - bordbottom, Width, Height, img); // Bottom + int filltype = (ui_screenborder_classic_scaling) ? -1 : 0; + drawer->AddFlatFill(0, 0, Width, bordtop, img, filltype); // Top + drawer->AddFlatFill(0, bordtop, bordleft, Height - bordbottom, img, filltype); // Left + drawer->AddFlatFill(Width - bordright, bordtop, Width, Height - bordbottom, img, filltype); // Right + drawer->AddFlatFill(0, Height - bordbottom, Width, Height, img, filltype); // Bottom } else { @@ -1222,7 +1224,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Screen, DrawThickLine, DrawThickLine) //========================================================================== // -// DCanvas :: Clear +// ClearRect // // Set an area to a specified color. // @@ -1281,7 +1283,7 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear) //========================================================================== // -// DCanvas :: Dim +// DoDim // // Applies a colored overlay to an area of the screen. // @@ -1351,9 +1353,10 @@ DEFINE_ACTION_FUNCTION(_Screen, Dim) void DrawBorder (F2DDrawer *drawer, FTextureID picnum, int x1, int y1, int x2, int y2) { + int filltype = (ui_screenborder_classic_scaling) ? -1 : 0; if (picnum.isValid()) { - drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(picnum, false)); + drawer->AddFlatFill (x1, y1, x2, y2, TexMan.GetGameTexture(picnum, false), filltype); } else { diff --git a/source/common/2d/v_draw.h b/source/common/2d/v_draw.h index fe76272f5..2322232e7 100644 --- a/source/common/2d/v_draw.h +++ b/source/common/2d/v_draw.h @@ -219,7 +219,6 @@ void DoDim(F2DDrawer* drawer, PalEntry color, float amount, int x1, int y1, int void Dim(F2DDrawer* drawer, PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr); void FillBorder(F2DDrawer *drawer, FGameTexture* img); // Fills the border around a 4:3 part of the screen on non-4:3 displays -void DrawFrame(F2DDrawer* drawer, int left, int top, int width, int height); void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2); void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness); diff --git a/source/common/audio/music/music.cpp b/source/common/audio/music/music.cpp index 683a6a02b..2d9008021 100644 --- a/source/common/audio/music/music.cpp +++ b/source/common/audio/music/music.cpp @@ -39,7 +39,6 @@ #include #include - #include "i_sound.h" #include "i_music.h" #include "printf.h" @@ -51,13 +50,6 @@ #include "filereadermusicinterface.h" #include -static bool MusicPaused; // whether music is paused -MusPlayingInfo mus_playing; // music currently being played -static FPlayList PlayList; -float relative_volume = 1.f; -float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function -MusicVolumeMap MusicVolumes; -MidiDeviceMap MidiDevices; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- extern float S_GetMusicVolume (const char *music); @@ -66,6 +58,13 @@ static void S_ActivatePlayList(bool goBack); // PRIVATE DATA DEFINITIONS ------------------------------------------------ +static bool MusicPaused; // whether music is paused +MusPlayingInfo mus_playing; // music currently being played +static FPlayList PlayList; +float relative_volume = 1.f; +float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function +MusicVolumeMap MusicVolumes; +MidiDeviceMap MidiDevices; static FileReader DefaultOpenMusic(const char* fn) { @@ -223,10 +222,10 @@ void S_UpdateMusic () } else { - S_StopMusic(true); + S_StopMusic(true); + } } } - } } //========================================================================== @@ -265,11 +264,11 @@ void S_ActivatePlayList (bool goBack) { pos = goBack ? PlayList.Backup () : PlayList.Advance (); if (pos == startpos) - { + { PlayList.Clear(); Printf ("Cannot play anything in the playlist.\n"); return; - } + } } } @@ -342,48 +341,48 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) return true; } - int lumpnum = -1; - int length = 0; - ZMusic_MusicStream handle = nullptr; + int lumpnum = -1; + int length = 0; + ZMusic_MusicStream handle = nullptr; MidiDeviceSetting* devp = MidiDevices.CheckKey(musicname); - // Strip off any leading file:// component. - if (strncmp(musicname, "file://", 7) == 0) - { - musicname += 7; - } + // Strip off any leading file:// component. + if (strncmp(musicname, "file://", 7) == 0) + { + musicname += 7; + } // opening the music must be done by the game because it's different depending on the game's file system use. FileReader reader = mus_cb.OpenMusic(musicname); - if (!reader.isOpen()) return false; + if (!reader.isOpen()) return false; - // shutdown old music + // shutdown old music S_StopMusic(true); - // Just record it if volume is 0 or music was disabled + // Just record it if volume is 0 or music was disabled if (snd_musicvolume <= 0 || !mus_enabled) - { - mus_playing.loop = looping; - mus_playing.name = musicname; - mus_playing.baseorder = order; - mus_playing.LastSong = musicname; - return true; - } + { + mus_playing.loop = looping; + mus_playing.name = musicname; + mus_playing.baseorder = order; + mus_playing.LastSong = musicname; + return true; + } - // load & register it - if (handle != nullptr) - { - mus_playing.handle = handle; - } - else - { - auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. + // load & register it + if (handle != nullptr) + { + mus_playing.handle = handle; + } + else + { + auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. mus_playing.handle = ZMusic_OpenSong(mreader, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); - if (mus_playing.handle == nullptr) - { - Printf("Unable to load %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError()); - } + if (mus_playing.handle == nullptr) + { + Printf("Unable to load %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError()); } + } mus_playing.loop = looping; mus_playing.name = musicname; @@ -574,19 +573,19 @@ UNSAFE_CCMD (playlist) { Printf("Could not open " TEXTCOLOR_BOLD "%s" TEXTCOLOR_NORMAL ": %s\n", argv[1], strerror(errno)); return; - } + } if (PlayList.GetNumSongs () > 0) - { - if (argc == 3) { + if (argc == 3) + { if (stricmp (argv[2], "shuffle") == 0) { PlayList.Shuffle (); - } + } else - { + { PlayList.SetPosition (atoi (argv[2])); - } + } } S_ActivatePlayList (false); } @@ -645,7 +644,7 @@ CCMD (playlistprev) { PlayList.Backup (); S_ActivatePlayList (true); - } + } } //========================================================================== diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index b1c55b308..5ecb6ee48 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -183,7 +183,6 @@ struct FSoundChan : public FISoundChannel // CHAN_VOICE is for oof, sight, or other voice sounds // CHAN_ITEM is for small things and item pickup // CHAN_BODY is for generic body sounds -// Channels below 0 are reserved for CHAN_AUTO. enum EChannel { diff --git a/source/common/console/c_bind.cpp b/source/common/console/c_bind.cpp index 609f2bf86..7dcabf96c 100644 --- a/source/common/console/c_bind.cpp +++ b/source/common/console/c_bind.cpp @@ -59,11 +59,11 @@ const char *KeyNames[NUM_KEYS] = nullptr, "Escape", "1", "2", "3", "4", "5", "6", //00 "7", "8", "9", "0", "-", "=", "Backspace","Tab", //08 "Q", "W", "E", "R", "T", "Y", "U", "I", //10 - "O", "P", "[", "]", "Enter", "LCtrl", "A", "S", //18 + "O", "P", "[", "]", "Enter", "Ctrl", "A", "S", //18 "D", "F", "G", "H", "J", "K", "L", ";", //20 - "'", "`", "LShift", "\\", "Z", "X", "C", "V", //28 + "'", "`", "Shift", "\\", "Z", "X", "C", "V", //28 "B", "N", "M", ",", ".", "/", "RShift", "KP*", //30 - "LAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", //38 + "Alt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", //38 "F6", "F7", "F8", "F9", "F10", "NumLock", "Scroll", "KP7", //40 "KP8", "KP9", "KP-", "KP4", "KP5", "KP6", "KP+", "KP1", //48 "KP2", "KP3", "KP0", "KP.", nullptr, nullptr, "OEM102", "F11", //50 @@ -717,13 +717,25 @@ void C_SetDefaultKeys(const char* baseconfig) while ((lump = fileSystem.FindLumpFullName(baseconfig, &lastlump)) != -1) { if (fileSystem.GetFileContainer(lump) > 0) break; - ReadBindings(lump, true); + // [SW] - We need to check to see the origin of the DEFBINDS... if it + // Comes from an IWAD/IPK3/IPK7 allow it to override the users settings... + // If it comes from a user mod however, don't. + if (fileSystem.GetFileContainer(lump) > fileSystem.GetMaxIwadNum()) + ReadBindings(lump, false); + else + ReadBindings(lump, true); } lastlump = 0; while ((lump = fileSystem.FindLump("DEFBINDS", &lastlump)) != -1) { - ReadBindings(lump, false); + // [SW] - We need to check to see the origin of the DEFBINDS... if it + // Comes from an IWAD/IPK3/IPK7 allow it to override the users settings... + // If it comes from a user mod however, don't. + if (fileSystem.GetFileContainer(lump) > fileSystem.GetMaxIwadNum()) + ReadBindings(lump, false); + else + ReadBindings(lump, true); } } diff --git a/source/common/engine/cycler.cpp b/source/common/engine/cycler.cpp new file mode 100644 index 000000000..1d0d28486 --- /dev/null +++ b/source/common/engine/cycler.cpp @@ -0,0 +1,160 @@ +/* +** gl_cycler.cpp +** Implements the cycler for dynamic lights and texture shaders. +** +**--------------------------------------------------------------------------- +** Copyright 2003 Timothy Stump +** Copyright 2006 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 +#include "serializer.h" +#include "cycler.h" + +//========================================================================== +// +// This will never be called with a null-def, so don't bother with that case. +// +//========================================================================== + +FSerializer &Serialize(FSerializer &arc, const char *key, FCycler &c, FCycler *def) +{ + if (arc.BeginObject(key)) + { + arc("start", c.m_start, def->m_start) + ("end", c.m_end, def->m_end) + ("current", c.m_current, def->m_current) + ("time", c.m_time, def->m_time) + ("cycle", c.m_cycle, def->m_cycle) + ("increment", c.m_increment, def->m_increment) + ("shouldcycle", c.m_shouldCycle, def->m_shouldCycle) + .Enum("type", c.m_cycleType) + .EndObject(); + } + return arc; +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FCycler::SetParams(double start, double end, double cycle, bool update) +{ + if (!update || cycle != m_cycle) + { + m_cycle = cycle; + m_time = 0.; + m_increment = true; + m_current = start; + } + else + { + // When updating and keeping the same cycle, scale the current light size to the new dimensions. + double fact = (m_current - m_start) / (m_end - m_start); + m_current = start + fact *(end - start); + } + m_start = start; + m_end = end; +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FCycler::Update(double diff) +{ + double mult, angle; + double step = m_end - m_start; + + if (!m_shouldCycle) + { + return; + } + + m_time += diff; + if (m_time >= m_cycle) + { + m_time = m_cycle; + } + + mult = m_time / m_cycle; + + switch (m_cycleType) + { + case CYCLE_Linear: + if (m_increment) + { + m_current = m_start + (step * mult); + } + else + { + m_current = m_end - (step * mult); + } + break; + case CYCLE_Sin: + angle = double(M_PI * 2. * mult); + mult = g_sin(angle); + mult = (mult + 1.) / 2.; + m_current = m_start + (step * mult); + break; + case CYCLE_Cos: + angle = double(M_PI * 2. * mult); + mult = g_cos(angle); + mult = (mult + 1.) / 2.; + m_current = m_start + (step * mult); + break; + case CYCLE_SawTooth: + m_current = m_start + (step * mult); + break; + case CYCLE_Square: + if (m_increment) + { + m_current = m_start; + } + else + { + m_current = m_end; + } + break; + } + + if (m_time == m_cycle) + { + m_time = 0.; + m_increment = !m_increment; + } +} + + diff --git a/source/common/engine/cycler.h b/source/common/engine/cycler.h new file mode 100644 index 000000000..0b49e644d --- /dev/null +++ b/source/common/engine/cycler.h @@ -0,0 +1,43 @@ +#ifndef __GL_CYCLER_H +#define __GL_CYCLER_H + +class FSerializer; + +enum CycleType +{ + CYCLE_Linear, + CYCLE_Sin, + CYCLE_Cos, + CYCLE_SawTooth, + CYCLE_Square +}; + +class FCycler; +FSerializer &Serialize(FSerializer &arc, const char *key, FCycler &c, FCycler *def); + +class FCycler +{ + friend FSerializer &Serialize(FSerializer &arc, const char *key, FCycler &c, FCycler *def); + +public: + FCycler() = default; + FCycler(const FCycler &other) = default; + FCycler &operator=(const FCycler &other) = default; + + void Update(double diff); + void SetParams(double start, double end, double cycle, bool update = false); + void ShouldCycle(bool sc) { m_shouldCycle = sc; } + void SetCycleType(CycleType ct) { m_cycleType = ct; } + double GetVal() { return m_current; } + + inline operator double () const { return m_current; } + + double m_start, m_end, m_current; + double m_time, m_cycle; + bool m_increment, m_shouldCycle; + + CycleType m_cycleType; +}; + + +#endif diff --git a/source/common/engine/i_interface.h b/source/common/engine/i_interface.h index d992203d9..5bd03dd0b 100644 --- a/source/common/engine/i_interface.h +++ b/source/common/engine/i_interface.h @@ -1,6 +1,7 @@ #pragma once #include "zstring.h" +#include "intrect.h" struct SystemCallbacks { @@ -11,7 +12,11 @@ struct SystemCallbacks bool (*CaptureModeInGame)(); void (*CrashInfo)(char* buffer, size_t bufflen, const char* lfstr); void (*PlayStartupSound)(const char* name); - + bool (*IsSpecialUI)(); + bool (*DisableTextureFilter)(); + void (*OnScreenSizeChanged)(); + IntRect(*GetSceneRect)(); + FString(*GetLocationDescription)(); }; extern SystemCallbacks *sysCallbacks; diff --git a/source/common/engine/namedef.h b/source/common/engine/namedef.h index 5cafc87ce..7d7cff000 100644 --- a/source/common/engine/namedef.h +++ b/source/common/engine/namedef.h @@ -462,6 +462,7 @@ xx(Friend) xx(Strifeally) xx(Standing) xx(Countsecret) +xx(NoCount) xx(Score) xx(Roll) xx(Scale) diff --git a/source/common/engine/palettecontainer.h b/source/common/engine/palettecontainer.h index c8c5499d3..f858eefb0 100644 --- a/source/common/engine/palettecontainer.h +++ b/source/common/engine/palettecontainer.h @@ -34,6 +34,7 @@ struct FRemapTable int Index; int NumEntries; // # of elements in this table (usually 256) bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL + bool TwodOnly = false; // Only used for 2D rendering bool ForFont = false; // Mark font translations because they may require different handling than the ones for sprites- private: diff --git a/source/common/engine/serializer.cpp b/source/common/engine/serializer.cpp index c2ea80a47..f0d31a13d 100644 --- a/source/common/engine/serializer.cpp +++ b/source/common/engine/serializer.cpp @@ -1062,7 +1062,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, float &value, float *d FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTextureID *defval) { -#if 0 if (arc.isWriting()) { if (!arc.w->inObject() || defval == nullptr || value != *defval) @@ -1140,7 +1139,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe } } } -#endif return arc; } diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 4d221431b..3f64b1625 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -89,6 +89,7 @@ FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * Intermission FFont *FFont::FirstFont = nullptr; int NumTextColors; +static bool translationsLoaded; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -138,7 +139,9 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) head == MAKE_ID(0xE1,0xE6,0xD5,0x1A)) { FFont *CreateSingleLumpFont (const char *fontname, int lump); - return CreateSingleLumpFont (name, lump); + font = CreateSingleLumpFont (name, lump); + if (translationsLoaded) font->LoadTranslations(); + return font; } } FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any); @@ -148,12 +151,15 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) if (tex && tex->GetSourceLump() >= folderfile) { FFont *CreateSinglePicFont(const char *name); - return CreateSinglePicFont (name); + font = CreateSinglePicFont (name); + return font; } } if (folderdata.Size() > 0) { - return new FFont(name, nullptr, name, HU_FONTSTART, HU_FONTSIZE, 1, -1); + font = new FFont(name, nullptr, name, HU_FONTSTART, HU_FONTSIZE, 1, -1); + if (translationsLoaded) font->LoadTranslations(); + return font; } } return font; @@ -728,13 +734,6 @@ void V_InitFonts() OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true); } - if (SmallFont) - { - uint32_t colors[256] = {}; - SmallFont->RecordAllTextureColors(colors); - if (OriginalSmallFont != nullptr) OriginalSmallFont->SetDefaultTranslation(colors); - NewSmallFont->SetDefaultTranslation(colors); - } if (!(SmallFont2 = V_GetFont("SmallFont2"))) // Only used by Strife { @@ -770,13 +769,6 @@ void V_InitFonts() OriginalBigFont = new FFont("OriginalBigFont", nullptr, "bigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true); } - if (BigFont) - { - uint32_t colors[256] = {}; - BigFont->RecordAllTextureColors(colors); - if (OriginalBigFont != nullptr) OriginalBigFont->SetDefaultTranslation(colors); - } - // let PWAD BIGFONTs override the stock BIGUPPER font. (This check needs to be made smarter.) if (BigUpper && BigFont->Type != FFont::Folder && BigUpper->Type == FFont::Folder) { @@ -833,7 +825,22 @@ void V_LoadTranslations() for (auto font = FFont::FirstFont; font; font = font->Next) { if (!font->noTranslate) font->LoadTranslations(); + else font->ActiveColors = 0; } + if (BigFont) + { + uint32_t colors[256] = {}; + BigFont->RecordAllTextureColors(colors); + if (OriginalBigFont != nullptr) OriginalBigFont->SetDefaultTranslation(colors); + } + if (SmallFont) + { + uint32_t colors[256] = {}; + SmallFont->RecordAllTextureColors(colors); + if (OriginalSmallFont != nullptr) OriginalSmallFont->SetDefaultTranslation(colors); + NewSmallFont->SetDefaultTranslation(colors); + } + translationsLoaded = true; } void V_ClearFonts() diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 2fff85888..6de1dae86 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -38,7 +38,6 @@ #include "palentry.h" #include "name.h" -class DCanvas; class FGameTexture; struct FRemapTable; @@ -156,7 +155,7 @@ protected: int TranslationType = 0; int Displacement = 0; char Cursor; - bool noTranslate; + bool noTranslate = false; bool translateUntranslated; bool MixedCase = false; bool forceremap = false; @@ -167,7 +166,7 @@ protected: int XMove = INT_MIN; }; TArray Chars; - int ActiveColors; + int ActiveColors = -1; TArray Translations; uint8_t PatchRemap[256]; diff --git a/source/common/objects/dobject.h b/source/common/objects/dobject.h index 3c98d144b..98d9106a2 100644 --- a/source/common/objects/dobject.h +++ b/source/common/objects/dobject.h @@ -110,7 +110,7 @@ enum EInPlace { EC_InPlace }; #define DECLARE_ABSTRACT_CLASS(cls,parent) \ public: \ - virtual PClass *StaticType() const; \ + PClass *StaticType() const override; \ static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \ typedef parent Super; \ private: \ diff --git a/source/common/platform/posix/cocoa/i_input.mm b/source/common/platform/posix/cocoa/i_input.mm index 8b81f86ad..dad875fba 100644 --- a/source/common/platform/posix/cocoa/i_input.mm +++ b/source/common/platform/posix/cocoa/i_input.mm @@ -46,6 +46,7 @@ #include "i_interface.h" #include "menustate.h" #include "engineerrors.h" +#include "keydef.h" EXTERN_CVAR(Int, m_use_mouse) diff --git a/source/common/platform/posix/cocoa/i_system.mm b/source/common/platform/posix/cocoa/i_system.mm index 627c82901..76a38cbcf 100644 --- a/source/common/platform/posix/cocoa/i_system.mm +++ b/source/common/platform/posix/cocoa/i_system.mm @@ -53,7 +53,7 @@ void CalculateCPUSpeed() PerfToSec = 1.0 / frequency; PerfToMillisec = 1000.0 / frequency; - //if (!batchrun) + if (!batchrun) { Printf("CPU speed: %.0f MHz\n", 0.001 / PerfToMillisec); } diff --git a/source/common/platform/posix/cocoa/i_video.mm b/source/common/platform/posix/cocoa/i_video.mm index 666f3235d..a7465cfab 100644 --- a/source/common/platform/posix/cocoa/i_video.mm +++ b/source/common/platform/posix/cocoa/i_video.mm @@ -53,12 +53,12 @@ #include "version.h" #include "printf.h" -#include "gl/system/gl_framebuffer.h" +#include "gl_framebuffer.h" #ifdef HAVE_VULKAN #include "vulkan/system/vk_framebuffer.h" #endif #ifdef HAVE_SOFTPOLY -#include "rendering/polyrenderer/backend/poly_framebuffer.h" +#include "poly_framebuffer.h" #endif extern bool ToggleFullscreen; @@ -807,7 +807,7 @@ CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI // --------------------------------------------------------------------------- -bool I_SetCursor(FTexture *cursorpic) +bool I_SetCursor(FGameTexture *cursorpic) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSCursor* cursor = nil; diff --git a/source/common/platform/posix/i_system_posix.cpp b/source/common/platform/posix/i_system_posix.cpp index cef139be4..aa8bea6d2 100644 --- a/source/common/platform/posix/i_system_posix.cpp +++ b/source/common/platform/posix/i_system_posix.cpp @@ -1,24 +1,33 @@ -//----------------------------------------------------------------------------- -// -// Copyright 1993-1996 id Software -// Copyright 1999-2016 Randy Heit -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//----------------------------------------------------------------------------- -// - +/* +**--------------------------------------------------------------------------- +** Copyright 2016 Randy Heit +** 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 #ifdef __APPLE__ @@ -26,7 +35,6 @@ #endif // __APPLE__ #include "cmdlib.h" -#include "d_protocol.h" #include "i_system.h" #include "gameconfigfile.h" #include "x86.h" diff --git a/source/common/platform/posix/sdl/i_main.cpp b/source/common/platform/posix/sdl/i_main.cpp index fe52d53af..7fc179a51 100644 --- a/source/common/platform/posix/sdl/i_main.cpp +++ b/source/common/platform/posix/sdl/i_main.cpp @@ -53,7 +53,6 @@ // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- -bool batchrun; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- diff --git a/source/common/platform/posix/sdl/sdlglvideo.cpp b/source/common/platform/posix/sdl/sdlglvideo.cpp index 66edd075e..857abe981 100644 --- a/source/common/platform/posix/sdl/sdlglvideo.cpp +++ b/source/common/platform/posix/sdl/sdlglvideo.cpp @@ -34,6 +34,7 @@ // HEADER FILES ------------------------------------------------------------ #include "i_module.h" +#include "i_soundinternal.h" #include "i_system.h" #include "i_video.h" #include "m_argv.h" @@ -47,15 +48,15 @@ #include "gl_sysfb.h" #include "gl_system.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/system/gl_framebuffer.h" +#include "gl_renderer.h" +#include "gl_framebuffer.h" #ifdef HAVE_VULKAN -#include "rendering/vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_framebuffer.h" #endif #ifdef HAVE_SOFTPOLY -#include "rendering/polyrenderer/backend/poly_framebuffer.h" +#include "poly_framebuffer.h" #endif // MACROS ------------------------------------------------------------------ diff --git a/source/common/platform/win32/win32basevideo.cpp b/source/common/platform/win32/win32basevideo.cpp index bb1fb81ba..fe2ba3b9a 100644 --- a/source/common/platform/win32/win32basevideo.cpp +++ b/source/common/platform/win32/win32basevideo.cpp @@ -52,7 +52,7 @@ #include "win32basevideo.h" #include "cmdlib.h" -#include "gl/system/gl_framebuffer.h" +#include "gl_framebuffer.h" CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) diff --git a/source/common/platform/win32/win32glvideo.cpp b/source/common/platform/win32/win32glvideo.cpp index 80dadfd0e..034ec8691 100644 --- a/source/common/platform/win32/win32glvideo.cpp +++ b/source/common/platform/win32/win32glvideo.cpp @@ -53,7 +53,7 @@ #include "engineerrors.h" #include "win32glvideo.h" -#include "gl/system/gl_framebuffer.h" +#include "gl_framebuffer.h" EXTERN_CVAR(Int, vid_adapter) EXTERN_CVAR(Bool, vid_hdr) diff --git a/source/common/platform/win32/win32polyvideo.h b/source/common/platform/win32/win32polyvideo.h index 6d1648d0c..3a1c36242 100644 --- a/source/common/platform/win32/win32polyvideo.h +++ b/source/common/platform/win32/win32polyvideo.h @@ -2,7 +2,7 @@ #include "win32basevideo.h" #include "c_cvars.h" -#include "rendering/polyrenderer/backend/poly_framebuffer.h" +#include "poly_framebuffer.h" EXTERN_CVAR(Bool, vid_fullscreen) diff --git a/source/common/platform/win32/win32vulkanvideo.h b/source/common/platform/win32/win32vulkanvideo.h index c34c41d72..2654597c7 100644 --- a/source/common/platform/win32/win32vulkanvideo.h +++ b/source/common/platform/win32/win32vulkanvideo.h @@ -2,7 +2,7 @@ #include "win32basevideo.h" #include "c_cvars.h" -#include "rendering/vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_framebuffer.h" EXTERN_CVAR(Bool, vid_fullscreen) diff --git a/source/common/scripting/backend/codegen.cpp b/source/common/scripting/backend/codegen.cpp index a225988fa..1c9209c58 100644 --- a/source/common/scripting/backend/codegen.cpp +++ b/source/common/scripting/backend/codegen.cpp @@ -18,10 +18,6 @@ ** 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. -** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be -** covered by the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or (at -** your option) any later version. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -48,7 +44,6 @@ #include "m_random.h" #include "v_font.h" #include "templates.h" -#include "palutil.h" extern FRandom pr_exrandom; FMemArena FxAlloc(65536); @@ -2918,7 +2913,6 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build) texcheck: // Do a bounds check for the texture index. Note that count can change at run time so this needs to read the value from the texture manager. -#if 0 auto * ptr = (FArray*)&TexMan.Textures; auto * countptr = &ptr->Count; ExpEmit bndp(build, REGT_POINTER); @@ -2928,7 +2922,6 @@ texcheck: build->Emit(OP_BOUND_R, to.RegNum, bndc.RegNum); bndp.Free(build); bndc.Free(build); -#endif return to; } @@ -6365,7 +6358,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx) if (Object->ValueType->isRealPointer()) { auto ptype = Object->ValueType->toPointer()->PointedType; - if (ptype->isContainer()) + if (ptype && ptype->isContainer()) { auto ret = ResolveMember(ctx, ctx.Class, Object, static_cast(ptype)); delete this; diff --git a/source/common/scripting/core/dictionary.cpp b/source/common/scripting/core/dictionary.cpp index 50551c059..753ac66fe 100644 --- a/source/common/scripting/core/dictionary.cpp +++ b/source/common/scripting/core/dictionary.cpp @@ -43,7 +43,7 @@ void Dictionary::Serialize(FSerializer &arc) Dictionary *pointerToDeserializedDictionary; arc(key, pointerToDeserializedDictionary); Map.TransferFrom(pointerToDeserializedDictionary->Map); - delete pointerToDeserializedDictionary; + pointerToDeserializedDictionary->Destroy(); } } @@ -62,7 +62,7 @@ static void DictInsert(Dictionary *dict, const FString &key, const FString &valu static void DictAt(const Dictionary *dict, const FString &key, FString *result) { const FString *value = dict->Map.CheckKey(key); - *result = value ? *value : FString(""); + *result = value ? *value : FString(); } static void DictToString(const Dictionary *dict, FString *result) diff --git a/source/common/scripting/core/dynarrays.cpp b/source/common/scripting/core/dynarrays.cpp index daedd60e6..16bb57ca8 100644 --- a/source/common/scripting/core/dynarrays.cpp +++ b/source/common/scripting/core/dynarrays.cpp @@ -18,10 +18,6 @@ ** 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. -** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be -** covered by the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or (at -** your option) any later version. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES diff --git a/source/common/scripting/core/imports.cpp b/source/common/scripting/core/imports.cpp index 2b4d56756..0c277c964 100644 --- a/source/common/scripting/core/imports.cpp +++ b/source/common/scripting/core/imports.cpp @@ -19,10 +19,6 @@ ** 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. -** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be -** covered by the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or (at -** your option) any later version. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES diff --git a/source/common/scripting/interface/stringformat.cpp b/source/common/scripting/interface/stringformat.cpp index b4d0bc4d8..8e0bf0c75 100644 --- a/source/common/scripting/interface/stringformat.cpp +++ b/source/common/scripting/interface/stringformat.cpp @@ -19,10 +19,6 @@ ** 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. -** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be -** covered by the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or (at -** your option) any later version. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES diff --git a/source/common/textures/formats/multipatchtexture.h b/source/common/textures/formats/multipatchtexture.h index 51f36abf5..5c75fa474 100644 --- a/source/common/textures/formats/multipatchtexture.h +++ b/source/common/textures/formats/multipatchtexture.h @@ -92,7 +92,7 @@ struct TexInit { FString TexName; ETextureType UseType = ETextureType::Null; - FImageTexture *Texture = nullptr; + FGameTexture *GameTexture = nullptr; bool Silent = false; bool HasLine = false; bool UseOffsets = false; diff --git a/source/common/textures/gametexture.cpp b/source/common/textures/gametexture.cpp index 1ec6a6062..3ab74a5c3 100644 --- a/source/common/textures/gametexture.cpp +++ b/source/common/textures/gametexture.cpp @@ -430,7 +430,7 @@ CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) float FTexCoordInfo::RowOffset(float rowoffset) const { - float scale = fabs(mScale.Y); + float scale = fabsf(mScale.Y); if (scale == 1.f || mWorldPanning) return rowoffset; else return rowoffset / scale; } @@ -443,7 +443,7 @@ float FTexCoordInfo::RowOffset(float rowoffset) const float FTexCoordInfo::TextureOffset(float textureoffset) const { - float scale = fabs(mScale.X); + float scale = fabsf(mScale.X); if (scale == 1.f || mWorldPanning) return textureoffset; else return textureoffset / scale; } @@ -458,7 +458,7 @@ float FTexCoordInfo::TextureAdjustWidth() const { if (mWorldPanning) { - float tscale = fabs(mTempScale.X); + float tscale = fabsf(mTempScale.X); if (tscale == 1.f) return (float)mRenderWidth; else return mWidth / fabs(tscale); } diff --git a/source/common/textures/gametexture.h b/source/common/textures/gametexture.h index 1f0c26d9d..38c0908c6 100644 --- a/source/common/textures/gametexture.h +++ b/source/common/textures/gametexture.h @@ -84,7 +84,7 @@ class FGameTexture float DisplayWidth, DisplayHeight; float ScaleX, ScaleY; - int8_t shouldUpscaleFlag = 0; // Without explicit setup, scaling is disabled for a texture. + int8_t shouldUpscaleFlag = 1; ETextureType UseType = ETextureType::Wall; // This texture's primary purpose SpritePositioningInfo* spi = nullptr; @@ -133,7 +133,7 @@ public: ETextureType GetUseType() const { return UseType; } void SetUpscaleFlag(int what) { shouldUpscaleFlag = what; } - int GetUpscaleFlag() { return shouldUpscaleFlag; } + int GetUpscaleFlag() { return shouldUpscaleFlag == 1; } FTexture* GetTexture() { return Base.get(); } int GetSourceLump() const { return Base->GetSourceLump(); } @@ -208,6 +208,7 @@ public: void CopySize(FGameTexture* BaseTexture) { Base->CopySize(BaseTexture->Base.get()); + SetDisplaySize(BaseTexture->GetDisplayWidth(), BaseTexture->GetDisplayHeight()); } // Glowing is a pure material property that should not filter down to the actual texture objects. @@ -235,12 +236,20 @@ public: DisplayHeight = h; ScaleX = TexelWidth / w; ScaleY = TexelHeight / h; + if (shouldUpscaleFlag < 2) + { + shouldUpscaleFlag = ScaleX < 2 && ScaleY < 2; + } // compensate for roundoff errors if (int(ScaleX * w) != TexelWidth) ScaleX += (1 / 65536.); if (int(ScaleY * h) != TexelHeight) ScaleY += (1 / 65536.); } + void SetBase(FTexture* Tex) + { + Base = Tex; + } void SetOffsets(int which, int x, int y) { LeftOffset[which] = x; @@ -253,12 +262,16 @@ public: LeftOffset[1] = x; TopOffset[1] = y; } - void SetScale(float x, float y) + void SetScale(float x, float y) { ScaleX = x; ScaleY = y; - DisplayWidth = x * TexelWidth; - DisplayHeight = y * TexelHeight; + if (shouldUpscaleFlag < 2) + { + shouldUpscaleFlag = ScaleX < 2 && ScaleY < 2; + } + DisplayWidth = TexelWidth / x; + DisplayHeight = TexelHeight / y; } const SpritePositioningInfo& GetSpritePositioning(int which) { if (spi == nullptr) SetupSpriteData(); return spi[which]; } diff --git a/source/common/textures/hires/hqresize.cpp b/source/common/textures/hires/hqresize.cpp index 2e7b2fb06..fe5beda4e 100644 --- a/source/common/textures/hires/hqresize.cpp +++ b/source/common/textures/hires/hqresize.cpp @@ -514,7 +514,7 @@ int calcShouldUpscale(FGameTexture *tex) return 0; // already scaled? - if (tex->GetDisplayWidth() >= 2* tex->GetTexelWidth() || tex->GetDisplayHeight() >= 2*tex->GetTexelHeight()) + if (tex->GetScaleX() >= 2.f || tex->GetScaleY() > 2.f) return 0; return CTF_Upscale; diff --git a/source/common/textures/image.cpp b/source/common/textures/image.cpp index d68db329d..e70c76e39 100644 --- a/source/common/textures/image.cpp +++ b/source/common/textures/image.cpp @@ -175,10 +175,8 @@ int FImageSource::CopyPixels(FBitmap *bmp, int conversion) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry *palette = GPalette.BaseColors; - for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values auto ppix = CreatePalettedPixels(conversion); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); - for(int i=1;i<256;i++) palette[i].a = 0; return 0; } diff --git a/source/common/textures/imagetexture.cpp b/source/common/textures/imagetexture.cpp index 2efc943ae..d222733a7 100644 --- a/source/common/textures/imagetexture.cpp +++ b/source/common/textures/imagetexture.cpp @@ -60,11 +60,11 @@ FImageTexture::FImageTexture(FImageSource *img) noexcept void FImageTexture::SetFromImage() { auto img = mImage; - Width = img->GetWidth(); - Height = img->GetHeight(); + Width = img->GetWidth(); + Height = img->GetHeight(); Masked = img->bMasked; - bTranslucent = img->bTranslucent; + bTranslucent = img->bTranslucent; } //=========================================================================== // @@ -72,10 +72,10 @@ void FImageTexture::SetFromImage() // //=========================================================================== -FBitmap FImageTexture::GetBgraBitmap(const PalEntry* p, int* trans) +FBitmap FImageTexture::GetBgraBitmap(const PalEntry *p, int *trans) { - return mImage->GetCachedBitmap(p, bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal, trans); -} + return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans); +} //=========================================================================== // @@ -85,8 +85,8 @@ FBitmap FImageTexture::GetBgraBitmap(const PalEntry* p, int* trans) TArray FImageTexture::Get8BitPixels(bool alpha) { - return mImage->GetPalettedPixels(alpha ? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); -} + return mImage->GetPalettedPixels(alpha? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); +} //=========================================================================== // diff --git a/source/common/textures/multipatchtexturebuilder.cpp b/source/common/textures/multipatchtexturebuilder.cpp index d95c681dc..7def5cb7a 100644 --- a/source/common/textures/multipatchtexturebuilder.cpp +++ b/source/common/textures/multipatchtexturebuilder.cpp @@ -138,17 +138,18 @@ void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType u { buildinfo.texture = new FGameTexture(nullptr, buildinfo.Name); buildinfo.texture->SetUseType(usetype); + buildinfo.texture->SetSize(buildinfo.Width, buildinfo.Height); + buildinfo.texture->SetOffsets(0, buildinfo.LeftOffset[0], buildinfo.TopOffset[0]); // These are needed for construction of other multipatch textures. + buildinfo.texture->SetOffsets(1, buildinfo.LeftOffset[1], buildinfo.TopOffset[1]); + buildinfo.texture->SetScale((float)buildinfo.Scale.X, (float)buildinfo.Scale.X); + buildinfo.texture->SetWorldPanning(buildinfo.bWorldPanning); + buildinfo.texture->SetNoDecals(buildinfo.bNoDecals); TexMan.AddGameTexture(buildinfo.texture); } void FMultipatchTextureBuilder::AddImageToTexture(FImageTexture *tex, BuildInfo& buildinfo) { - buildinfo.texture->Setup(tex); - buildinfo.texture->SetOffsets(0, buildinfo.LeftOffset[0], buildinfo.TopOffset[0]); - buildinfo.texture->SetOffsets(1, buildinfo.LeftOffset[1], buildinfo.TopOffset[1]); - buildinfo.texture->SetScale((float)buildinfo.Scale.X, (float)buildinfo.Scale.X); - buildinfo.texture->SetWorldPanning(buildinfo.bWorldPanning); - buildinfo.texture->SetNoDecals(buildinfo.bNoDecals); + buildinfo.texture->SetBase(tex); calcShouldUpscale(buildinfo.texture); // calculate this once at insertion } @@ -812,10 +813,10 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) { FGameTexture *tex = TexMan.GetGameTexture(texno); - if (tex != nullptr && tex->isValid() && dynamic_cast(tex->GetTexture())) + if (tex != nullptr && tex->isValid() && (tex->GetTexture() == nullptr || dynamic_cast(tex->GetTexture()))) { - //We cannot set the image source yet. First all textures need to be resolved. - buildinfo.Inits[i].Texture = static_cast(tex->GetTexture()); + //We cannot set the image texture yet. First all textures need to be resolved. + buildinfo.Inits[i].GameTexture = tex; bool iscomplex = !!complex.CheckKey(tex); if (iscomplex) complex.Insert(buildinfo.texture, true); buildinfo.bComplex |= iscomplex; @@ -830,13 +831,15 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) // The patch is bogus. Remove it. if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Invalid patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); else Printf(TEXTCOLOR_YELLOW "Invalid patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); + buildinfo.Inits.Delete(i); + buildinfo.Parts.Delete(i); i--; } } } for (unsigned i = 0; i < buildinfo.Inits.Size(); i++) { - if (buildinfo.Inits[i].Texture == nullptr) + if (buildinfo.Inits[i].GameTexture == nullptr) { buildinfo.Inits.Delete(i); buildinfo.Parts.Delete(i); @@ -876,10 +879,10 @@ void FMultipatchTextureBuilder::ResolveAllPatches() { if (buildinfo.Parts[j].TexImage == nullptr) { - auto image = buildinfo.Inits[j].Texture; - if (image->GetImage() != nullptr) + auto image = buildinfo.Inits[j].GameTexture->GetTexture(); + if (image && image->GetImage() != nullptr) { - buildinfo.Parts[j].TexImage = image; + buildinfo.Parts[j].TexImage = static_cast(image); donesomething = true; } else hasEmpty = true; @@ -901,7 +904,6 @@ void FMultipatchTextureBuilder::ResolveAllPatches() !buildinfo.bComplex) { AddImageToTexture(buildinfo.Parts[0].TexImage, buildinfo); - buildinfo.texture->Setup(buildinfo.Parts[0].TexImage); done = true; } } diff --git a/source/common/textures/skyboxtexture.cpp b/source/common/textures/skyboxtexture.cpp index 486bd1a4d..2ca476a20 100644 --- a/source/common/textures/skyboxtexture.cpp +++ b/source/common/textures/skyboxtexture.cpp @@ -31,7 +31,6 @@ ** */ - #include "filesystem.h" #include "textures.h" #include "skyboxtexture.h" diff --git a/source/common/textures/textureid.h b/source/common/textures/textureid.h index 5d2b7d726..c7a6355cc 100644 --- a/source/common/textures/textureid.h +++ b/source/common/textures/textureid.h @@ -50,6 +50,12 @@ private: int texnum; }; +class FNullTextureID : public FTextureID +{ +public: + FNullTextureID() : FTextureID(0) {} +}; + // This is for the script interface which needs to do casts from int to texture. class FSetTextureID : public FTextureID { diff --git a/source/common/textures/texturemanager.cpp b/source/common/textures/texturemanager.cpp index a94a1592a..c7cffd07c 100644 --- a/source/common/textures/texturemanager.cpp +++ b/source/common/textures/texturemanager.cpp @@ -1541,3 +1541,9 @@ FTextureID FTextureID::operator +(int offset) throw() if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1); return FTextureID(texnum + offset); } + +CCMD(flushtextures) +{ + TexMan.FlushAll(); +} + diff --git a/source/common/textures/texturemanager.h b/source/common/textures/texturemanager.h index fcece60d5..2aa53da24 100644 --- a/source/common/textures/texturemanager.h +++ b/source/common/textures/texturemanager.h @@ -4,13 +4,13 @@ #include "tarray.h" #include "textureid.h" #include "basics.h" -#include "sc_man.h" #include "texmanip.h" #include "name.h" class FxAddSub; struct BuildInfo; class FMultipatchTextureBuilder; +class FScanner; int PalCheck(int tex); // Texture manager diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index 5c8468061..b3e900ef6 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -124,12 +124,6 @@ class FMultipatchTextureBuilder; extern int r_spriteadjustSW, r_spriteadjustHW; -class FNullTextureID : public FTextureID -{ -public: - FNullTextureID() : FTextureID(0) {} -}; - enum FTextureFormat : uint32_t { TEX_Pal, @@ -287,7 +281,6 @@ public: public: FTextureBuffer CreateTexBuffer(int translation, int flags = 0); - virtual bool DetermineTranslucency(); bool GetTranslucency() { @@ -359,7 +352,7 @@ protected: void SetFromImage(); public: FImageTexture(FImageSource* image) noexcept; - virtual TArray Get8BitPixels(bool alphatex); + TArray Get8BitPixels(bool alphatex) override; void SetImage(FImageSource* img) { diff --git a/source/common/textures/v_collection.cpp b/source/common/textures/v_collection.cpp new file mode 100644 index 000000000..2b51885bf --- /dev/null +++ b/source/common/textures/v_collection.cpp @@ -0,0 +1,82 @@ +/* +** v_collection.cpp +** Holds a collection of images +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** 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 "v_collection.h" +#include "v_font.h" +#include "v_video.h" +#include "filesystem.h" +#include "texturemanager.h" + +FImageCollection::FImageCollection () +{ +} + +FImageCollection::FImageCollection (const char **patchNames, int numPatches) +{ + Add (patchNames, numPatches); +} + +void FImageCollection::Init (const char **patchNames, int numPatches, ETextureType namespc) +{ + ImageMap.Clear(); + Add(patchNames, numPatches, namespc); +} + +// [MH] Mainly for mugshots with skins and SBARINFO +void FImageCollection::Add (const char **patchNames, int numPatches, ETextureType namespc) +{ + int OldCount = ImageMap.Size(); + + ImageMap.Resize(OldCount + numPatches); + + for (int i = 0; i < numPatches; ++i) + { + FTextureID picnum = TexMan.CheckForTexture(patchNames[i], namespc); + ImageMap[OldCount + i] = picnum; + } +} + +void FImageCollection::Uninit () +{ + ImageMap.Clear(); +} + +FGameTexture *FImageCollection::operator[] (int index) const +{ + if ((unsigned int)index >= ImageMap.Size()) + { + return NULL; + } + return ImageMap[index].Exists()? TexMan.GetGameTexture(ImageMap[index], true) : NULL; +} diff --git a/source/common/textures/v_collection.h b/source/common/textures/v_collection.h new file mode 100644 index 000000000..8574e5802 --- /dev/null +++ b/source/common/textures/v_collection.h @@ -0,0 +1,58 @@ +/* +** v_collection.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** 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. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __V_COLLECTION_H__ +#define __V_COLLECTION_H__ + +#include "tarray.h" +#include "textureid.h" + +class FGameTexture; + +class FImageCollection +{ +public: + FImageCollection(); + FImageCollection(const char **patchNames, int numPatches); + + void Init(const char **patchnames, int numPatches, ETextureType namespc = ETextureType::Any); + void Add(const char **patchnames, int numPatches, ETextureType namespc = ETextureType::Any); + void Uninit(); + + FGameTexture *operator[] (int index) const; + +protected: + TArray ImageMap; +}; + +#endif //__V_COLLECTION_H__ diff --git a/source/common/utility/basics.h b/source/common/utility/basics.h index 503d3ea7b..615789b58 100644 --- a/source/common/utility/basics.h +++ b/source/common/utility/basics.h @@ -3,6 +3,9 @@ #include #include +#define MAXWIDTH 12000 +#define MAXHEIGHT 5000 + // // fixed point, 32bit as 16.16. // diff --git a/source/common/utility/cmdlib.cpp b/source/common/utility/cmdlib.cpp index c25ade8b9..dac58292a 100644 --- a/source/common/utility/cmdlib.cpp +++ b/source/common/utility/cmdlib.cpp @@ -39,15 +39,15 @@ #include "files.h" #include "md5.h" +#include +#include +#include + #ifndef _WIN32 #include #include #endif -#include -#include -#include - /* progdir will hold the path up to the game directory, including the slash diff --git a/source/common/utility/findfile.cpp b/source/common/utility/findfile.cpp index 2ab573399..332f0db88 100644 --- a/source/common/utility/findfile.cpp +++ b/source/common/utility/findfile.cpp @@ -43,6 +43,8 @@ #include #include +#include "cmdlib.h" + static const char *pattern; static int matchfile(const struct dirent *ent) diff --git a/source/common/utility/findfile.h b/source/common/utility/findfile.h index b08f44618..895bbde69 100644 --- a/source/common/utility/findfile.h +++ b/source/common/utility/findfile.h @@ -10,6 +10,7 @@ enum }; #ifndef _WIN32 + #include struct findstate_t diff --git a/source/common/utility/intrect.h b/source/common/utility/intrect.h new file mode 100644 index 000000000..3cda7613e --- /dev/null +++ b/source/common/utility/intrect.h @@ -0,0 +1,31 @@ +#pragma once + + +struct IntRect +{ + int left, top; + int width, height; + + + void Offset(int xofs, int yofs) + { + left += xofs; + top += yofs; + } + + void AddToRect(int x, int y) + { + if (x < left) + left = x; + if (x > left + width) + width = x - left; + + if (y < top) + top = y; + if (y > top + height) + height = y - top; + } + + +}; + diff --git a/source/common/utility/m_bbox.h b/source/common/utility/m_bbox.h new file mode 100644 index 000000000..f117c290b --- /dev/null +++ b/source/common/utility/m_bbox.h @@ -0,0 +1,87 @@ + +#ifndef __M_BBOX_H__ +#define __M_BBOX_H__ + +#include +#include "vectors.h" + +enum +{ + BOXTOP, + BOXBOTTOM, + BOXLEFT, + BOXRIGHT +}; // bbox coordinates + + +class FBoundingBox +{ +public: + FBoundingBox() + { + ClearBox(); + } + + FBoundingBox(double left, double bottom, double right, double top) + { + m_Box[BOXTOP] = top; + m_Box[BOXLEFT] = left; + m_Box[BOXRIGHT] = right; + m_Box[BOXBOTTOM] = bottom; + } + + FBoundingBox(double x, double y, double radius) + { + setBox(x, y, radius); + } + + + void setBox(double x, double y, double radius) + { + m_Box[BOXTOP] = y + radius; + m_Box[BOXLEFT] = x - radius; + m_Box[BOXRIGHT] = x + radius; + m_Box[BOXBOTTOM] = y - radius; + } + + void ClearBox () + { + m_Box[BOXTOP] = m_Box[BOXRIGHT] = -FLT_MAX; + m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX; + } + + // Returns a bounding box that encloses both bounding boxes + FBoundingBox operator | (const FBoundingBox &box2) const + { + return FBoundingBox(m_Box[BOXLEFT] < box2.m_Box[BOXLEFT] ? m_Box[BOXLEFT] : box2.m_Box[BOXLEFT], + m_Box[BOXBOTTOM] < box2.m_Box[BOXBOTTOM] ? m_Box[BOXBOTTOM] : box2.m_Box[BOXBOTTOM], + m_Box[BOXRIGHT] > box2.m_Box[BOXRIGHT] ? m_Box[BOXRIGHT] : box2.m_Box[BOXRIGHT], + m_Box[BOXTOP] > box2.m_Box[BOXTOP] ? m_Box[BOXTOP] : box2.m_Box[BOXTOP]); + } + + void AddToBox(const DVector2 &pos) + { + if (pos.X < m_Box[BOXLEFT]) + m_Box[BOXLEFT] = pos.X; + if (pos.X > m_Box[BOXRIGHT]) + m_Box[BOXRIGHT] = pos.X; + + if (pos.Y < m_Box[BOXBOTTOM]) + m_Box[BOXBOTTOM] = pos.Y; + if (pos.Y > m_Box[BOXTOP]) + m_Box[BOXTOP] = pos.Y; + } + + inline double Top () const { return m_Box[BOXTOP]; } + inline double Bottom () const { return m_Box[BOXBOTTOM]; } + inline double Left () const { return m_Box[BOXLEFT]; } + inline double Right () const { return m_Box[BOXRIGHT]; } + + void Set(int index, double value) {m_Box[index] = value;} + +protected: + double m_Box[4]; +}; + + +#endif //__M_BBOX_H__ diff --git a/source/common/utility/r_memory.cpp b/source/common/utility/r_memory.cpp new file mode 100644 index 000000000..99a75d0f7 --- /dev/null +++ b/source/common/utility/r_memory.cpp @@ -0,0 +1,101 @@ +/* +** Render memory allocation +** Copyright (c) 2016-2020 Magnus Norddahl +** +** This software is provided 'as-is', without any express or implied +** warranty. In no event will the authors be held liable for any damages +** arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, +** including commercial applications, and to alter it and redistribute it +** freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not +** claim that you wrote the original software. If you use this software +** in a product, an acknowledgment in the product documentation would be +** appreciated but is not required. +** 2. Altered source versions must be plainly marked as such, and must not be +** misrepresented as being the original software. +** 3. This notice may not be removed or altered from any source distribution. +** +*/ + +#include +#include "templates.h" +#include "r_memory.h" +#include + +void *RenderMemory::AllocBytes(int size) +{ + size = (size + 15) / 16 * 16; // 16-byte align + + if (UsedBlocks.empty() || UsedBlocks.back()->Position + size > BlockSize) + { + if (!FreeBlocks.empty()) + { + auto block = std::move(FreeBlocks.back()); + block->Position = 0; + FreeBlocks.pop_back(); + UsedBlocks.push_back(std::move(block)); + } + else + { + UsedBlocks.push_back(std::unique_ptr(new MemoryBlock())); + } + } + + auto &block = UsedBlocks.back(); + void *data = block->Data + block->Position; + block->Position += size; + + return data; +} + +void RenderMemory::Clear() +{ + while (!UsedBlocks.empty()) + { + auto block = std::move(UsedBlocks.back()); + UsedBlocks.pop_back(); + FreeBlocks.push_back(std::move(block)); + } +} + +static void* Aligned_Alloc(size_t alignment, size_t size) +{ + void* ptr; +#if defined (_MSC_VER) || defined (__MINGW32__) + ptr = _aligned_malloc(size, alignment); + if (!ptr) + throw std::bad_alloc(); +#else + // posix_memalign required alignment to be a min of sizeof(void *) + if (alignment < sizeof(void*)) + alignment = sizeof(void*); + + if (posix_memalign((void**)&ptr, alignment, size)) + throw std::bad_alloc(); +#endif + return ptr; +} + +static void Aligned_Free(void* ptr) +{ + if (ptr) + { +#if defined _MSC_VER + _aligned_free(ptr); +#else + free(ptr); +#endif + } +} + +RenderMemory::MemoryBlock::MemoryBlock() : Data(static_cast(Aligned_Alloc(16, BlockSize))), Position(0) +{ +} + +RenderMemory::MemoryBlock::~MemoryBlock() +{ + Aligned_Free(Data); +} diff --git a/source/common/utility/r_memory.h b/source/common/utility/r_memory.h new file mode 100644 index 000000000..8007b6cc1 --- /dev/null +++ b/source/common/utility/r_memory.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +// Memory needed for the duration of a frame rendering +class RenderMemory +{ +public: + void Clear(); + + template + T *AllocMemory(int size = 1) + { + return (T*)AllocBytes(sizeof(T) * size); + } + + template + T *NewObject(Types &&... args) + { + void *ptr = AllocBytes(sizeof(T)); + return new (ptr)T(std::forward(args)...); + } + +private: + void *AllocBytes(int size); + + enum { BlockSize = 1024 * 1024 }; + + struct MemoryBlock + { + MemoryBlock(); + ~MemoryBlock(); + + MemoryBlock(const MemoryBlock &) = delete; + MemoryBlock &operator=(const MemoryBlock &) = delete; + + uint8_t *Data; + uint32_t Position; + }; + std::vector> UsedBlocks; + std::vector> FreeBlocks; +}; diff --git a/source/common/utility/weightedlist.h b/source/common/utility/weightedlist.h new file mode 100644 index 000000000..cd6a4ba0e --- /dev/null +++ b/source/common/utility/weightedlist.h @@ -0,0 +1,166 @@ +/* +** weightedlist.h +** A weighted list template class +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** 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 +#include + +class FRandom; + +template +class TWeightedList +{ + template + struct Choice + { + Choice(uint16_t w, U v) : Next(NULL), Weight(w), RandomVal(0), Value(v) {} + + Choice *Next; + uint16_t Weight; + uint8_t RandomVal; // 0 (never) - 255 (always) + T Value; + }; + + public: + TWeightedList (FRandom &pr) : Choices (NULL), RandomClass (pr) {} + ~TWeightedList () + { + Choice *choice = Choices; + while (choice != NULL) + { + Choice *next = choice->Next; + delete choice; + choice = next; + } + } + + void AddEntry (T value, uint16_t weight); + T PickEntry () const; + void ReplaceValues (T oldval, T newval); + + private: + Choice *Choices; + FRandom &RandomClass; + + void RecalcRandomVals (); + + TWeightedList &operator= (const TWeightedList &) { return *this; } +}; + +template +void TWeightedList::AddEntry (T value, uint16_t weight) +{ + if (weight == 0) + { // If the weight is 0, don't bother adding it, + // since it will never be chosen. + return; + } + + Choice **insAfter = &Choices, *insBefore = Choices; + Choice *theNewOne; + + while (insBefore != NULL && insBefore->Weight < weight) + { + insAfter = &insBefore->Next; + insBefore = insBefore->Next; + } + theNewOne = new Choice (weight, value); + *insAfter = theNewOne; + theNewOne->Next = insBefore; + RecalcRandomVals (); +} + +template +T TWeightedList::PickEntry () const +{ + uint8_t randomnum = RandomClass(); + Choice *choice = Choices; + + while (choice != NULL && randomnum > choice->RandomVal) + { + choice = choice->Next; + } + return choice != NULL ? choice->Value : NULL; +} + +template +void TWeightedList::RecalcRandomVals () +{ + // Redistribute the RandomVals so that they form the correct + // distribution (as determined by the range of weights). + + int numChoices, weightSums; + Choice *choice; + double randVal, weightDenom; + + if (Choices == NULL) + { // No choices, so nothing to do. + return; + } + + numChoices = 1; + weightSums = 0; + + for (choice = Choices; choice->Next != NULL; choice = choice->Next) + { + ++numChoices; + weightSums += choice->Weight; + } + + weightSums += choice->Weight; + choice->RandomVal = 255; // The last choice is always randomval 255 + + randVal = 0.0; + weightDenom = 1.0 / (double)weightSums; + + for (choice = Choices; choice->Next != NULL; choice = choice->Next) + { + randVal += (double)choice->Weight * weightDenom; + choice->RandomVal = (uint8_t)(randVal * 255.0); + } +} + +// Replace all values that match oldval with newval +template +void TWeightedList::ReplaceValues(T oldval, T newval) +{ + Choice *choice; + + for (choice = Choices; choice != NULL; choice = choice->Next) + { + if (choice->Value == oldval) + { + choice->Value = newval; + } + } +} diff --git a/source/core/rendering/v_video.h b/source/core/rendering/v_video.h index 4d9fbc4fb..60ae4a4a5 100644 --- a/source/core/rendering/v_video.h +++ b/source/core/rendering/v_video.h @@ -41,6 +41,7 @@ #include "renderstyle.h" #include "c_cvars.h" #include "v_2ddrawer.h" +#include "intrect.h" //#include "hwrenderer/dynlights/hw_shadowmap.h" static const int VID_MIN_WIDTH = 640; @@ -79,35 +80,6 @@ enum EHWCaps }; -struct IntRect -{ - int left, top; - int width, height; - - - void Offset(int xofs, int yofs) - { - left += xofs; - top += yofs; - } - - void AddToRect(int x, int y) - { - if (x < left) - left = x; - if (x > left + width) - width = x - left; - - if (y < top) - top = y; - if (y > top + height) - height = y - top; - } - - -}; - - extern int DisplayWidth, DisplayHeight; void V_UpdateModeSize (int width, int height);