From b570d0819b9a46e350efd12a38a93ac37dd122b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 13:14:22 +0100 Subject: [PATCH 01/11] - streamlined font handling for scripts a bit. - moved the two 'you raised the alarm' messages for Strife to the string table --- src/c_console.cpp | 3 +- src/d_main.cpp | 3 + src/dobjtype.cpp | 2 + src/dobjtype.h | 1 + src/r_utility.cpp | 2 - src/scripting/codegeneration/codegen.cpp | 78 ++++++++++++++++++++ src/scripting/codegeneration/codegen.h | 20 +++++ src/serializer.cpp | 8 +- src/v_font.cpp | 40 +++++----- src/v_font.h | 6 +- wadsrc/static/language.enu | 3 + wadsrc/static/zscript/base.txt | 5 +- wadsrc/static/zscript/compatibility.txt | 4 +- wadsrc/static/zscript/strife/strifeitems.txt | 4 +- 14 files changed, 144 insertions(+), 35 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 4340cc3f8..493625bf9 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1752,11 +1752,10 @@ void C_MidPrintBold (FFont *font, const char *msg) DEFINE_ACTION_FUNCTION(_Console, MidPrint) { PARAM_PROLOGUE; - PARAM_STRING(font); + PARAM_POINTER_NOT_NULL(fnt, FFont); PARAM_STRING(text); PARAM_BOOL_DEF(bold); - FFont *fnt = FFont::FindFont(font); const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars(); if (!bold) C_MidPrint(fnt, txt); else C_MidPrintBold(fnt, txt); diff --git a/src/d_main.cpp b/src/d_main.cpp index 9a966e6d5..573c19071 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2467,6 +2467,9 @@ void D_DoomMain (void) TexMan.Init(); C_InitConback(); + StartScreen->Progress(); + V_InitFonts(); + // [CW] Parse any TEAMINFO lumps. if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n"); TeamLibrary.ParseTeamInfo (); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 7468b6dab..e4d9fc177 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -88,6 +88,7 @@ PColor *TypeColor; PTextureID *TypeTextureID; PSpriteID *TypeSpriteID; PStatePointer *TypeState; +PPointer *TypeFont; PStateLabel *TypeStateLabel; PStruct *TypeVector2; PStruct *TypeVector3; @@ -437,6 +438,7 @@ void PType::StaticInit() TypeVoidPtr = NewPointer(TypeVoid, false); TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value. TypeStringStruct = NewNativeStruct("Stringstruct", nullptr); + TypeFont = NewPointer(NewNativeStruct("Font", nullptr)); #ifdef __BIG_ENDIAN__ TypeColorStruct->AddField(NAME_a, TypeUInt8); TypeColorStruct->AddField(NAME_r, TypeUInt8); diff --git a/src/dobjtype.h b/src/dobjtype.h index 2726ebff1..8cbe79966 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -940,6 +940,7 @@ extern PStruct *TypeVector3; extern PStruct *TypeColorStruct; extern PStruct *TypeStringStruct; extern PStatePointer *TypeState; +extern PPointer *TypeFont; extern PStateLabel *TypeStateLabel; extern PPointer *TypeNullPtr; extern PPointer *TypeVoidPtr; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index d2358d8b3..a7a3860bb 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -337,8 +337,6 @@ void R_Init () { atterm (R_Shutdown); - StartScreen->Progress(); - V_InitFonts(); StartScreen->Progress(); // Colormap init moved back to InitPalette() //R_InitColormaps (); diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index a23811390..a3641269f 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -1420,6 +1420,76 @@ ExpEmit FxSoundCast::Emit(VMFunctionBuilder *build) return to; } +//========================================================================== +// +// +// +//========================================================================== + +FxFontCast::FxFontCast(FxExpression *x) + : FxExpression(EFX_FontCast, x->ScriptPosition) +{ + basex = x; + ValueType = TypeSound; +} + +//========================================================================== +// +// +// +//========================================================================== + +FxFontCast::~FxFontCast() +{ + SAFE_DELETE(basex); +} + +//========================================================================== +// +// +// +//========================================================================== + +FxExpression *FxFontCast::Resolve(FCompileContext &ctx) +{ + CHECKRESOLVED(); + SAFE_RESOLVE(basex, ctx); + + if (basex->ValueType == TypeFont) + { + FxExpression *x = basex; + basex = nullptr; + delete this; + return x; + } + // This intentionally does not convert non-constants. + // The sole reason for this cast is to allow passing both font pointers and string constants to printing functions and have the font names checked at compile time. + else if ((basex->ValueType == TypeString || basex->ValueType == TypeName) && basex->isConstant()) + { + ExpVal constval = static_cast(basex)->GetValue(); + FFont *font = V_GetFont(constval.GetString()); + // Font must exist. Most internal functions working with fonts do not like null pointers. + // If checking is needed scripts will have to call Font.GetFont themselves. + if (font == nullptr) + { + ScriptPosition.Message(MSG_ERROR, "Unknown font '%s'", constval.GetString().GetChars()); + delete this; + return nullptr; + } + + FxExpression *x = new FxConstant(font, ScriptPosition); + delete this; + return x; + } + else + { + ScriptPosition.Message(MSG_ERROR, "Cannot convert to font"); + delete this; + return nullptr; + } +} + + //========================================================================== // // generic type cast operator @@ -1649,6 +1719,14 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx) { goto basereturn; } + else if (ValueType == TypeFont) + { + FxExpression *x = new FxFontCast(basex); + x = x->Resolve(ctx); + basex = nullptr; + delete this; + return x; + } // todo: pointers to class objects. // All other types are only compatible to themselves and have already been handled above by the equality check. // Anything that falls through here is not compatible and must print an error. diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index 69ad192f5..6438e0868 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -294,6 +294,7 @@ enum EFxType EFX_StrLen, EFX_ColorLiteral, EFX_GetDefaultByType, + EFX_FontCast, EFX_COUNT }; @@ -488,6 +489,13 @@ public: isresolved = true; } + FxConstant(FFont *state, const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) + { + value.pointer = state; + ValueType = value.Type = TypeFont; + isresolved = true; + } + FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) { value.pointer = nullptr; @@ -664,6 +672,18 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; +class FxFontCast : public FxExpression +{ + FxExpression *basex; + +public: + + FxFontCast(FxExpression *x); + ~FxFontCast(); + FxExpression *Resolve(FCompileContext&); +}; + + //========================================================================== // // FxTypeCast diff --git a/src/serializer.cpp b/src/serializer.cpp index 6d7a6ef7c..dcb7acab6 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -2187,13 +2187,13 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon { if (arc.isWriting()) { - const char *n = font->GetName(); - return arc.StringPtr(key, n); + FName n = font->GetName(); + return arc(key, n); } else { - const char *n; - arc.StringPtr(key, n); + FName n; + arc(key, n); font = V_GetFont(n); if (font == nullptr) { diff --git a/src/v_font.cpp b/src/v_font.cpp index 2854be8c2..6a4f60826 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -340,6 +340,14 @@ FFont *V_GetFont(const char *name) return font; } +DEFINE_ACTION_FUNCTION(FFont, GetFont) +{ + PARAM_PROLOGUE; + PARAM_NAME(name); + ACTION_RETURN_POINTER(V_GetFont(name.GetChars())); +} + + //========================================================================== // // FFont :: FFont @@ -366,7 +374,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; - Name = copystring (name); + FontName = name; Next = FirstFont; FirstFont = this; Cursor = '_'; @@ -478,11 +486,6 @@ FFont::~FFont () delete[] PatchRemap; PatchRemap = NULL; } - if (Name) - { - delete[] Name; - Name = NULL; - } FFont **prev = &FirstFont; FFont *font = *prev; @@ -508,27 +511,26 @@ FFont::~FFont () // //========================================================================== -FFont *FFont::FindFont (const char *name) +FFont *FFont::FindFont (FName name) { - if (name == NULL) + if (name == NAME_None) { - return NULL; + return nullptr; } FFont *font = FirstFont; - while (font != NULL) + while (font != nullptr) { - if (stricmp (font->Name, name) == 0) - break; + if (font->FontName == name) return font; font = font->Next; } - return font; + return nullptr; } DEFINE_ACTION_FUNCTION(FFont, FindFont) { PARAM_PROLOGUE; - PARAM_STRING(name); + PARAM_NAME(name); ACTION_RETURN_POINTER(FFont::FindFont(name)); } @@ -935,7 +937,7 @@ FFont::FFont (int lump) Lump = lump; Chars = NULL; PatchRemap = NULL; - Name = NULL; + FontName = NAME_None; Cursor = '_'; } @@ -951,7 +953,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) { assert(lump >= 0); - Name = copystring (name); + FontName = name; FMemLump data1 = Wads.ReadLump (lump); const BYTE *data = (const BYTE *)data1.GetMem(); @@ -1189,7 +1191,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) if (destSize < 0) { i += FirstChar; - I_FatalError ("Overflow decompressing char %d (%c) of %s", i, i, Name); + I_FatalError ("Overflow decompressing char %d (%c) of %s", i, i, FontName.GetChars()); } } @@ -1491,7 +1493,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) : FTexture *pic = TexMan[picnum]; - Name = copystring(picname); + FontName = picname; FontHeight = pic->GetScaledHeight(); SpaceWidth = pic->GetScaledWidth(); GlobalKerning = 0; @@ -1903,7 +1905,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l memcpy(this->notranslate, notranslate, 256*sizeof(bool)); - Name = copystring(name); + FontName = name; Chars = new CharData[count]; charlumps = new FTexture*[count]; PatchRemap = new BYTE[256]; diff --git a/src/v_font.h b/src/v_font.h index b31c51471..124f29a4e 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -88,9 +88,9 @@ public: int GetDefaultKerning () const { return GlobalKerning; } virtual void LoadTranslations(); void Preload() const; - const char *GetName() const { return Name; } + FName GetName() const { return FontName; } - static FFont *FindFont (const char *fontname); + static FFont *FindFont(FName fontname); static void StaticPreloadFonts(); // Return width of string in pixels (unscaled) @@ -127,7 +127,7 @@ protected: BYTE *PatchRemap; int Lump; - char *Name; + FName FontName; FFont *Next; static FFont *FirstFont; diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index bdc1ce3ae..4d567d3ca 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1417,6 +1417,9 @@ TXT_KILLED_ORACLE = "You've Killed The Oracle!"; TXT_KILLED_MACIL = "You Killed Macil!"; TXT_KILLED_LOREMASTER = "You've Killed the Loremaster!"; +TXT_YOUFOOL = "You Fool! You've set off the alarm."; +TXT_YOUREDEAD = "You're dead! You set off the alarm."; + // Strife pickup messages TXT_METALARMOR = "You picked up the Metal Armor."; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index b84d72a51..f1df373c3 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -70,13 +70,14 @@ struct Screen native struct Font native { - native static Font FindFont(String name); + native static Font FindFont(Name fontname); + native static Font GetFont(Name fontname); } struct Console native { native static void HideConsole(); - native static void MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. + native static void MidPrint(Font fontname, string textlabel, bool bold = false); } struct DamageTypeDefinition native diff --git a/wadsrc/static/zscript/compatibility.txt b/wadsrc/static/zscript/compatibility.txt index 752de8016..1ae88ab85 100644 --- a/wadsrc/static/zscript/compatibility.txt +++ b/wadsrc/static/zscript/compatibility.txt @@ -9,7 +9,9 @@ extend class Object deprecated static void C_MidPrint(string fontname, string textlabel, bool bold = false) // deprecated for 2.4.x { - return Console.MidPrint(fontname, textlabel, bold); + let f = Font.GetFont(fontname); + if (f == null) return; + return Console.MidPrint(f, textlabel, bold); } } diff --git a/wadsrc/static/zscript/strife/strifeitems.txt b/wadsrc/static/zscript/strife/strifeitems.txt index 970478cae..4c7311b56 100644 --- a/wadsrc/static/zscript/strife/strifeitems.txt +++ b/wadsrc/static/zscript/strife/strifeitems.txt @@ -632,7 +632,7 @@ class RaiseAlarm : DummyStrifeItem dropper.target.SoundAlert(dropper.target); if (dropper.target.CheckLocalView(consoleplayer)) { - A_Log("You Fool! You've set off the alarm."); + Console.MidPrint(SmallFont, "$TXT_YOUFOOL"); } } Destroy (); @@ -672,7 +672,7 @@ class CloseDoor222 : DummyStrifeItem { if (dropper.target.CheckLocalView(consoleplayer)) { - A_Log("You're dead! You set off the alarm."); + Console.MidPrint(SmallFont, "$TXT_YOUREDEAD"); } dropper.target.SoundAlert(dropper.target); } From ef871ec09faf26d87ffdd7981caa9970d31ba654 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Feb 2017 14:52:17 +0200 Subject: [PATCH 02/11] Fixed compilation with GCC/Clang error: cannot pass non-trivial object of type 'FName' to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs] --- src/serializer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serializer.cpp b/src/serializer.cpp index dcb7acab6..a577056af 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -2197,7 +2197,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon font = V_GetFont(n); if (font == nullptr) { - Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n); + Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n.GetChars()); font = SmallFont; } return arc; From d8a1ce88b01eb43b815cae0a43fc0c800d814782 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 13:55:05 +0100 Subject: [PATCH 03/11] - a few more exports from FFont. --- src/v_font.cpp | 76 ++++++++++++++++++++++++++++++---- src/v_font.h | 2 - src/v_text.cpp | 42 ------------------- wadsrc/static/zscript/base.txt | 3 ++ 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 6a4f60826..00d3b10f7 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -94,6 +94,7 @@ The FON2 header is followed by variable length data: #include "r_data/r_translate.h" #include "colormatcher.h" #include "v_palette.h" +#include "v_text.h" // MACROS ------------------------------------------------------------------ @@ -845,6 +846,65 @@ int FFont::GetCharWidth (int code) const return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove; } +DEFINE_ACTION_FUNCTION(FFont, GetCharWidth) +{ + PARAM_SELF_STRUCT_PROLOGUE(FFont); + PARAM_INT(code); + ACTION_RETURN_INT(self->GetCharWidth(code)); +} + +//========================================================================== +// +// Find string width using this font +// +//========================================================================== + +int FFont::StringWidth(const BYTE *string) const +{ + int w = 0; + int maxw = 0; + + while (*string) + { + if (*string == TEXTCOLOR_ESCAPE) + { + ++string; + if (*string == '[') + { + while (*string != '\0' && *string != ']') + { + ++string; + } + } + if (*string != '\0') + { + ++string; + } + continue; + } + else if (*string == '\n') + { + if (w > maxw) + maxw = w; + w = 0; + ++string; + } + else + { + w += GetCharWidth(*string++) + GlobalKerning; + } + } + + return MAX(maxw, w); +} + +DEFINE_ACTION_FUNCTION(FFont, StringWidth) +{ + PARAM_SELF_STRUCT_PROLOGUE(FFont); + PARAM_STRING(str); + ACTION_RETURN_INT(self->StringWidth(str)); +} + //========================================================================== // // FFont :: LoadTranslations @@ -2492,6 +2552,13 @@ EColorRange V_FindFontColor (FName name) return CR_UNTRANSLATED; } +DEFINE_ACTION_FUNCTION(FFont, FindFontColor) +{ + PARAM_SELF_STRUCT_PROLOGUE(FFont); + PARAM_NAME(code); + ACTION_RETURN_INT((int)V_FindFontColor(code)); +} + //========================================================================== // // V_LogColorFromColorRange @@ -2666,12 +2733,3 @@ void V_ClearFonts() SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL; } -void V_RetranslateFonts() -{ - FFont *font = FFont::FirstFont; - while(font) - { - font->LoadTranslations(); - font = font->Next; - } -} diff --git a/src/v_font.h b/src/v_font.h index 124f29a4e..4c78b3007 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -134,7 +134,6 @@ protected: friend struct FontsDeleter; friend void V_ClearFonts(); - friend void V_RetranslateFonts(); }; @@ -147,6 +146,5 @@ PalEntry V_LogColorFromColorRange (EColorRange range); EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor); FFont *V_GetFont(const char *); void V_InitFontColors(); -void V_RetranslateFonts(); #endif //__V_FONT_H__ diff --git a/src/v_text.cpp b/src/v_text.cpp index 3fcac5541..47fbf6f1b 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -167,48 +167,6 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s } -// -// Find string width using this font -// -int FFont::StringWidth (const BYTE *string) const -{ - int w = 0; - int maxw = 0; - - while (*string) - { - if (*string == TEXTCOLOR_ESCAPE) - { - ++string; - if (*string == '[') - { - while (*string != '\0' && *string != ']') - { - ++string; - } - } - if (*string != '\0') - { - ++string; - } - continue; - } - else if (*string == '\n') - { - if (w > maxw) - maxw = w; - w = 0; - ++string; - } - else - { - w += GetCharWidth (*string++) + GlobalKerning; - } - } - - return MAX (maxw, w); -} - // // Break long lines of text into multiple lines no longer than maxwidth pixels // diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index f1df373c3..cb5239a37 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -70,6 +70,9 @@ struct Screen native struct Font native { + native int GetCharWidth(int code); + native int StringWidth(String code); + native static int FindFontColor(Name color); native static Font FindFont(Name fontname); native static Font GetFont(Name fontname); } From 52bec33c0d30cef75b7a990bce6f6ef4198e2591 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 16:18:41 +0100 Subject: [PATCH 04/11] - exported BrokenLines to scripting as a new class. - removed the hard limit of 128 lines for V_BreakLines. --- src/v_text.cpp | 92 +++++++++++++++++++++++++++++----- src/v_text.h | 10 ++-- wadsrc/static/zscript/base.txt | 8 +++ 3 files changed, 92 insertions(+), 18 deletions(-) diff --git a/src/v_text.cpp b/src/v_text.cpp index 47fbf6f1b..324e22bc0 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -47,11 +47,14 @@ #include "doomstat.h" #include "templates.h" +//========================================================================== // // DrawChar // // Write a single character using the given font // +//========================================================================== + void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...) { if (font == NULL) @@ -79,11 +82,14 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch } } +//========================================================================== // // DrawText // // Write a string using the given font // +//========================================================================== + void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...) { int w; @@ -167,9 +173,12 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s } +//========================================================================== // // Break long lines of text into multiple lines no longer than maxwidth pixels // +//========================================================================== + static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const BYTE *stop, FString &linecolor) { if (!linecolor.IsEmpty()) @@ -181,20 +190,19 @@ static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const B line->Width = font->StringWidth (line->Text); } -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor) +FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor, unsigned int *count) { - FBrokenLines lines[128]; // Support up to 128 lines (should be plenty) + TArray Lines(128); const BYTE *space = NULL, *start = string; - size_t i, ii; int c, w, nw; FString lastcolor, linecolor; bool lastWasSpace = false; int kerning = font->GetDefaultKerning (); - i = w = 0; + w = 0; - while ( (c = *string++) && i < countof(lines) ) + while ( (c = *string++) ) { if (c == TEXTCOLOR_ESCAPE) { @@ -241,14 +249,14 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool if (!space) space = string - 1; - breakit (&lines[i], font, start, space, linecolor); + auto index = Lines.Reserve(1); + breakit (&Lines[index], font, start, space, linecolor); if (c == '\n' && !preservecolor) { lastcolor = ""; // Why, oh why, did I do it like this? } linecolor = lastcolor; - i++; w = 0; lastWasSpace = false; start = space; @@ -270,7 +278,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool } // String here is pointing one character after the '\0' - if (i < countof(lines) && --string - start >= 1) + if (--string - start >= 1) { const BYTE *s = start; @@ -279,20 +287,25 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool // If there is any non-white space in the remainder of the string, add it. if (!isspace (*s++)) { - breakit (&lines[i++], font, start, string, linecolor); + auto i = Lines.Reserve(1); + breakit (&Lines[i], font, start, string, linecolor); break; } } } // Make a copy of the broken lines and return them - FBrokenLines *broken = new FBrokenLines[i+1]; + FBrokenLines *broken = new FBrokenLines[Lines.Size() + 1]; - for (ii = 0; ii < i; ++ii) + for (unsigned ii = 0; ii < Lines.Size(); ++ii) { - broken[ii] = lines[ii]; + broken[ii] = Lines[ii]; + } + broken[Lines.Size()].Width = -1; + if (count != nullptr) + { + *count = Lines.Size(); } - broken[ii].Width = -1; return broken; } @@ -304,3 +317,56 @@ void V_FreeBrokenLines (FBrokenLines *lines) delete[] lines; } } + +class DBrokenLines : public DObject +{ + DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) + +public: + FBrokenLines *mBroken; + unsigned int mCount; + + DBrokenLines(FBrokenLines *broken, unsigned int count) + { + mBroken = broken; + mCount = count; + } + + void OnDestroy() override + { + V_FreeBrokenLines(mBroken); + } +}; + +IMPLEMENT_CLASS(DBrokenLines, true, false); + +DEFINE_ACTION_FUNCTION(DBrokenLines, Count) +{ + PARAM_SELF_PROLOGUE(DBrokenLines); + ACTION_RETURN_INT(self->mCount); +} + +DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth) +{ + PARAM_SELF_PROLOGUE(DBrokenLines); + PARAM_INT(index); + ACTION_RETURN_INT((unsigned)index >= self->mCount? -1 : self->mBroken[index].Width); +} + +DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt) +{ + PARAM_SELF_PROLOGUE(DBrokenLines); + PARAM_INT(index); + ACTION_RETURN_STRING((unsigned)index >= self->mCount? -1 : self->mBroken[index].Text); +} + +DEFINE_ACTION_FUNCTION(FFont, BreakLines) +{ + PARAM_SELF_STRUCT_PROLOGUE(FFont); + PARAM_STRING(text); + PARAM_INT(maxwidth); + + unsigned int count; + FBrokenLines *broken = V_BreakLines(self, maxwidth, text, true, &count); + ACTION_RETURN_OBJECT(new DBrokenLines(broken, count)); +} diff --git a/src/v_text.h b/src/v_text.h index 3baf62af7..bd24be405 100644 --- a/src/v_text.h +++ b/src/v_text.h @@ -75,11 +75,11 @@ struct FBrokenLines #define TEXTCOLOR_CHAT "\034*" #define TEXTCOLOR_TEAMCHAT "\034!" -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false); +FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false, unsigned int *count = nullptr); void V_FreeBrokenLines (FBrokenLines *lines); -inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false) - { return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor); } -inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false) - { return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor); } +inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false, unsigned int *count = nullptr) + { return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor, count); } +inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr) + { return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor, count); } #endif //__V_TEXT_H__ diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index cb5239a37..57ec1b6df 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -68,6 +68,13 @@ struct Screen native native static void DrawHUDTexture(TextureID tex, double x, double y); } +class BrokenLines : Object native +{ + native int Count(); + native int StringWidth(int line); + native String StringAt(int line); +} + struct Font native { native int GetCharWidth(int code); @@ -75,6 +82,7 @@ struct Font native native static int FindFontColor(Name color); native static Font FindFont(Name fontname); native static Font GetFont(Name fontname); + native static BrokenLines BreakLines(String text, int maxlen); } struct Console native From 9e038b75fa9d0532c8232cdfc06b58d198ec31cb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 16:47:33 +0100 Subject: [PATCH 05/11] - exported DrawChar and DrawText. --- src/v_draw.cpp | 4 +- src/v_text.cpp | 121 ++++++++++++++++++++++++++------- src/v_video.h | 8 ++- wadsrc/static/zscript/base.txt | 6 +- 4 files changed, 109 insertions(+), 30 deletions(-) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 331be9712..52f8cde7a 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -142,7 +142,7 @@ void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, .. DrawTextureParms(img, parms); } -static int ListGetInt(VMVa_List &tags); +int ListGetInt(VMVa_List &tags); void DCanvas::DrawTexture(FTexture *img, double x, double y, VMVa_List &args) { @@ -487,7 +487,7 @@ static void ListEnd(VMVa_List &tags) { } -static int ListGetInt(VMVa_List &tags) +int ListGetInt(VMVa_List &tags) { if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_INT) { diff --git a/src/v_text.cpp b/src/v_text.cpp index 324e22bc0..3394e448a 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -47,6 +47,8 @@ #include "doomstat.h" #include "templates.h" +int ListGetInt(VMVa_List &tags); + //========================================================================== // // DrawChar @@ -82,6 +84,42 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch } } +void DCanvas::DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args) +{ + if (font == NULL) + return; + + if (normalcolor >= NumTextColors) + normalcolor = CR_UNTRANSLATED; + + FTexture *pic; + int dummy; + + if (NULL != (pic = font->GetChar(character, &dummy))) + { + DrawParms parms; + uint32_t tag = ListGetInt(args); + bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false); + if (!res) return; + parms.remap = font->GetColorTranslation((EColorRange)normalcolor); + DrawTextureParms(pic, parms); + } +} + +DEFINE_ACTION_FUNCTION(_Screen, DrawChar) +{ + PARAM_PROLOGUE; + PARAM_POINTER(font, FFont); + PARAM_INT(cr); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_INT(chr); + + VMVa_List args = { param + 5, 0, numparam - 5 }; + screen->DrawChar(font, cr, x, y, chr, args); + return 0; +} + //========================================================================== // // DrawText @@ -90,32 +128,17 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch // //========================================================================== -void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...) +void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms) { int w; const BYTE *ch; int c; - int cx; - int cy; + double cx; + double cy; int boldcolor; FRemapTable *range; int kerning; FTexture *pic; - DrawParms parms; - - va_list tags; - - if (font == NULL || string == NULL) - return; - - va_start(tags, tag_first); - bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true); - va_end(tags); - if (!res) - { - return; - } - if (parms.celly == 0) parms.celly = font->GetHeight() + 1; parms.celly *= parms.scaley; @@ -124,15 +147,15 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s normalcolor = CR_UNTRANSLATED; boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1; - range = font->GetColorTranslation ((EColorRange)normalcolor); + range = font->GetColorTranslation((EColorRange)normalcolor); - kerning = font->GetDefaultKerning (); + kerning = font->GetDefaultKerning(); ch = (const BYTE *)string; cx = x; cy = y; - + while ((const char *)ch - string < parms.maxstrlen) { c = *ch++; @@ -141,14 +164,14 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s if (c == TEXTCOLOR_ESCAPE) { - EColorRange newcolor = V_ParseFontColor (ch, normalcolor, boldcolor); + EColorRange newcolor = V_ParseFontColor(ch, normalcolor, boldcolor); if (newcolor != CR_UNDEFINED) { - range = font->GetColorTranslation (newcolor); + range = font->GetColorTranslation(newcolor); } continue; } - + if (c == '\n') { cx = x; @@ -156,7 +179,7 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s continue; } - if (NULL != (pic = font->GetChar (c, &w))) + if (NULL != (pic = font->GetChar(c, &w))) { parms.remap = range; SetTextureParms(&parms, pic, cx, cy); @@ -172,6 +195,54 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s } } +void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...) +{ + va_list tags; + DrawParms parms; + + if (font == NULL || string == NULL) + return; + + va_start(tags, tag_first); + bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true); + va_end(tags); + if (!res) + { + return; + } + DrawTextCommon(font, normalcolor, x, y, string, parms); +} + +void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args) +{ + DrawParms parms; + + if (font == NULL || string == NULL) + return; + + uint32_t tag = ListGetInt(args); + bool res = ParseDrawTextureTags(nullptr, 0, 0, tag, args, &parms, true); + if (!res) + { + return; + } + DrawTextCommon(font, normalcolor, x, y, string, parms); +} + +DEFINE_ACTION_FUNCTION(_Screen, DrawText) +{ + PARAM_PROLOGUE; + PARAM_POINTER(font, FFont); + PARAM_INT(cr); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_STRING(chr); + + VMVa_List args = { param + 5, 0, numparam - 5 }; + screen->DrawText(font, cr, x, y, chr, args); + return 0; +} + //========================================================================== // diff --git a/src/v_video.h b/src/v_video.h index 18bb310e1..a594fa8fe 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -269,8 +269,10 @@ public: #undef DrawText // See WinUser.h for the definition of DrawText as a macro #endif // 2D Text drawing - void DrawText (FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...); - void DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); + void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...); + void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args); + void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); + void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args); protected: BYTE *Buffer; @@ -279,6 +281,8 @@ protected: int Pitch; int LockCount; + void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms); + bool ClipBox (int &left, int &top, int &width, int &height, const BYTE *&src, const int srcpitch) const; void DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) = delete; virtual void DrawTextureParms(FTexture *img, DrawParms &parms); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 57ec1b6df..802c220c9 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -66,6 +66,10 @@ struct Screen native native static int GetWidth(); native static int GetHeight(); native static void DrawHUDTexture(TextureID tex, double x, double y); + native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...); + native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...); + native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...); + } class BrokenLines : Object native @@ -357,7 +361,7 @@ struct StringStruct native { native void Replace(String pattern, String replacement); native static vararg String Format(String fmt, ...); - native vararg void AppendFormat(String fmt, ...); + native vararg void AppendFormat(String fmt, ...); } class Floor : Thinker native From 72810c969d87fd21566d6d74d2bdd5b2ede12e64 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 18:07:12 +0100 Subject: [PATCH 06/11] - added ChangeCamera script function. --- src/p_actionfunctions.cpp | 25 ++++++++++++++ wadsrc/static/zscript/actor.txt | 1 + wadsrc/static/zscript/base.txt | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index f89a560ab..c732ea18c 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -79,6 +79,7 @@ #include "thingdef.h" #include "math/cmath.h" #include "g_levellocals.h" +#include "r_utility.h" AActor *SingleActorFromTID(int tid, AActor *defactor); @@ -6913,3 +6914,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetSize) ACTION_RETURN_BOOL(true); } + +DEFINE_ACTION_FUNCTION(AActor, SetCamera) +{ + PARAM_ACTION_PROLOGUE(AActor); + PARAM_OBJECT(cam, AActor); + PARAM_BOOL_DEF(revert); + + if (self->player == nullptr || self->player->mo != self) return 0; + + if (camera == nullptr) + { + camera = self; + revert = false; + } + AActor *oldcamera = self->player->camera; + self->player->camera = camera; + if (revert) self->player->cheats |= CF_REVERTPLEASE; + + if (oldcamera != camera) + { + R_ClearPastViewer(camera); + } + return 0; +} diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 24afe68e9..9b6f42b88 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -498,6 +498,7 @@ class Actor : Thinker native native bool UsePuzzleItem(int PuzzleItemType); native float AccuracyFactor(); native bool MorphMonster (Class spawntype, int duration, int style, Class enter_flash, Class exit_flash); + native void SetCamera(Actor cam, bool revert = false); // DECORATE compatible functions native int CountInv(class itemtype, int ptr_select = AAPTR_DEFAULT); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 802c220c9..175f8341d 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -32,6 +32,64 @@ struct TexMan native static TextureID CheckForTexture(String name, int usetype, int flags = TryAny); } +enum DrawTextureTags +{ + TAG_USER = (1<<30), + DTA_Base = TAG_USER + 5000, + DTA_DestWidth, // width of area to draw to + DTA_DestHeight, // height of area to draw to + DTA_Alpha, // alpha value for translucency + DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers) + DTA_TranslationIndex, // translation table to recolor the source + DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor + DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac + DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen + DTA_Bottom320x200, // bool: same as DTA_320x200 but centers virtual screen on bottom for 1280x1024 targets + DTA_CleanNoMove, // bool: like DTA_Clean but does not reposition output position + DTA_CleanNoMove_1, // bool: like DTA_CleanNoMove, but uses Clean[XY]fac_1 instead + DTA_FlipX, // bool: flip image horizontally //FIXME: Does not work with DTA_Window(Left|Right) + DTA_ShadowColor, // color of shadow + DTA_ShadowAlpha, // alpha of shadow + DTA_Shadow, // set shadow color and alphas to defaults + DTA_VirtualWidth, // pretend the canvas is this wide + DTA_VirtualHeight, // pretend the canvas is this tall + DTA_TopOffset, // override texture's top offset + DTA_LeftOffset, // override texture's left offset + DTA_CenterOffset, // bool: override texture's left and top offsets and set them for the texture's middle + DTA_CenterBottomOffset,// bool: override texture's left and top offsets and set them for the texture's bottom middle + DTA_WindowLeft, // don't draw anything left of this column (on source, not dest) + DTA_WindowRight, // don't draw anything at or to the right of this column (on source, not dest) + DTA_ClipTop, // don't draw anything above this row (on dest, not source) + DTA_ClipBottom, // don't draw anything at or below this row (on dest, not source) + DTA_ClipLeft, // don't draw anything to the left of this column (on dest, not source) + DTA_ClipRight, // don't draw anything at or to the right of this column (on dest, not source) + DTA_Masked, // true(default)=use masks from texture, false=ignore masks + DTA_HUDRules, // use fullscreen HUD rules to position and size textures + DTA_HUDRulesC, // only used internally for marking HUD_HorizCenter + DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3 + DTA_RenderStyle, // same as render style for actors + DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software + DTA_Internal1, + DTA_Internal2, + DTA_Internal3, + DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.) + + // floating point duplicates of some of the above: + DTA_DestWidthF, + DTA_DestHeightF, + DTA_TopOffsetF, + DTA_LeftOffsetF, + DTA_VirtualWidthF, + DTA_VirtualHeightF, + DTA_WindowLeftF, + DTA_WindowRightF, + + // For DrawText calls only: + DTA_TextLen, // stop after this many characters, even if \0 not hit + DTA_CellX, // horizontal size of character cell + DTA_CellY, // vertical size of character cell +}; + struct Screen native { enum EColorRange From 481bddf6288de9c2c646fe6ee164d36511788264 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Feb 2017 11:26:17 +0200 Subject: [PATCH 07/11] Fixed incorrect offscreen rendering of player's blend --- src/gl/scene/gl_scene.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index b67cf810e..e9d6b7e1e 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -866,6 +866,14 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo // This should be done after postprocessing, not before. mBuffers->BindCurrentFB(); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); + + if (!toscreen) + { + gl_RenderState.mViewMatrix.loadIdentity(); + gl_RenderState.mProjectionMatrix.ortho(mScreenViewport.left, mScreenViewport.width, mScreenViewport.height, mScreenViewport.top, -1.0f, 1.0f); + gl_RenderState.ApplyMatrices(); + } + DrawBlend(lviewsector); } mDrawingScene2D = false; From e55406bc234f610386b0b4a4135188454ef188ff Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 18:48:49 +0100 Subject: [PATCH 08/11] - changed clean scaling factor calculation so that it doesn't prefer larger scales on high resolution displays. This was a tweak that only makes sense when the scaling factors are low, i.e. 2 vs. 3, but for modern high resolutions it will enlarge things a bit too much. --- src/v_video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 6077f878e..6d5913ce1 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1396,7 +1396,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real cy1 = MAX(cheight / designheight, 1); cx2 = MAX(realwidth / designwidth, 1); cy2 = MAX(realheight / designheight, 1); - if (abs(cx1 - cy1) <= abs(cx2 - cy2)) + if (abs(cx1 - cy1) <= abs(cx2 - cy2) || cx1 >= 4) { // e.g. 640x360 looks better with this. *cleanx = cx1; *cleany = cy1; From 810efe517df4f9228023032bc9a9b341b4dc222b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 21:38:06 +0100 Subject: [PATCH 09/11] - fixed: AActor::SetOrigin lost its 'virtual' qualifier in the ZScript merge, but ADynamicLight needs this to work properly. --- src/actor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actor.h b/src/actor.h index 652d40aa1..05b1aa076 100644 --- a/src/actor.h +++ b/src/actor.h @@ -972,7 +972,7 @@ public: { SetOrigin(Pos() + vel, true); } - void SetOrigin(double x, double y, double z, bool moving); + virtual void SetOrigin(double x, double y, double z, bool moving); void SetOrigin(const DVector3 & npos, bool moving) { SetOrigin(npos.X, npos.Y, npos.Z, moving); From a4dbbf696987747a85534fc6d194ac1829e6e0ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 21:43:16 +0100 Subject: [PATCH 10/11] - fixed P_NightmareRespawn did not respawn a map defined spawn health and neither made skill-related adjustments. --- src/p_mobj.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index df6223242..758b4ac18 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3196,6 +3196,7 @@ void P_NightmareRespawn (AActor *mobj) // spawn it mo = AActor::StaticSpawn(mobj->GetClass(), DVector3(mobj->SpawnPoint.X, mobj->SpawnPoint.Y, z), NO_REPLACE, true); + mo->health = mobj->SpawnHealth(); if (z == ONFLOORZ) { From d90f2ba1faa0a68f3d3d0c9f1b34e447f8e41287 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 21:54:09 +0100 Subject: [PATCH 11/11] - wrap the va_list that gets passed around by the Draw functions into a struct so that the templates can use reliable, identical semantics for both this and the VM's arg list. --- src/v_draw.cpp | 28 ++++++++++++++-------------- src/v_text.cpp | 12 ++++++------ src/v_video.h | 5 +++++ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 52f8cde7a..6f0e8330a 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -129,12 +129,12 @@ static int PalFromRGB(uint32 rgb) void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...) { - va_list tags; - va_start(tags, tags_first); + Va_List tags; + va_start(tags.list, tags_first); DrawParms parms; bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false); - va_end(tags); + va_end(tags.list); if (!res) { return; @@ -457,30 +457,30 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double return false; } -static void ListEnd(va_list &tags) +static void ListEnd(Va_List &tags) { - va_end(tags); + va_end(tags.list); } -static int ListGetInt(va_list &tags) +static int ListGetInt(Va_List &tags) { - return va_arg(tags, int); + return va_arg(tags.list, int); } -static inline double ListGetDouble(va_list &tags) +static inline double ListGetDouble(Va_List &tags) { - return va_arg(tags, double); + return va_arg(tags.list, double); } // These two options are only being used by the D3D version of the HUD weapon drawer, they serve no purpose anywhere else. -static inline FSpecialColormap * ListGetSpecialColormap(va_list &tags) +static inline FSpecialColormap * ListGetSpecialColormap(Va_List &tags) { - return va_arg(tags, FSpecialColormap *); + return va_arg(tags.list, FSpecialColormap *); } -static inline FColormapStyle * ListGetColormapStyle(va_list &tags) +static inline FColormapStyle * ListGetColormapStyle(Va_List &tags) { - return va_arg(tags, FColormapStyle *); + return va_arg(tags.list, FColormapStyle *); } static void ListEnd(VMVa_List &tags) @@ -946,7 +946,7 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, } // explicitly instantiate both versions for v_text.cpp. -template bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, va_list& tags, DrawParms *parms, bool fortext) const; +template bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, Va_List& tags, DrawParms *parms, bool fortext) const; template bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, VMVa_List& tags, DrawParms *parms, bool fortext) const; void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, diff --git a/src/v_text.cpp b/src/v_text.cpp index 3394e448a..8b612e83c 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -71,10 +71,10 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch if (NULL != (pic = font->GetChar (character, &dummy))) { DrawParms parms; - va_list tags; - va_start(tags, tag_first); + Va_List tags; + va_start(tags.list, tag_first); bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false); - va_end(tags); + va_end(tags.list); if (!res) { return; @@ -197,15 +197,15 @@ void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, c void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...) { - va_list tags; + Va_List tags; DrawParms parms; if (font == NULL || string == NULL) return; - va_start(tags, tag_first); + va_start(tags.list, tag_first); bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true); - va_end(tags); + va_end(tags.list); if (!res) { return; diff --git a/src/v_video.h b/src/v_video.h index a594fa8fe..a2586d5a7 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -177,6 +177,11 @@ struct DrawParms bool virtBottom; }; +struct Va_List +{ + va_list list; +}; + struct VMVa_List { VMValue *args;