From 535102ae6e376f89e1ee7df7508b05dabd7c35f6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 5 May 2015 11:22:58 +0200 Subject: [PATCH 01/17] - fixed: NULLing the flash state in P_BringUpWeapon should be done before setting the main weapon state so that it doesn't cancel any flash state effects that get initiated there. --- src/p_pspr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 6e699a41b0..63f3bc6486 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -207,10 +207,10 @@ void P_BringUpWeapon (player_t *player) player->ReadyWeapon = weapon; player->psprites[ps_weapon].sy = player->cheats & CF_INSTANTWEAPSWITCH ? WEAPONTOP : WEAPONBOTTOM; - P_SetPsprite (player, ps_weapon, newstate); // make sure that the previous weapon's flash state is terminated. // When coming here from a weapon drop it may still be active. P_SetPsprite(player, ps_flash, NULL); + P_SetPsprite (player, ps_weapon, newstate); player->mo->weaponspecial = 0; } From b587c85a819c93ffc7caf89d9d63329af005c720 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 7 May 2015 00:45:36 +0200 Subject: [PATCH 02/17] - fixed: On Windows the cache path could end up with double slashes when no AppData folder could be found. --- src/m_specialpaths.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 086f170f8f..3e12be17d1 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -146,6 +146,7 @@ FString M_GetCachePath(bool create) // Don't use GAME_DIR and such so that ZDoom and its child ports can // share the node cache. path += "/zdoom/cache"; + path.Substitute("//", "/"); // needed because progdir ends with a slash. return path; } From 87ff82dba68ca91364a1b963efd5e66a466d2d9b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 May 2015 23:24:27 +0200 Subject: [PATCH 03/17] - fixed: Trying to remove sector tags for line-less sectors crashed when there were no sector tags at all in a map. --- src/p_tags.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/p_tags.cpp b/src/p_tags.cpp index 851c4ee94d..c08caec8fb 100644 --- a/src/p_tags.cpp +++ b/src/p_tags.cpp @@ -98,13 +98,16 @@ void FTagManager::AddSectorTag(int sector, int tag) void FTagManager::RemoveSectorTags(int sect) { - int start = startForSector[sect]; - if (start >= 0) + if (startForSector.Size() > 0) { - while (allTags[start].target == sect) + int start = startForSector[sect]; + if (start >= 0) { - allTags[start].tag = allTags[start].target = -1; - start++; + while (allTags[start].target == sect) + { + allTags[start].tag = allTags[start].target = -1; + start++; + } } } } From f10416af8a3faf223a3c49f3a08145554cc5c87f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 7 May 2015 23:52:58 -0400 Subject: [PATCH 04/17] - Fixed: Missing WINAPI macro in SHGetFolderPathA (MSDN documentation didn't include it so I didn't. Apparently Microsoft is just incosistent since it's documented in functions like GetLongPathName.) --- src/m_specialpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 3e12be17d1..7a48a2b9cb 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -83,7 +83,7 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create // new to Vista, hence the reason we support both. if (SHGetKnownFolderPath == NULL) { - static TOptWin32Proc + static TOptWin32Proc SHGetFolderPathA("shell32.dll", "SHGetFolderPathA"); // NT4 doesn't even have this function. From 92989a8c77354455d68b8b679bc1154d6182e9f0 Mon Sep 17 00:00:00 2001 From: svdijk Date: Sat, 16 May 2015 12:10:08 +0200 Subject: [PATCH 05/17] CMake: Fix building on 32-bit Linux (Fedora 20). --- dumb/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt index d13f232547..e95c691542 100644 --- a/dumb/CMakeLists.txt +++ b/dumb/CMakeLists.txt @@ -111,6 +111,6 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) CHECK_CXX_COMPILER_FLAG( -msse DUMB_CAN_USE_SSE ) if( DUMB_CAN_USE_SSE ) - set_source_files_properties( src/it/filter.cpp PROPERTIES COMPILE_FLAGS -msse ) + set_source_files_properties( src/helpers/resampler.c PROPERTIES COMPILE_FLAGS -msse ) endif( DUMB_CAN_USE_SSE ) endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) From 1e3230486ec975dfcb823ba3b6c35cfa400dcdfd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 May 2015 21:40:25 +0200 Subject: [PATCH 06/17] - Fixed: FTagManager::Clear did not clear the line ID hashing index. --- src/p_tags.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_tags.h b/src/p_tags.h index 75d397d8d3..c3162d9b56 100644 --- a/src/p_tags.h +++ b/src/p_tags.h @@ -49,6 +49,7 @@ public: startForSector.Clear(); startForLine.Clear(); memset(TagHashFirst, -1, sizeof(TagHashFirst)); + memset(IDHashFirst, -1, sizeof(IDHashFirst)); } bool SectorHasTags(const sector_t *sector) const; From 4d082d93cd561d588fa0e5376123c6e243e67842 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 19 May 2015 17:09:20 -0400 Subject: [PATCH 07/17] - Use SDL_RenderSetLogicalSize to handle animorphic ratios in fullscreen with SDL backend. - Reuse the old window in the SDL backend since in some instances switching windows causes issues (OS X fullscreen for instance (while using the SDL backend of course)). - Clear the SDL render before copying in the framebuffer to remove HOM-like effect. --- src/posix/sdl/sdlvideo.cpp | 77 +++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index c24fd797a7..dbaf182398 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -28,7 +28,7 @@ class SDLFB : public DFrameBuffer { DECLARE_CLASS(SDLFB, DFrameBuffer) public: - SDLFB (int width, int height, bool fullscreen); + SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin); ~SDLFB (); bool Lock (bool buffer); @@ -67,7 +67,6 @@ private: SDL_Texture *Texture; SDL_Surface *Surface; }; - SDL_Rect UpdateRect; bool UsingRenderer; bool NeedPalUpdate; @@ -261,6 +260,8 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree PalEntry flashColor; int flashAmount; + SDL_Window *oldwin = NULL; + if (old != NULL) { // Reuse the old framebuffer if its attributes are the same SDLFB *fb = static_cast (old); @@ -275,6 +276,10 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree } return old; } + + oldwin = fb->Screen; + fb->Screen = NULL; + old->GetFlash (flashColor, flashAmount); old->ObjectFlags |= OF_YesReallyDelete; if (screen == old) screen = NULL; @@ -286,7 +291,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree flashAmount = 0; } - SDLFB *fb = new SDLFB (width, height, fullscreen); + SDLFB *fb = new SDLFB (width, height, fullscreen, oldwin); // If we could not create the framebuffer, try again with slightly // different parameters in this order: @@ -340,7 +345,7 @@ void SDLVideo::SetWindowedScale (float scale) // FrameBuffer implementation ----------------------------------------------- -SDLFB::SDLFB (int width, int height, bool fullscreen) +SDLFB::SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin) : DFrameBuffer (width, height) { int i; @@ -351,15 +356,27 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) NotPaletted = false; FlashAmount = 0; - FString caption; - caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + if (oldwin) + { + // In some cases (Mac OS X fullscreen) SDL2 doesn't like having multiple windows which + // appears to inevitably happen while compositor animations are running. So lets try + // to reuse the existing window. + Screen = oldwin; + SDL_SetWindowSize (Screen, width, height); + SetFullscreen (fullscreen); + } + else + { + FString caption; + caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - Screen = SDL_CreateWindow (caption, - SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), - width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + Screen = SDL_CreateWindow (caption, + SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)|SDL_WINDOW_RESIZABLE); - if (Screen == NULL) - return; + if (Screen == NULL) + return; + } Renderer = NULL; Texture = NULL; @@ -381,15 +398,15 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) SDLFB::~SDLFB () { + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + if(Screen) { - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - SDL_DestroyWindow (Screen); } } @@ -498,7 +515,8 @@ void SDLFB::Update () SDL_UnlockTexture (Texture); SDLFlipCycles.Clock(); - SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); + SDL_RenderClear(Renderer); + SDL_RenderCopy(Renderer, Texture, NULL, NULL); SDL_RenderPresent(Renderer); SDLFlipCycles.Unclock(); } @@ -613,6 +631,9 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256]) void SDLFB::SetFullscreen (bool fullscreen) { + if (IsFullscreen() == fullscreen) + return; + SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); if (!fullscreen) { @@ -645,6 +666,8 @@ void SDLFB::ResetSDLRenderer () if (!Renderer) return; + SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255); + Uint32 fmt; switch(vid_displaybits) { @@ -681,24 +704,18 @@ void SDLFB::ResetSDLRenderer () NotPaletted = false; } - // Calculate update rectangle + // In fullscreen, set logical size according to animorphic ratio. + // Windowed modes are always rendered 1:1. if (IsFullscreen ()) { int w, h; SDL_GetWindowSize (Screen, &w, &h); - UpdateRect.w = w; - UpdateRect.h = h; - ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); - UpdateRect.x = (w - UpdateRect.w)/2; - UpdateRect.y = (h - UpdateRect.h)/2; + ScaleWithAspect (w, h, Width, Height); + SDL_RenderSetLogicalSize (Renderer, w, h); } else { - // In windowed mode we just update the whole window. - UpdateRect.x = 0; - UpdateRect.y = 0; - UpdateRect.w = Width; - UpdateRect.h = Height; + SDL_RenderSetLogicalSize (Renderer, Width, Height); } } From 354ec022b313af7c6c5266e1d70eebabf7dcf4af Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 20 May 2015 12:32:17 -0400 Subject: [PATCH 08/17] - On Windows resizing a window just renders the image to the size of the window, so lets do the same for SDL (makes mouse coordinate scaling easier). --- src/posix/sdl/sdlvideo.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index dbaf182398..76191e1a92 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -705,7 +705,7 @@ void SDLFB::ResetSDLRenderer () } // In fullscreen, set logical size according to animorphic ratio. - // Windowed modes are always rendered 1:1. + // Windowed modes are rendered to fill the window (usually 1:1) if (IsFullscreen ()) { int w, h; @@ -713,10 +713,6 @@ void SDLFB::ResetSDLRenderer () ScaleWithAspect (w, h, Width, Height); SDL_RenderSetLogicalSize (Renderer, w, h); } - else - { - SDL_RenderSetLogicalSize (Renderer, Width, Height); - } } void SDLFB::SetVSync (bool vsync) @@ -743,13 +739,14 @@ void SDLFB::SetVSync (bool vsync) void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) { + int w, h; + SDL_GetWindowSize (Screen, &w, &h); + // Detect if we're doing scaling in the Window and adjust the mouse // coordinates accordingly. This could be more efficent, but I // don't think performance is an issue in the menus. if(IsFullscreen()) { - int w, h; - SDL_GetWindowSize (Screen, &w, &h); int realw = w, realh = h; ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); if (realw != SCREENWIDTH || realh != SCREENHEIGHT) @@ -768,6 +765,11 @@ void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) } } } + else + { + x = (SWORD)(x*Width/w); + y = (SWORD)(y*Height/h); + } } ADD_STAT (blit) From e46b25f6283a0da0fcfa02187f657bf4c89d8a93 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 20 May 2015 12:54:13 -0400 Subject: [PATCH 09/17] - Fixed: god2 didn't trigger invulnerability in SBarInfo. --- src/g_shared/sbarinfo_commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index bb1b048502..db5d9fc05c 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -525,7 +525,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage } else if(condition == INVULNERABILITY) { - if(statusBar->CPlayer->cheats&CF_GODMODE) + if(statusBar->CPlayer->cheats&(CF_GODMODE|CF_GODMODE2)) { drawAlt = 1; } From c9214c1ce98ac5082fc323658e35f265d503c95d Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 20 May 2015 13:10:08 -0400 Subject: [PATCH 10/17] - Fixed: Hexen's status bar top graphic was drawn 1 pixel too low. - Fixed: Artiflash played on initial save loading. I seem to recall this looking like an intentional change, but perhaps I broke it since it's completely pointless to play the animation only on the first load of a save game if nothing has been loaded beforehand. --- src/g_shared/sbarinfo_commands.cpp | 2 +- wadsrc/static/sbarinfo/hexen.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index db5d9fc05c..2f7739a4fd 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -1730,7 +1730,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra static int artiflashTick; static fixed_t itemflashFade; }; -int CommandDrawSelectedInventory::artiflashTick = 4; +int CommandDrawSelectedInventory::artiflashTick = 0; int CommandDrawSelectedInventory::itemflashFade = FRACUNIT*3/4; void DSBarInfo::FlashItem(const PClass *itemtype) diff --git a/wadsrc/static/sbarinfo/hexen.txt b/wadsrc/static/sbarinfo/hexen.txt index 6450fac585..6e57550bce 100755 --- a/wadsrc/static/sbarinfo/hexen.txt +++ b/wadsrc/static/sbarinfo/hexen.txt @@ -51,7 +51,7 @@ statusbar fullscreen, fullscreenoffsets statusbar Normal { - drawimage "H2BAR", 0, 135; + drawimage "H2BAR", 0, 134; drawimage "STATBAR", 38, 162; drawselectedinventory artiflash, INDEXFONT_RAVEN, 143, 163, 174, 184, untranslated; @@ -204,7 +204,7 @@ statusbar Normal statusbar Automap { - drawimage "H2BAR", 0, 135; + drawimage "H2BAR", 0, 134; drawimage "KEYBAR", 38, 162; drawkeybar 5, horizontal, 20, 46, 164; drawimage hexenarmor(armor, "ARMSLOT1"), 150, 164; From 9f208409f2bb8a62a11ea0a1a515cbe433c7d17b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 May 2015 19:57:36 +0200 Subject: [PATCH 11/17] - fixed: The tag check in Sector_CopyScroller was inverted (it should reject sectors with the given tag, but it rejected everything else.) --- src/p_spec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 81f4a27e40..42a7b9ca46 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1741,7 +1741,7 @@ static void P_SpawnScrollers(void) if (lines[i].special == Sector_CopyScroller) { // don't allow copying the scroller if the sector has the same tag as it would just duplicate it. - if (tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0])) + if (!tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0])) { copyscrollers.Push(i); } From 0b3a22d6d2e5b98394b94b6fdbb681b8ad6e8648 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 May 2015 09:03:53 +0200 Subject: [PATCH 12/17] - fixed: The ending flat for No Rest For The Living was wrong. --- wadsrc/static/mapinfo/doom2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/mapinfo/doom2.txt b/wadsrc/static/mapinfo/doom2.txt index 5d0d405179..4f010352cc 100644 --- a/wadsrc/static/mapinfo/doom2.txt +++ b/wadsrc/static/mapinfo/doom2.txt @@ -536,7 +536,7 @@ map LEVEL09 lookup "NHUSTR_9" cluster 11 { - flat = "RROCK19" + flat = "SLIME16" music = "$MUSIC_READ_M" exittext = lookup, "NERVETEXT" } From 4546df7dc32519520ff05d2be6b562b582a91658 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Thu, 28 May 2015 00:41:07 +0200 Subject: [PATCH 13/17] - Fixed SetActorPitch and ChangeActorPitch issue. The code did not take into account the player's limited pitch. --- src/actor.h | 2 +- src/p_mobj.cpp | 18 +++++++++++++++++- src/thingdef/thingdef_codeptr.cpp | 18 +----------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/actor.h b/src/actor.h index 81b0a8b7b4..b38d4b2e0c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -823,7 +823,7 @@ public: } // These also set CF_INTERPVIEW for players. - void SetPitch(int p, bool interpolate); + void SetPitch(int p, bool interpolate, bool forceclamp = false); void SetAngle(angle_t ang, bool interpolate); void SetRoll(angle_t roll, bool interpolate); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 588bc2dccf..b0fc0d08ed 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3115,8 +3115,24 @@ void AActor::SetShade (int r, int g, int b) fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b); } -void AActor::SetPitch(int p, bool interpolate) +void AActor::SetPitch(int p, bool interpolate, bool forceclamp) { + if (player != NULL || forceclamp) + { // clamp the pitch we set + int min, max; + + if (player != NULL) + { + min = player->MinPitch; + max = player->MaxPitch; + } + else + { + min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); + max = ANGLE_90 - (1 << ANGLETOFINESHIFT); + } + p = clamp(p, min, max); + } if (p != pitch) { pitch = p; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 6ac0f115b1..15d8291fc8 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3989,23 +3989,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) return; } - if (ref->player != NULL || (flags & SPF_FORCECLAMP)) - { // clamp the pitch we set - int min, max; - - if (ref->player != NULL) - { - min = ref->player->MinPitch; - max = ref->player->MaxPitch; - } - else - { - min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); - max = ANGLE_90 - (1 << ANGLETOFINESHIFT); - } - pitch = clamp(pitch, min, max); - } - ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE)); + ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP)); } //=========================================================================== From 65cc361e9b1dc720950bc5f2e87bb526674260f3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 May 2015 09:22:48 +0200 Subject: [PATCH 14/17] - added Zandronum's text input menu items. --- src/menu/menu.h | 6 +- src/menu/menudef.cpp | 57 +++++++++++ src/menu/menuinput.cpp | 10 +- src/menu/optionmenuitems.h | 202 +++++++++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+), 2 deletions(-) diff --git a/src/menu/menu.h b/src/menu/menu.h index 3712c90658..561953d1c7 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -644,9 +644,13 @@ class DTextEnterMenu : public DMenu int InputGridX; int InputGridY; + // [TP] + bool AllowColors; + public: - DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid); + // [TP] Added allowcolors + DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false); void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 819ba96ba7..73101a76e7 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -830,6 +830,63 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) FOptionMenuItem *it = new FOptionMenuScreenResolutionLine(sc.String); desc->mItems.Push(it); } + // [TP] -- Text input widget + else if ( sc.Compare( "TextField" )) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName( "," ); + sc.MustGetString(); + FString cvar = sc.String; + FString check; + + if ( sc.CheckString( "," )) + { + sc.MustGetString(); + check = sc.String; + } + + FOptionMenuItem* it = new FOptionMenuTextField( label, cvar, check ); + desc->mItems.Push( it ); + } + // [TP] -- Number input widget + else if ( sc.Compare( "NumberField" )) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName( "," ); + sc.MustGetString(); + FString cvar = sc.String; + float minimum = 0.0f; + float maximum = 100.0f; + float step = 1.0f; + FString check; + + if ( sc.CheckString( "," )) + { + sc.MustGetFloat(); + minimum = (float) sc.Float; + sc.MustGetStringName( "," ); + sc.MustGetFloat(); + maximum = (float) sc.Float; + + if ( sc.CheckString( "," )) + { + sc.MustGetFloat(); + step = (float) sc.Float; + + if ( sc.CheckString( "," )) + { + sc.MustGetString(); + check = sc.String; + } + } + } + + FOptionMenuItem* it = new FOptionMenuNumberField( label, cvar, + minimum, maximum, step, check ); + desc->mItems.Push( it ); + } else { sc.ScriptError("Unknown keyword '%s'", sc.String); diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index 0f35b7e1f5..dc58b54ca9 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -40,6 +40,8 @@ #include "d_gui.h" #include "v_font.h" #include "v_palette.h" +// [TP] New #includes +#include "v_text.h" IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu) @@ -64,7 +66,8 @@ CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //============================================================================= -DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid) +// [TP] Added allowcolors +DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors) : DMenu(parent) { mEnterString = textbuffer; @@ -83,6 +86,7 @@ DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int InputGridX = 0; InputGridY = 0; } + AllowColors = allowcolors; // [TP] } //============================================================================= @@ -140,6 +144,10 @@ bool DTextEnterMenu::Responder(event_t *ev) { if (mEnterString[0]) { + // [TP] If we allow color codes, colorize the string now. + if (AllowColors) + strbin(mEnterString); + DMenu *parent = mParentMenu; Close(); parent->MenuEvent(MKEY_Input, false); diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 439ed7ffcf..5bc015369b 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -31,6 +31,7 @@ **--------------------------------------------------------------------------- ** */ +#include "v_text.h" void M_DrawConText (int color, int x, int y, const char *str); @@ -943,6 +944,207 @@ public: } }; + +//============================================================================= +// +// [TP] FOptionMenuFieldBase +// +// Base class for input fields +// +//============================================================================= + +class FOptionMenuFieldBase : public FOptionMenuItem +{ +public: + FOptionMenuFieldBase ( const char* label, const char* menu, const char* graycheck ) : + FOptionMenuItem ( label, menu ), + mCVar ( FindCVar( mAction, NULL )), + mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {} + + const char* GetCVarString() + { + if ( mCVar == NULL ) + return ""; + + return mCVar->GetGenericRep( CVAR_String ).String; + } + + virtual FString Represent() + { + return GetCVarString(); + } + + int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) + { + bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool ); + drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); + int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0; + + screen->DrawText( SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, + Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE ); + return indent; + } + + bool GetString ( int i, char* s, int len ) + { + if ( i == 0 ) + { + strncpy( s, GetCVarString(), len ); + s[len - 1] = '\0'; + return true; + } + + return false; + } + + bool SetString ( int i, const char* s ) + { + if ( i == 0 ) + { + if ( mCVar ) + { + UCVarValue vval; + vval.String = s; + mCVar->SetGenericRep( vval, CVAR_String ); + } + + return true; + } + + return false; + } + +protected: + // Action is a CVar in this class and derivatives. + FBaseCVar* mCVar; + FBaseCVar* mGrayCheck; +}; + +//============================================================================= +// +// [TP] FOptionMenuTextField +// +// A text input field widget, for use with string CVars. +// +//============================================================================= + +class FOptionMenuTextField : public FOptionMenuFieldBase +{ +public: + FOptionMenuTextField ( const char *label, const char* menu, const char* graycheck ) : + FOptionMenuFieldBase ( label, menu, graycheck ), + mEntering ( false ) {} + + FString Represent() + { + FString text = mEntering ? mEditName : GetCVarString(); + + if ( mEntering ) + text += ( gameinfo.gametype & GAME_DoomStrifeChex ) ? '_' : '['; + + return text; + } + + bool MenuEvent ( int mkey, bool fromcontroller ) + { + if ( mkey == MKEY_Enter ) + { + S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE ); + strcpy( mEditName, GetCVarString() ); + mEntering = true; + DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); + M_ActivateMenu( input ); + return true; + } + else if ( mkey == MKEY_Input ) + { + if ( mCVar ) + { + UCVarValue vval; + vval.String = mEditName; + mCVar->SetGenericRep( vval, CVAR_String ); + } + + mEntering = false; + return true; + } + else if ( mkey == MKEY_Abort ) + { + mEntering = false; + return true; + } + + return FOptionMenuItem::MenuEvent( mkey, fromcontroller ); + } + +private: + bool mEntering; + char mEditName[128]; +}; + +//============================================================================= +// +// [TP] FOptionMenuNumberField +// +// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e. +// where the user is interested in the exact value specifically) +// +//============================================================================= + +class FOptionMenuNumberField : public FOptionMenuFieldBase +{ +public: + FOptionMenuNumberField ( const char *label, const char* menu, float minimum, float maximum, + float step, const char* graycheck ) + : FOptionMenuFieldBase ( label, menu, graycheck ), + mMinimum ( minimum ), + mMaximum ( maximum ), + mStep ( step ) + { + if ( mMaximum <= mMinimum ) + swapvalues( mMinimum, mMaximum ); + + if ( mStep <= 0 ) + mStep = 1; + } + + bool MenuEvent ( int mkey, bool fromcontroller ) + { + if ( mCVar ) + { + float value = mCVar->GetGenericRep( CVAR_Float ).Float; + + if ( mkey == MKEY_Left ) + { + value -= mStep; + + if ( value < mMinimum ) + value = mMaximum; + } + else if ( mkey == MKEY_Right || mkey == MKEY_Enter ) + { + value += mStep; + + if ( value > mMaximum ) + value = mMinimum; + } + else + return FOptionMenuItem::MenuEvent( mkey, fromcontroller ); + + UCVarValue vval; + vval.Float = value; + mCVar->SetGenericRep( vval, CVAR_Float ); + S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE ); + } + + return true; + } + +private: + float mMinimum; + float mMaximum; + float mStep; +}; #ifndef NO_IMP CCMD(am_restorecolors) { From 22570e079e50eaf7c6e2c32f43dd4d8c3432bf8c Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 2 Jun 2015 12:10:45 -0500 Subject: [PATCH 15/17] * Added LAXTELEFRAGDMG. This flag forces all damage to be factored, regardless being above or below the telefrag threshold. - This only affects damage calculations being received by the end result. If the original damage was not a million or more, from the start, it will not hurt invulnerable-flagged or kill buddha-flagged monsters. - Fixed: Damage was inconsistent by the time the function checked for player cheats/invulnerability and (monster and player) buddha, yet monster invulnerability checked the original damage prior to factor processing. This means a damage source that intended to damage another below the threshold could accidentally increase with a powerdamage multiplier or the recipient with a weakness for it, resulting in invulnerability/buddha foiling. Now, checks for telefrag damage using the raw original value on player godmode, player/monster invulnerability and buddha. --- src/actor.h | 1 + src/p_interaction.cpp | 21 +++++++++++++-------- src/thingdef/thingdef_data.cpp | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/actor.h b/src/actor.h index b38d4b2e0c..52c88e9018 100644 --- a/src/actor.h +++ b/src/actor.h @@ -372,6 +372,7 @@ enum ActorFlag7 MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly MF7_NODECAL = 0x00040000, // [ZK] Forces puff to have no impact decal MF7_FORCEDECAL = 0x00080000, // [ZK] Forces puff's decal to override the weapon's. + MF7_LAXTELEFRAGDMG = 0x00100000, // [MC] Telefrag damage can be reduced. }; // --- mobj.renderflags --- diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index e25dcf7aca..f7035d462d 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -946,6 +946,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, bool forcedPain = false; int fakeDamage = 0; int holdDamage = 0; + int rawdamage = damage; if (damage < 0) damage = 0; @@ -980,7 +981,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } return -1; } - if ((target->flags2 & MF2_INVULNERABLE) && (damage < TELEFRAG_DAMAGE) && (!(flags & DMG_FORCED))) + // [MC] Changed it to check rawdamage here for consistency, even though that doesn't actually do anything + // different here. At any rate, invulnerable is being checked before type factoring, which is then being + // checked by player cheats/invul/buddha followed by monster buddha. This is inconsistent. Don't let the + // original telefrag damage CHECK (rawdamage) be influenced by outside factors when looking at cheats/invul. + if ((target->flags2 & MF2_INVULNERABLE) && (rawdamage < TELEFRAG_DAMAGE) && (!(flags & DMG_FORCED))) { // actor is invulnerable if (target->player == NULL) { @@ -1040,7 +1045,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, return -1; } - if (damage < TELEFRAG_DAMAGE) // TELEFRAG_DAMAGE may not be reduced at all or it may not guarantee its effect. + if ((rawdamage < TELEFRAG_DAMAGE) || (target->flags7 & MF7_NOTELEFRAGPIERCE)) // TELEFRAG_DAMAGE may only be reduced with NOTELEFRAGPIERCE or it may not guarantee its effect. { if (player && damage > 1) { @@ -1218,7 +1223,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { if (player) FriendlyFire = true; - if (damage < TELEFRAG_DAMAGE) + if (rawdamage < TELEFRAG_DAMAGE) //Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it. { // Still allow telefragging :-( damage = (int)((float)damage * level.teamdamage); if (damage < 0) @@ -1261,7 +1266,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (!(flags & DMG_FORCED)) { // check the real player, not a voodoo doll here for invulnerability effects - if ((damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) || + if ((rawdamage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) || (player->cheats & CF_GODMODE))) || (player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE)) //Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2. @@ -1286,7 +1291,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { player->mo->Inventory->AbsorbDamage(damage, mod, newdam); } - if (damage < TELEFRAG_DAMAGE) + if ((rawdamage < TELEFRAG_DAMAGE) || (player->mo->flags7 & MF7_NOTELEFRAGPIERCE)) //rawdamage is never modified. { // if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise. damage = newdam; @@ -1305,7 +1310,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } } - if (damage >= player->health && damage < TELEFRAG_DAMAGE + if (damage >= player->health && rawdamage < TELEFRAG_DAMAGE && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) && !player->morphTics) { // Try to use some inventory health @@ -1329,7 +1334,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // but telefragging should still do enough damage to kill the player) // Ignore players that are already dead. // [MC]Buddha2 absorbs telefrag damage, and anything else thrown their way. - if (!(flags & DMG_FORCED) && (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD))) + if (!(flags & DMG_FORCED) && (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (rawdamage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD))) { // If this is a voodoo doll we need to handle the real player as well. player->mo->health = target->health = player->health = 1; @@ -1394,7 +1399,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (target->health <= 0) { //[MC]Buddha flag for monsters. - if (!(flags & DMG_FORCED) && ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))) + if (!(flags & DMG_FORCED) && ((target->flags7 & MF7_BUDDHA) && (rawdamage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))) { //FOILBUDDHA or Telefrag damage must kill it. target->health = 1; } diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index a471e9985a..b1387ba524 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -258,6 +258,8 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(MF7, NODECAL, AActor, flags7), DEFINE_FLAG(MF7, FORCEDECAL, AActor, flags7), + DEFINE_FLAG(MF7, LAXTELEFRAGDMG, AActor, flags7), + // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects), From 4c390d92a4008bd1a6607df9d00ca4ca8b8c8d6e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 2 Jun 2015 12:22:26 -0500 Subject: [PATCH 16/17] -...forgot this one. --- src/p_interaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index f7035d462d..cbbd879781 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1045,7 +1045,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, return -1; } - if ((rawdamage < TELEFRAG_DAMAGE) || (target->flags7 & MF7_NOTELEFRAGPIERCE)) // TELEFRAG_DAMAGE may only be reduced with NOTELEFRAGPIERCE or it may not guarantee its effect. + if ((rawdamage < TELEFRAG_DAMAGE) || (target->flags7 & MF7_LAXTELEFRAGDMG)) // TELEFRAG_DAMAGE may only be reduced with NOTELEFRAGPIERCE or it may not guarantee its effect. { if (player && damage > 1) { @@ -1291,7 +1291,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { player->mo->Inventory->AbsorbDamage(damage, mod, newdam); } - if ((rawdamage < TELEFRAG_DAMAGE) || (player->mo->flags7 & MF7_NOTELEFRAGPIERCE)) //rawdamage is never modified. + if ((rawdamage < TELEFRAG_DAMAGE) || (player->mo->flags7 & MF7_LAXTELEFRAGDMG)) //rawdamage is never modified. { // if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise. damage = newdam; From ae3b52a68a6fbd92612545f3de5c61e60509c929 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 4 Jun 2015 09:20:55 +0200 Subject: [PATCH 17/17] - fixed: Software renderer's colormap variables should not be accessed from common renderer interface code. --- src/r_swrenderer.cpp | 7 +++++++ src/r_utility.cpp | 11 ----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index df928b25ec..051506e117 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -267,6 +267,11 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin BYTE *Pixels = const_cast(tex->GetPixels()); DSimpleCanvas *Canvas = tex->GetCanvas(); + // curse Doom's overuse of global variables in the renderer. + // These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette. + unsigned char *savecolormap = fixedcolormap; + FSpecialColormap *savecm = realfixedcolormap; + float savedfov = LastFOV; R_SetFOV ((float)fov); R_RenderViewToCanvas (viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); @@ -280,6 +285,8 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin FTexture::FlipNonSquareBlockRemap (Pixels, Canvas->GetBuffer(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap); } tex->SetUpdated(); + fixedcolormap = savecolormap; + realfixedcolormap = savecm; } //========================================================================== diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 60e2c1af15..cfe1767c77 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -62,9 +62,6 @@ extern bool DrawFSHUD; // [RH] Defined in d_main.cpp EXTERN_CVAR (Bool, cl_capfps) -extern lighttable_t* fixedcolormap; -extern FSpecialColormap*realfixedcolormap; - // TYPES ------------------------------------------------------------------- struct InterpolationViewer @@ -1101,11 +1098,6 @@ void FCanvasTextureInfo::UpdateAll () { FCanvasTextureInfo *probe; - // curse Doom's overuse of global variables in the renderer. - // These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette. - unsigned char *savecolormap = fixedcolormap; - FSpecialColormap *savecm = realfixedcolormap; - for (probe = List; probe != NULL; probe = probe->Next) { if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) @@ -1113,9 +1105,6 @@ void FCanvasTextureInfo::UpdateAll () Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); } } - - fixedcolormap = savecolormap; - realfixedcolormap = savecm; } //==========================================================================