diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 76eaedce..21b5e2c4 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -131,6 +131,9 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h Left = intpart - (float)(fracpart & 3) / 10.f; } } + NoWrap = false; + ClipX = ClipY = ClipWidth = ClipHeight = 0; + WrapWidth = 0; Top = y; Next = NULL; Lines = NULL; @@ -182,6 +185,17 @@ void DHUDMessage::Serialize (FArchive &arc) << Tics << State << TextColor << SBarID << SourceText << Font << Next << HUDWidth << HUDHeight; + if (SaveVersion >= 3960) + { + arc << NoWrap; + arc << ClipX << ClipY << ClipWidth << ClipHeight; + arc << WrapWidth; + } + else + { + NoWrap = false; + ClipX = ClipY = ClipWidth = ClipHeight = WrapWidth = 0; + } if (arc.IsLoading ()) { Lines = NULL; @@ -220,6 +234,37 @@ void DHUDMessage::ScreenSizeChanged () } } +//============================================================================ +// +// DHUDMessage :: CalcClipCoords +// +// Take the clip rectangle in HUD coordinates (set via SetHudSize in ACS) +// and convert them to screen coordinates. +// +//============================================================================ + +void DHUDMessage::CalcClipCoords(int hudheight) +{ + int x = ClipX, y = ClipY, w = ClipWidth, h = ClipHeight; + + if ((x | y | w | h) == 0) + { // No clipping rectangle set; use the full screen. + ClipLeft = 0; + ClipTop = 0; + ClipRight = screen->GetWidth(); + ClipBot = screen->GetHeight(); + } + else + { + screen->VirtualToRealCoordsInt(x, y, w, h, + HUDWidth, hudheight, false, true); + ClipLeft = x; + ClipTop = y; + ClipRight = x + w; + ClipBot = y + h; + } +} + //============================================================================ // // DHUDMessage :: ResetText @@ -232,11 +277,11 @@ void DHUDMessage::ResetText (const char *text) if (HUDWidth != 0) { - width = HUDWidth; + width = ClipWidth == 0 ? HUDWidth : ClipWidth; } else { - width = con_scaletext >=2 ? SCREENWIDTH/2 : (con_scaletext ? SCREENWIDTH / CleanXfac : SCREENWIDTH); + width = con_scaletext >= 2 ? SCREENWIDTH/2 : (con_scaletext ? SCREENWIDTH / CleanXfac : SCREENWIDTH); } if (Lines != NULL) @@ -244,7 +289,7 @@ void DHUDMessage::ResetText (const char *text) V_FreeBrokenLines (Lines); } - Lines = V_BreakLines (Font, width, (BYTE *)text); + Lines = V_BreakLines (Font, NoWrap ? INT_MAX : width, (BYTE *)text); NumLines = 0; Width = 0; @@ -377,15 +422,14 @@ void DHUDMessage::Draw (int bottom, int visibility) ystep = Font->GetHeight() * yscale; if (HUDHeight < 0) - { - // A negative height means the HUD size covers the status bar + { // A negative height means the HUD size covers the status bar hudheight = -HUDHeight; } else - { - // A positive height means the HUD size does not cover the status bar + { // A positive height means the HUD size does not cover the status bar hudheight = Scale (HUDHeight, screen_height, bottom); } + CalcClipCoords(hudheight); for (i = 0; i < NumLines; i++) { @@ -441,6 +485,10 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_ClipLeft, ClipLeft, + DTA_ClipRight, ClipRight, + DTA_ClipTop, ClipTop, + DTA_ClipBottom, ClipBot, DTA_Alpha, Alpha, DTA_RenderStyle, Style, TAG_DONE); @@ -541,6 +589,10 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_ClipLeft, ClipLeft, + DTA_ClipRight, ClipRight, + DTA_ClipTop, ClipTop, + DTA_ClipBottom, ClipBot, DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); @@ -638,6 +690,10 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_ClipLeft, ClipLeft, + DTA_ClipRight, ClipRight, + DTA_ClipTop, ClipTop, + DTA_ClipBottom, ClipBot, DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); @@ -814,6 +870,10 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_ClipLeft, ClipLeft, + DTA_ClipRight, ClipRight, + DTA_ClipTop, ClipTop, + DTA_ClipBottom, ClipBot, DTA_Alpha, Alpha, DTA_TextLen, LineVisible, DTA_RenderStyle, Style, diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index df3daf59..d45f88cd 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -85,22 +85,42 @@ public: { Alpha = alpha; } + void SetNoWrap(bool nowrap) + { + NoWrap = nowrap; + ResetText(SourceText); + } + void SetClipRect(int x, int y, int width, int height) + { + ClipX = x; + ClipY = y; + ClipWidth = width; + ClipHeight = height; + } + void SetWrapWidth(int wrap) + { + WrapWidth = wrap; + ResetText(SourceText); + } protected: FBrokenLines *Lines; int Width, Height, NumLines; float Left, Top; - bool CenterX; + bool CenterX, NoWrap; int HoldTics; int Tics; int State; int VisibilityFlags; int HUDWidth, HUDHeight; + int ClipX, ClipY, ClipWidth, ClipHeight, WrapWidth; // in HUD coords + int ClipLeft, ClipTop, ClipRight, ClipBot; // in screen coords EColorRange TextColor; FFont *Font; FRenderStyle Style; fixed_t Alpha; + void CalcClipCoords(int hudheight); DHUDMessage () : SourceText(NULL) {} private: diff --git a/src/info.cpp b/src/info.cpp index e6bb0da0..0a8d9221 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -55,7 +55,7 @@ extern void LoadActors (); extern void InitBotStuff(); extern void ClearStrifeTypes(); -FRandom FState::pr_statetics; +FRandom FState::pr_statetics("StateTics"); //========================================================================== // diff --git a/src/p_acs.cpp b/src/p_acs.cpp index c87f4181..607b6826 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -93,6 +93,7 @@ FRandom pr_acs ("ACS"); #define HUDMSG_COLORSTRING (0x40000000) #define HUDMSG_ADDBLEND (0x20000000) #define HUDMSG_ALPHA (0x10000000) +#define HUDMSG_NOWRAP (0x08000000) // HUD message layers; these are not flags #define HUDMSG_LAYER_SHIFT 12 @@ -2169,6 +2170,15 @@ void DLevelScript::Serialize (FArchive &arc) arc << activefont << hudwidth << hudheight; + if (SaveVersion >= 3960) + { + arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight + << WrapWidth; + } + else + { + ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0; + } } DLevelScript::DLevelScript () @@ -3382,10 +3392,12 @@ enum EACSFunctions ACSF_Sqrt, ACSF_FixedSqrt, ACSF_VectorLength, + ACSF_SetHUDClipRect, + ACSF_SetHUDWrapWidth, // ZDaemon - ACSF_GetTeamScore = 19620, - ACSF_SetTeamScore, + ACSF_GetTeamScore = 19620, // (int team) + ACSF_SetTeamScore, // (int team, int value) }; int DLevelScript::SideFromID(int id, int side) @@ -3900,11 +3912,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_UniqueTID: return P_FindUniqueTID(argCount > 0 ? args[0] : 0, argCount > 1 ? args[1] : 0); - break; case ACSF_IsTIDUsed: return P_IsTIDUsed(args[0]); - break; case ACSF_Sqrt: return xs_FloorToInt(sqrt(double(args[0]))); @@ -3915,6 +3925,18 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_VectorLength: return FLOAT2FIXED(TVector2(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length()); + case ACSF_SetHUDClipRect: + ClipRectLeft = argCount > 0 ? args[0] : 0; + ClipRectTop = argCount > 1 ? args[1] : 0; + ClipRectWidth = argCount > 2 ? args[2] : 0; + ClipRectHeight = argCount > 3 ? args[3] : 0; + WrapWidth = argCount > 4 ? args[4] : 0; + break; + + case ACSF_SetHUDWrapWidth: + WrapWidth = argCount > 0 ? args[0] : 0; + break; + default: break; } @@ -5737,7 +5759,16 @@ scriptwait: } break; } + msg->SetClipRect(ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight); + if (WrapWidth != 0) + { + msg->SetWrapWidth(WrapWidth); + } msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); + if (type & HUDMSG_NOWRAP) + { + msg->SetNoWrap(true); + } if (type & HUDMSG_ALPHA) { msg->SetAlpha(alpha); @@ -7351,7 +7382,9 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr backSide = flags & ACS_BACKSIDE; activefont = SmallFont; hudwidth = hudheight = 0; + ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0; state = SCRIPT_Running; + // Hexen waited one second before executing any open scripts. I didn't realize // this when I wrote my ACS implementation. Now that I know, it's still best to // run them right away because there are several map properties that can't be diff --git a/src/p_acs.h b/src/p_acs.h index d2ae2038..44786e26 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -707,6 +707,8 @@ protected: bool backSide; FFont *activefont; int hudwidth, hudheight; + int ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight; + int WrapWidth; FBehavior *activeBehavior; void Link (); diff --git a/src/svnrevision.h b/src/svnrevision.h index b3dd416b..82de1094 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3959" -#define ZD_SVN_REVISION_NUMBER 3959 +#define ZD_SVN_REVISION_STRING "3963" +#define ZD_SVN_REVISION_NUMBER 3963 diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c55cd32a..597ba48d 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2299,15 +2299,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) for (i = 0; i < GetDefaultByType(debris)->health; i++) { mo = Spawn(debris, self->x+((pr_spawndebris()-128)<<12), - self->y+((pr_spawndebris()-128)<<12), - self->z+(pr_spawndebris()*self->height/256+self->GetBobOffset()), ALLOW_REPLACE); - if (mo && transfer_translation) + self->y + ((pr_spawndebris()-128)<<12), + self->z + (pr_spawndebris()*self->height/256+self->GetBobOffset()), ALLOW_REPLACE); + if (mo) { - mo->Translation = self->Translation; - } - if (mo && i < mo->GetClass()->ActorInfo->NumOwnedStates) - { - mo->SetState (mo->GetClass()->ActorInfo->OwnedStates + i); + if (transfer_translation) + { + mo->Translation = self->Translation; + } + if (i < mo->GetClass()->ActorInfo->NumOwnedStates) + { + mo->SetState(mo->GetClass()->ActorInfo->OwnedStates + i); + } mo->velz = FixedMul(mult_v, ((pr_spawndebris()&7)+5)*FRACUNIT); mo->velx = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6)); mo->vely = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6));