diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt index d13f23254..e95c69154 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 ) diff --git a/src/actor.h b/src/actor.h index 755ae6f3a..d7413da3d 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 --- @@ -823,7 +824,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/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index bb1b04850..2f7739a4f 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; } @@ -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/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 086f170f8..7a48a2b9c 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. @@ -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; } diff --git a/src/menu/menu.h b/src/menu/menu.h index 3712c9065..561953d1c 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 819ba96ba..73101a76e 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 0f35b7e1f..dc58b54ca 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 439ed7ffc..5bc015369 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) { diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index e25dcf7ac..cbbd87978 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_LAXTELEFRAGDMG)) // 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_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; @@ -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/p_mobj.cpp b/src/p_mobj.cpp index 588bc2dcc..b0fc0d08e 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/p_pspr.cpp b/src/p_pspr.cpp index 6e699a41b..63f3bc648 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; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 81f4a27e4..42a7b9ca4 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); } diff --git a/src/p_tags.cpp b/src/p_tags.cpp index 851c4ee94..c08caec8f 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++; + } } } } diff --git a/src/p_tags.h b/src/p_tags.h index 75d397d8d..c3162d9b5 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; diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index c24fd797a..76191e1a9 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,14 @@ void SDLFB::ResetSDLRenderer () NotPaletted = false; } - // Calculate update rectangle + // In fullscreen, set logical size according to animorphic ratio. + // Windowed modes are rendered to fill the window (usually 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; - } - else - { - // In windowed mode we just update the whole window. - UpdateRect.x = 0; - UpdateRect.y = 0; - UpdateRect.w = Width; - UpdateRect.h = Height; + ScaleWithAspect (w, h, Width, Height); + SDL_RenderSetLogicalSize (Renderer, w, h); } } @@ -726,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) @@ -751,6 +765,11 @@ void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) } } } + else + { + x = (SWORD)(x*Width/w); + y = (SWORD)(y*Height/h); + } } ADD_STAT (blit) diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index df928b25e..051506e11 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 60e2c1af1..cfe1767c7 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; } //========================================================================== diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 6ac0f115b..15d8291fc 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)); } //=========================================================================== diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index a471e9985..b1387ba52 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), diff --git a/wadsrc/static/mapinfo/doom2.txt b/wadsrc/static/mapinfo/doom2.txt index 5d0d40517..4f010352c 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" } diff --git a/wadsrc/static/sbarinfo/hexen.txt b/wadsrc/static/sbarinfo/hexen.txt index 6450fac58..6e57550bc 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;