From 8578a5a12e1517c342cabd1efb9ae38558e516ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 3 Feb 2017 22:56:03 +0100 Subject: [PATCH 01/20] - added a 'new' intrinsic to create new objects from inside scripts. This is not tested yet and likely to not working correctly yet. Will be fixed once I get far enough to use it later. --- src/namedef.h | 1 + src/scripting/codegeneration/codegen.cpp | 73 ++++++++++++++++++++++++ src/scripting/codegeneration/codegen.h | 21 +++++++ src/scripting/vm/vmdisasm.cpp | 1 + src/scripting/vm/vmexec.h | 8 +++ src/scripting/vm/vmops.h | 2 + 6 files changed, 106 insertions(+) diff --git a/src/namedef.h b/src/namedef.h index ef7f1c58da..2bdb74ee63 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -346,6 +346,7 @@ xx(SinH) xx(TanH) xx(ATan2) xx(VectorAngle) +xx(New) xx(Alpha) xx(Angle) xx(Args) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 8fd95c411e..e6cd1989cd 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -4918,6 +4918,70 @@ ExpEmit FxATan2::Emit(VMFunctionBuilder *build) return out; } +//========================================================================== +// +// +// +//========================================================================== +FxNew::FxNew(FxExpression *v) + : FxExpression(EFX_New, v->ScriptPosition) +{ + val = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), v, false); + ValueType = NewPointer(RUNTIME_CLASS(DObject)); +} + +//========================================================================== +// +// +// +//========================================================================== + +FxNew::~FxNew() +{ + SAFE_DELETE(val); +} + +//========================================================================== +// +// +// +//========================================================================== + +FxExpression *FxNew::Resolve(FCompileContext &ctx) +{ + CHECKRESOLVED(); + SAFE_RESOLVE(val, ctx); + + if (!val->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer))) + { + ScriptPosition.Message(MSG_ERROR, "Class type expected"); + delete this; + return nullptr; + } + if (val->isConstant()) + { + auto cls = static_cast(static_cast(val)->GetValue().GetPointer()); + ValueType = NewPointer(cls); + } + return this; +} + +//========================================================================== +// +// +// +//========================================================================== + +ExpEmit FxNew::Emit(VMFunctionBuilder *build) +{ + assert(ValueType == val->ValueType); + ExpEmit from = val->Emit(build); + from.Free(build); + ExpEmit to(build, REGT_POINTER); + build->Emit(from.Konst ? OP_NEW_K : OP_NEW, to.RegNum, from.RegNum); + return to; +} + //========================================================================== // // The atan2 opcode only takes registers as parameters, so any constants @@ -7428,6 +7492,15 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) } break; + case NAME_New: + if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition)) + { + func = new FxNew(ArgList[0]); + ArgList[0] = nullptr; + } + break; + + default: ScriptPosition.Message(MSG_ERROR, "Call to unknown function '%s'", MethodName.GetChars()); break; diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index 42d5b0ccfd..69ad192f58 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -242,6 +242,7 @@ enum EFxType EFX_Conditional, EFX_Abs, EFX_ATan2, + EFX_New, EFX_MinMax, EFX_Random, EFX_RandomPick, @@ -1176,6 +1177,26 @@ public: private: ExpEmit ToReg(VMFunctionBuilder *build, FxExpression *val); }; + +//========================================================================== +// +// +// +//========================================================================== + +class FxNew : public FxExpression +{ + FxExpression *val; + +public: + + FxNew(FxExpression *v); + ~FxNew(); + FxExpression *Resolve(FCompileContext&); + + ExpEmit Emit(VMFunctionBuilder *build); +}; + //========================================================================== // // diff --git a/src/scripting/vm/vmdisasm.cpp b/src/scripting/vm/vmdisasm.cpp index d21e38d207..276533e2d1 100644 --- a/src/scripting/vm/vmdisasm.cpp +++ b/src/scripting/vm/vmdisasm.cpp @@ -72,6 +72,7 @@ #define RFRF MODE_AF | MODE_BF | MODE_CUNUSED #define RSRS MODE_AS | MODE_BS | MODE_CUNUSED #define RPRP MODE_AP | MODE_BP | MODE_CUNUSED +#define RPKP MODE_AP | MODE_BKP | MODE_CUNUSED #define RXRXI8 MODE_AX | MODE_BX | MODE_CIMMZ #define RPRPRP MODE_AP | MODE_BP | MODE_CP #define RPRPKP MODE_AP | MODE_BP | MODE_CKP diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index d916658d73..fc6a53bee1 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -759,6 +759,14 @@ begin: assert(0); NEXTOP; + OP(NEW_K): + OP(NEW): + { + PClass *cls = (PClass*)(op == OP_NEW ? reg.a[C] : konsta[C].v); + reg.a[B] = cls->CreateNew(); + NEXTOP; + } + OP(TRY): assert(try_depth < MAX_TRY_DEPTH); if (try_depth >= MAX_TRY_DEPTH) diff --git a/src/scripting/vm/vmops.h b/src/scripting/vm/vmops.h index 0829ab2c65..86554940ea 100644 --- a/src/scripting/vm/vmops.h +++ b/src/scripting/vm/vmops.h @@ -104,6 +104,8 @@ xx(TAIL_K, tail, KPI8, TAIL, 1, REGT_POINTER), xx(RESULT, result, __BCP, NOP, 0, 0), // Result should go in register encoded in BC (in caller, after CALL) xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to return value A, possibly returning xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning +xx(NEW, new, RPRP, NOP, 0, 0), +xx(NEW_K, new, RPKP, NOP, 0, 0), xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB From d5b908186c5c454eb52f8923226acbcd9069b753 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 00:19:25 +0100 Subject: [PATCH 02/20] - some work on the base classes for menus. None of this is being used yet. --- src/menu/listmenu.cpp | 42 ++++++------- src/menu/menu.h | 40 ++++++------- src/menu/menudef.cpp | 18 +++--- src/menu/optionmenuitems.h | 4 +- src/menu/playerdisplay.cpp | 3 +- src/menu/playermenu.cpp | 38 ++++++------ src/v_font.h | 3 +- wadsrc/static/zscript.txt | 3 + wadsrc/static/zscript/base.txt | 29 +++++++++ wadsrc/static/zscript/menu/menu.txt | 17 ++++++ wadsrc/static/zscript/menu/menuitembase.txt | 66 +++++++++++++++++++++ 11 files changed, 189 insertions(+), 74 deletions(-) create mode 100644 wadsrc/static/zscript/menu/menu.txt create mode 100644 wadsrc/static/zscript/menu/menuitembase.txt diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 03223b6a7c..4605246bd9 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -101,7 +101,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) // //============================================================================= -DListMenuItem *DListMenu::GetItem(FName name) +DMenuItemBase *DListMenu::GetItem(FName name) { for(unsigned i=0;imItems.Size(); i++) { @@ -274,27 +274,27 @@ void DListMenu::Drawer () // base class for menu items // //============================================================================= -IMPLEMENT_CLASS(DListMenuItem, true, false) +IMPLEMENT_CLASS(DMenuItemBase, true, false) -bool DListMenuItem::CheckCoordinate(int x, int y) +bool DMenuItemBase::CheckCoordinate(int x, int y) { return false; } -void DListMenuItem::Ticker() +void DMenuItemBase::Ticker() { } -void DListMenuItem::Drawer(bool selected) +void DMenuItemBase::Drawer(bool selected) { } -bool DListMenuItem::Selectable() +bool DMenuItemBase::Selectable() { return false; } -void DListMenuItem::DrawSelector(int xofs, int yofs, FTextureID tex) +void DMenuItemBase::DrawSelector(int xofs, int yofs, FTextureID tex) { if (tex.isNull()) { @@ -315,57 +315,57 @@ void DListMenuItem::DrawSelector(int xofs, int yofs, FTextureID tex) } } -bool DListMenuItem::Activate() +bool DMenuItemBase::Activate() { return false; // cannot be activated } -FName DListMenuItem::GetAction(int *pparam) +FName DMenuItemBase::GetAction(int *pparam) { return mAction; } -bool DListMenuItem::SetString(int i, const char *s) +bool DMenuItemBase::SetString(int i, const char *s) { return false; } -bool DListMenuItem::GetString(int i, char *s, int len) +bool DMenuItemBase::GetString(int i, char *s, int len) { return false; } -bool DListMenuItem::SetValue(int i, int value) +bool DMenuItemBase::SetValue(int i, int value) { return false; } -bool DListMenuItem::GetValue(int i, int *pvalue) +bool DMenuItemBase::GetValue(int i, int *pvalue) { return false; } -void DListMenuItem::Enable(bool on) +void DMenuItemBase::Enable(bool on) { mEnabled = on; } -bool DListMenuItem::MenuEvent(int mkey, bool fromcontroller) +bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller) { return false; } -bool DListMenuItem::MouseEvent(int type, int x, int y) +bool DMenuItemBase::MouseEvent(int type, int x, int y) { return false; } -bool DListMenuItem::CheckHotkey(int c) +bool DMenuItemBase::CheckHotkey(int c) { return false; } -int DListMenuItem::GetWidth() +int DMenuItemBase::GetWidth() { return 0; } @@ -379,7 +379,7 @@ int DListMenuItem::GetWidth() IMPLEMENT_CLASS(DListMenuItemStaticPatch, false, false) DListMenuItemStaticPatch::DListMenuItemStaticPatch(int x, int y, FTextureID patch, bool centered) -: DListMenuItem(x, y) +: DMenuItemBase(x, y) { mTexture = patch; mCentered = centered; @@ -415,7 +415,7 @@ void DListMenuItemStaticPatch::Drawer(bool selected) IMPLEMENT_CLASS(DListMenuItemStaticText, false, false) DListMenuItemStaticText::DListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered) -: DListMenuItem(x, y) +: DMenuItemBase(x, y) { mText = text; mFont = font; @@ -452,7 +452,7 @@ void DListMenuItemStaticText::Drawer(bool selected) IMPLEMENT_CLASS(DListMenuItemSelectable, false, false) DListMenuItemSelectable::DListMenuItemSelectable(int x, int y, int height, FName action, int param) -: DListMenuItem(x, y, action) +: DMenuItemBase(x, y, action) { mHeight = height; mParam = param; diff --git a/src/menu/menu.h b/src/menu/menu.h index 24833f280d..e789604a82 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -92,12 +92,12 @@ struct FMenuDescriptor virtual size_t PropagateMark() { return 0; } }; -class DListMenuItem; +class DMenuItemBase; class DOptionMenuItem; struct FListMenuDescriptor : public FMenuDescriptor { - TArray mItems; + TArray mItems; int mSelectedItem; int mSelectOfsX; int mSelectOfsY; @@ -255,9 +255,9 @@ public: // //============================================================================= -class DListMenuItem : public DObject +class DMenuItemBase : public DObject { - DECLARE_CLASS(DListMenuItem, DObject) + DECLARE_CLASS(DMenuItemBase, DObject) protected: int mXpos, mYpos; FName mAction; @@ -265,7 +265,7 @@ protected: public: bool mEnabled; - DListMenuItem(int xpos = 0, int ypos = 0, FName action = NAME_None) + DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None) { mXpos = xpos; mYpos = ypos; @@ -295,9 +295,9 @@ public: void SetX(int x) { mXpos = x; } }; -class DListMenuItemStaticPatch : public DListMenuItem +class DListMenuItemStaticPatch : public DMenuItemBase { - DECLARE_CLASS(DListMenuItemStaticPatch, DListMenuItem) + DECLARE_CLASS(DListMenuItemStaticPatch, DMenuItemBase) protected: FTextureID mTexture; bool mCentered; @@ -308,9 +308,9 @@ public: void Drawer(bool selected); }; -class DListMenuItemStaticText : public DListMenuItem +class DListMenuItemStaticText : public DMenuItemBase { - DECLARE_CLASS(DListMenuItemStaticText, DListMenuItem) + DECLARE_CLASS(DListMenuItemStaticText, DMenuItemBase) protected: FString mText; FFont *mFont; @@ -329,9 +329,9 @@ public: // //============================================================================= -class DListMenuItemPlayerDisplay : public DListMenuItem +class DListMenuItemPlayerDisplay : public DMenuItemBase { - DECLARE_CLASS(DListMenuItemPlayerDisplay, DListMenuItem) + DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase) FListMenuDescriptor *mOwner; FTexture *mBackdrop; @@ -379,9 +379,9 @@ public: // //============================================================================= -class DListMenuItemSelectable : public DListMenuItem +class DListMenuItemSelectable : public DMenuItemBase { - DECLARE_CLASS(DListMenuItemSelectable, DListMenuItem) + DECLARE_CLASS(DListMenuItemSelectable, DMenuItemBase) protected: int mHotkey; int mHeight; @@ -523,22 +523,22 @@ class DListMenu : public DMenu protected: FListMenuDescriptor *mDesc; - DListMenuItem *mFocusControl; + DMenuItemBase *mFocusControl; public: DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - DListMenuItem *GetItem(FName name); + DMenuItemBase *GetItem(FName name); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); void Ticker (); void Drawer (); - void SetFocus(DListMenuItem *fc) + void SetFocus(DMenuItemBase *fc) { mFocusControl = fc; } - bool CheckFocus(DListMenuItem *fc) + bool CheckFocus(DMenuItemBase *fc) { return mFocusControl == fc; } @@ -555,9 +555,9 @@ public: // //============================================================================= -class DOptionMenuItem : public DListMenuItem +class DOptionMenuItem : public DMenuItemBase { - DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DListMenuItem) + DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase) protected: FString mLabel; bool mCentered; @@ -566,7 +566,7 @@ protected: public: DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false) - : DListMenuItem(0, 0, action) + : DMenuItemBase(0, 0, action) { mLabel = text; mCentered = center; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index a8822470f8..08e44fbabc 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -294,7 +294,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.MustGetString(); FTextureID tex = GetMenuTexture(sc.String); - DListMenuItem *it = new DListMenuItemStaticPatch(x, y, tex, centered); + DMenuItemBase *it = new DListMenuItemStaticPatch(x, y, tex, centered); desc->mItems.Push(it); } else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) @@ -315,7 +315,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) cr = V_FindFontColor(sc.String); if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated")) cr = desc->mFontColor; } - DListMenuItem *it = new DListMenuItemStaticText(x, y, label, desc->mFont, cr, centered); + DMenuItemBase *it = new DListMenuItemStaticText(x, y, label, desc->mFont, cr, centered); desc->mItems.Push(it); } else if (sc.Compare("PatchItem")) @@ -335,7 +335,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) param = sc.Number; } - DListMenuItem *it = new DListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); + DMenuItemBase *it = new DListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; @@ -357,7 +357,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) param = sc.Number; } - DListMenuItem *it = new DListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); + DMenuItemBase *it = new DListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; @@ -426,7 +426,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) int ofs = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); - DListMenuItem *it = new DPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String); + DMenuItemBase *it = new DPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; @@ -444,7 +444,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.MustGetString(); values = sc.String; } - DListMenuItem *it = new DValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values); + DMenuItemBase *it = new DValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; @@ -465,7 +465,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.MustGetStringName(","); sc.MustGetNumber(); int step = sc.Number; - DListMenuItem *it = new DSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step); + DMenuItemBase *it = new DSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; @@ -1081,7 +1081,7 @@ static void BuildEpisodeMenu() ld->mSelectedItem = ld->mItems.Size(); for(unsigned i = 0; i < AllEpisodes.Size(); i++) { - DListMenuItem *it; + DMenuItemBase *it; if (AllEpisodes[i].mPicName.IsNotEmpty()) { FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); @@ -1465,7 +1465,7 @@ void M_StartupSkillMenu(FGameStartup *gs) for(unsigned int i = 0; i < AllSkills.Size(); i++) { FSkillInfo &skill = AllSkills[i]; - DListMenuItem *li; + DMenuItemBase *li; // Using a different name for skills that must be confirmed makes handling this easier. FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? NAME_StartgameConfirm : NAME_Startgame; diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 0acaea9ccc..b1821eebf7 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -402,7 +402,7 @@ public: if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) { DOptionMenu *m = barrier_cast(mParentMenu); - DListMenuItem *it = m->GetItem(NAME_Controlmessage); + DMenuItemBase *it = m->GetItem(NAME_Controlmessage); if (it != NULL) { it->SetValue(0, which); @@ -1242,7 +1242,7 @@ IMPLEMENT_CLASS(DOptionMenuTextField, false, false) //============================================================================= // -// [TP] DOptionMenuNumberField +// [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) diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index bba255bcfd..aaec6fba3b 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -355,9 +355,8 @@ void FBackdropTexture::Render() // //============================================================================= IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false) - DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action) -: DListMenuItem(x, y, action) +: DMenuItemBase(x, y, action) { mOwner = menu; diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index ea2489e9c2..7116608b34 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -499,11 +499,11 @@ class DPlayerMenu : public DListMenu void UpdateTranslation(); void SendNewColor (int red, int green, int blue); - void PlayerNameChanged(DListMenuItem *li); - void ColorSetChanged (DListMenuItem *li); - void ClassChanged (DListMenuItem *li); - void AutoaimChanged (DListMenuItem *li); - void SkinChanged (DListMenuItem *li); + void PlayerNameChanged(DMenuItemBase *li); + void ColorSetChanged (DMenuItemBase *li); + void ClassChanged (DMenuItemBase *li); + void AutoaimChanged (DMenuItemBase *li); + void SkinChanged (DMenuItemBase *li); public: @@ -527,7 +527,7 @@ IMPLEMENT_CLASS(DPlayerMenu, false, false) void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc) { - DListMenuItem *li; + DMenuItemBase *li; Super::Init(parent, desc); PickPlayerClass(); @@ -655,7 +655,7 @@ bool DPlayerMenu::Responder (event_t *ev) { // turn the player sprite around mRotation = 8 - mRotation; - DListMenuItem *li = GetItem(NAME_Playerdisplay); + DMenuItemBase *li = GetItem(NAME_Playerdisplay); if (li != NULL) { li->SetValue(DListMenuItemPlayerDisplay::PDF_ROTATION, mRotation); @@ -745,7 +745,7 @@ void DPlayerMenu::SendNewColor (int red, int green, int blue) void DPlayerMenu::UpdateColorsets() { - DListMenuItem *li = GetItem(NAME_Color); + DMenuItemBase *li = GetItem(NAME_Color); if (li != NULL) { int sel = 0; @@ -781,7 +781,7 @@ void DPlayerMenu::UpdateSkins() { int sel = 0; int skin; - DListMenuItem *li = GetItem(NAME_Skin); + DMenuItemBase *li = GetItem(NAME_Skin); if (li != NULL) { if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || @@ -824,7 +824,7 @@ void DPlayerMenu::UpdateSkins() // //============================================================================= -void DPlayerMenu::PlayerNameChanged(DListMenuItem *li) +void DPlayerMenu::PlayerNameChanged(DMenuItemBase *li) { char pp[MAXPLAYERNAME+1]; const char *p; @@ -852,7 +852,7 @@ void DPlayerMenu::PlayerNameChanged(DListMenuItem *li) // //============================================================================= -void DPlayerMenu::ColorSetChanged (DListMenuItem *li) +void DPlayerMenu::ColorSetChanged (DMenuItemBase *li) { int sel; @@ -862,9 +862,9 @@ void DPlayerMenu::ColorSetChanged (DListMenuItem *li) if (sel > 0) mycolorset = PlayerColorSets[sel-1]; - DListMenuItem *red = GetItem(NAME_Red); - DListMenuItem *green = GetItem(NAME_Green); - DListMenuItem *blue = GetItem(NAME_Blue); + DMenuItemBase *red = GetItem(NAME_Red); + DMenuItemBase *green = GetItem(NAME_Green); + DMenuItemBase *blue = GetItem(NAME_Blue); // disable the sliders if a valid colorset is selected if (red != NULL) red->Enable(mycolorset == -1); @@ -885,7 +885,7 @@ void DPlayerMenu::ColorSetChanged (DListMenuItem *li) // //============================================================================= -void DPlayerMenu::ClassChanged (DListMenuItem *li) +void DPlayerMenu::ClassChanged (DMenuItemBase *li) { if (PlayerClasses.Size () == 1) { @@ -919,7 +919,7 @@ void DPlayerMenu::ClassChanged (DListMenuItem *li) // //============================================================================= -void DPlayerMenu::SkinChanged (DListMenuItem *li) +void DPlayerMenu::SkinChanged (DMenuItemBase *li) { if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || players[consoleplayer].userinfo.GetPlayerClassNum() == -1) @@ -950,7 +950,7 @@ void DPlayerMenu::SkinChanged (DListMenuItem *li) // //============================================================================= -void DPlayerMenu::AutoaimChanged (DListMenuItem *li) +void DPlayerMenu::AutoaimChanged (DMenuItemBase *li) { int sel; @@ -971,7 +971,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller) int v; if (mDesc->mSelectedItem >= 0) { - DListMenuItem *li = mDesc->mItems[mDesc->mSelectedItem]; + DMenuItemBase *li = mDesc->mItems[mDesc->mSelectedItem]; if (li->MenuEvent(mkey, fromcontroller)) { FName current = li->GetAction(NULL); @@ -1067,7 +1067,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller) bool DPlayerMenu::MouseEvent(int type, int x, int y) { int v; - DListMenuItem *li = mFocusControl; + DMenuItemBase *li = mFocusControl; bool res = Super::MouseEvent(type, x, y); if (li == NULL) li = mFocusControl; if (li != NULL) diff --git a/src/v_font.h b/src/v_font.h index 7523e6bf05..b31c51471b 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -66,7 +66,8 @@ enum EColorRange CR_PURPLE, CR_DARKGRAY, CR_CYAN, - NUM_TEXT_COLORS + NUM_TEXT_COLORS, + FORCE_DWORD = 0x7fffffff // required for script access. }; extern int NumTextColors; diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 7cd9722bc8..16b7b52541 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -6,6 +6,9 @@ #include "zscript/actor.txt" #include "zscript/actor_checks.txt" +#include "zscript/menu/menu.txt" +#include "zscript/menu/menuitembase.txt" + #include "zscript/inventory/inventory.txt" #include "zscript/inventory/inv_misc.txt" #include "zscript/inventory/stateprovider.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index a1177289e7..73909e83de 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -34,6 +34,35 @@ struct TexMan struct Screen native { + enum EColorRange + { + CR_UNDEFINED = -1, + CR_BRICK, + CR_TAN, + CR_GRAY, + CR_GREY = CR_GRAY, + CR_GREEN, + CR_BROWN, + CR_GOLD, + CR_RED, + CR_BLUE, + CR_ORANGE, + CR_WHITE, + CR_YELLOW, + CR_UNTRANSLATED, + CR_BLACK, + CR_LIGHTBLUE, + CR_CREAM, + CR_OLIVE, + CR_DARKGREEN, + CR_DARKRED, + CR_DARKBROWN, + CR_PURPLE, + CR_DARKGRAY, + CR_CYAN, + NUM_TEXT_COLORS + }; + native static void DrawHUDTexture(TextureID tex, double x, double y); } diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt new file mode 100644 index 0000000000..ffada31983 --- /dev/null +++ b/wadsrc/static/zscript/menu/menu.txt @@ -0,0 +1,17 @@ + +class Menu : Object native +{ + //native static int MenuTime(); +} + +struct FOptionMenuSettings +{ + int mTitleColor; + int mFontColor; + int mFontColorValue; + int mFontColorMore; + int mFontColorHeader; + int mFontColorHighlight; + int mFontColorSelection; + int mLinespacing; +} diff --git a/wadsrc/static/zscript/menu/menuitembase.txt b/wadsrc/static/zscript/menu/menuitembase.txt new file mode 100644 index 0000000000..e92f17fcf4 --- /dev/null +++ b/wadsrc/static/zscript/menu/menuitembase.txt @@ -0,0 +1,66 @@ +//============================================================================= +// +// base class for menu items +// +//============================================================================= + +class MenuItemBase : Object native +{ + protected int mXpos, mYpos; + protected Name mAction; + + bool mEnabled; + + protected void Init(int xpos = 0, int ypos = 0, Name actionname = 'None') + { + mXpos = xpos; + mYpos = ypos; + mAction = actionname; + mEnabled = true; + } + + virtual bool CheckCoordinate(int x, int y) { return false; } + virtual void Ticker() {} + virtual void Drawer(bool selected) {} + virtual bool Selectable() {return false; } + virtual bool Activate() { return false; } + virtual Name, int GetAction() { return mAction, 0; } + virtual bool SetString(int i, String s) { return false; } + virtual bool, String GetString(int i) { return false, ""; } + virtual bool SetValue(int i, int value) { return false; } + virtual bool, int GetValue(int i) { return false, 0; } + virtual void Enable(bool on) { mEnabled = on; } + virtual bool MenuEvent (int mkey, bool fromcontroller) { return false; } + virtual bool MouseEvent(int type, int x, int y) { return false; } + virtual bool CheckHotkey(int c) { return false; } + virtual int GetWidth() { return 0; } + virtual void OffsetPositionY(int ydelta) { mYpos += ydelta; } + virtual int GetY() { return mYpos; } + virtual int GetX() { return mXpos; } + virtual void SetX(int x) { mXpos = x; } + + /* + virtual void DrawSelector(int xofs, int yofs, TextureID tex) + { + if (tex.isNull()) + { + if ((Menu.MenuTime() % 8) < 6) + { + screen.DrawText(ConFont, OptionSettings.mFontColorSelection, + (mXpos + xofs - 160) * CleanXfac + screen.GetWidth() / 2, + (mYpos + yofs - 100) * CleanYfac + screen.GetHeight() / 2, + "\xd", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); + } + } + else + { + screen.DrawTexture (tex, mXpos + xofs, mYpos + yofs, DTA_Clean, true, TAG_DONE); + } + } + */ + +} + From abac75628987022a906c380ddb27d104600fcc59 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 00:46:22 +0100 Subject: [PATCH 03/20] - exported some stuff for fonts and screen size that will be needed for the menus. --- src/scripting/thingdef_data.cpp | 46 +++++++++++++++++++++++---------- src/v_draw.cpp | 11 ++++++++ src/v_font.cpp | 7 +++++ wadsrc/static/zscript/base.txt | 7 +++++ 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 421ef6ae5a..9c36f0e499 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -53,6 +53,7 @@ #include "vm.h" #include "p_checkposition.h" #include "r_sky.h" +#include "v_font.h" static TArray properties; static TArray AFTable; @@ -801,34 +802,51 @@ void InitThingdef() pstruct->Size = sizeof(player_t); pstruct->Align = alignof(player_t); PArray *parray = NewArray(pstruct, MAXPLAYERS); - PField *playerf = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); pstruct->AddNativeField("weapons", NewNativeStruct("WeaponSlots", nullptr), myoffsetof(player_t, weapons), VARF_Native); parray = NewArray(TypeBool, MAXPLAYERS); - playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - playerf = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - playerf = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + auto fontptr = NewPointer(NewNativeStruct("Font", nullptr)); + + fieldptr = new PField("smallfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + fieldptr = new PField("smallfont2", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont2); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + fieldptr = new PField("bigfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BigFont); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + fieldptr = new PField("confont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&ConFont); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + fieldptr = new PField("intermissionfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&IntermissionFont); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); // Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag. // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution' // is to create a static variable from it and reference that in the script. Yuck!!! static AWeapon *wpnochg = WP_NOCHANGE; - playerf = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg); - Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf); + fieldptr = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. for (auto &fl : FlagLists) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 9db885efbd..cf1e4c6881 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -91,6 +91,17 @@ CVAR (Bool, hud_scale, true, CVAR_ARCHIVE); static int LastPal = -1; static uint32 LastRGB; +DEFINE_ACTION_FUNCTION(_Screen, GetWidth) +{ + PARAM_PROLOGUE; + ACTION_RETURN_INT(screen->GetWidth()); +} + +DEFINE_ACTION_FUNCTION(_Screen, GetHeight) +{ + PARAM_PROLOGUE; + ACTION_RETURN_INT(screen->GetHeight()); +} static int PalFromRGB(uint32 rgb) { diff --git a/src/v_font.cpp b/src/v_font.cpp index f024e2d2ba..2854be8c2b 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -525,6 +525,13 @@ FFont *FFont::FindFont (const char *name) return font; } +DEFINE_ACTION_FUNCTION(FFont, FindFont) +{ + PARAM_PROLOGUE; + PARAM_STRING(name); + ACTION_RETURN_POINTER(FFont::FindFont(name)); +} + //========================================================================== // // RecordTextureColors diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 73909e83de..b84d72a51a 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -63,9 +63,16 @@ struct Screen native NUM_TEXT_COLORS }; + native static int GetWidth(); + native static int GetHeight(); native static void DrawHUDTexture(TextureID tex, double x, double y); } +struct Font native +{ + native static Font FindFont(String name); +} + struct Console native { native static void HideConsole(); From d3ed83942f9b5c3b3727d64b4d0bf9e6c4ca86df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 13:11:12 +0100 Subject: [PATCH 04/20] - did some preparations to ParseDrawTextureTags to allow using the same code for parsing tag lists generated by the VM. - removed the fixed point alpha tag from DrawTexture and replaced all uses with the floating point version. --- src/am_map.cpp | 2 +- src/c_console.cpp | 14 +-- src/g_shared/hudmessages.cpp | 24 +++--- src/g_shared/shared_hud.cpp | 24 +++--- src/g_statusbar/sbarinfo.cpp | 12 +-- src/g_statusbar/strife_sbar.cpp | 20 ++--- src/intermission/intermission.cpp | 2 +- src/menu/menu.cpp | 2 +- src/menu/readthis.cpp | 2 +- src/p_conversation.cpp | 4 +- src/r_things.cpp | 2 +- src/v_draw.cpp | 139 ++++++++++++++++++------------ src/v_video.h | 3 +- src/wi_stuff.cpp | 2 +- 14 files changed, 139 insertions(+), 113 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index fad6a13ac9..19f10f0675 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2935,7 +2935,7 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust, DTA_ClipRight, f_x + f_w, DTA_FlipX, flip, DTA_Translation, TranslationToTable(translation), - DTA_AlphaF, alpha, + DTA_Alpha, alpha, DTA_FillColor, fillcolor, DTA_RenderStyle, DWORD(renderstyle), TAG_DONE); diff --git a/src/c_console.cpp b/src/c_console.cpp index a9cd975579..4340cc3f88 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1003,23 +1003,23 @@ void FNotifyBuffer::Draw() { if (!center) screen->DrawText (SmallFont, color, 0, line, notify.Text, - DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE); + DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - SmallFont->StringWidth (notify.Text)*CleanXfac)/2, line, notify.Text, DTA_CleanNoMove, true, - DTA_AlphaF, alpha, TAG_DONE); + DTA_Alpha, alpha, TAG_DONE); } else if (active_con_scaletext() == 1) { if (!center) screen->DrawText (SmallFont, color, 0, line, notify.Text, - DTA_AlphaF, alpha, TAG_DONE); + DTA_Alpha, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - SmallFont->StringWidth (notify.Text))/2, line, notify.Text, - DTA_AlphaF, alpha, TAG_DONE); + DTA_Alpha, alpha, TAG_DONE); } else { @@ -1028,7 +1028,7 @@ void FNotifyBuffer::Draw() DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_KeepRatio, true, - DTA_AlphaF, alpha, TAG_DONE); + DTA_Alpha, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (screen->GetWidth() - SmallFont->StringWidth (notify.Text) * active_con_scaletext()) / 2 / active_con_scaletext(), @@ -1036,7 +1036,7 @@ void FNotifyBuffer::Draw() DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_KeepRatio, true, - DTA_AlphaF, alpha, TAG_DONE); + DTA_Alpha, alpha, TAG_DONE); } line += lineadv; canskip = false; @@ -1117,7 +1117,7 @@ void C_DrawConsole (bool hw2d) DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), DTA_ColorOverlay, conshade, - DTA_AlphaF, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., + DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., DTA_Masked, false, TAG_DONE); if (conline && visheight < screen->GetHeight()) diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 0db6d4743a..86ddc4bfd5 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -457,7 +457,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -466,7 +466,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -481,7 +481,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -560,7 +560,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -569,7 +569,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -584,7 +584,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -660,7 +660,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -669,7 +669,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH / active_con_scaletext(), DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -684,7 +684,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_AlphaF, trans, + DTA_Alpha, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -842,7 +842,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, DTA_TextLen, LineVisible, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -853,7 +853,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in DTA_VirtualHeight, SCREENHEIGHT / active_con_scaletext(), DTA_KeepRatio, true, DTA_TextLen, LineVisible, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -867,7 +867,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_TextLen, LineVisible, DTA_RenderStyle, Style, TAG_DONE); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 37312748c0..4ab0c81338 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -138,7 +138,7 @@ void SetHUDIcon(PClassInventory *cls, FTextureID tex) // center of the box. The image is scaled down if it doesn't fit // //--------------------------------------------------------------------------- -static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans=0xc000) +static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, double trans = 0.75) { double scale1, scale2; @@ -174,7 +174,7 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans // //--------------------------------------------------------------------------- -static void DrawHudText(FFont *font, int color, char * text, int x, int y, int trans=0xc000) +static void DrawHudText(FFont *font, int color, char * text, int x, int y, double trans = 0.75) { int zerowidth; FTexture *tex_zero = font->GetChar('0', &zerowidth); @@ -207,7 +207,7 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, int t // //--------------------------------------------------------------------------- -static void DrawHudNumber(FFont *font, int color, int num, int x, int y, int trans=0xc000) +static void DrawHudNumber(FFont *font, int color, int num, int x, int y, double trans = 0.75) { char text[15]; @@ -227,11 +227,11 @@ static void DrawStatLine(int x, int &y, const char *prefix, const char *string) y -= SmallFont->GetHeight()-1; screen->DrawText(SmallFont, hudcolor_statnames, x, y, prefix, DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.75, TAG_DONE); screen->DrawText(SmallFont, hudcolor_stats, x+statspace, y, string, DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE); + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.75, TAG_DONE); } static void DrawStatus(player_t * CPlayer, int x, int y) @@ -654,7 +654,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) FTextureID icon = !AltIcon.isNull()? AltIcon : inv->Icon; if (!icon.isValid()) continue; - int trans= (wi && (type==wi->AmmoType1 || type==wi->AmmoType2)) ? 0xc000:0x6000; + double trans= (wi && (type==wi->AmmoType1 || type==wi->AmmoType2)) ? 0.75 : 0.375; int maxammo = inv->MaxAmount; int ammo = ammoitem? ammoitem->Amount : 0; @@ -731,16 +731,16 @@ FTextureID GetInventoryIcon(AInventory *item, DWORD flags, bool *applyscale=NULL static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) { - int trans; + double trans; // Powered up weapons and inherited sister weapons are not displayed. if (weapon->WeaponFlags & WIF_POWERED_UP) return; if (weapon->SisterWeapon && weapon->IsKindOf(weapon->SisterWeapon->GetClass())) return; - trans=0x6666; + trans=0.4; if (CPlayer->ReadyWeapon) { - if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999; + if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans = 0.85; } FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST); @@ -809,7 +809,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y) { screen->DrawTexture(invgems[!!(level.time&4)], x-10, y, DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0x6666, TAG_DONE); + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE); } for(i=0;iNextInv()) @@ -820,7 +820,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y) if (AltIcon.Exists() && (rover->Icon.isValid() || AltIcon.isValid()) ) { - int trans = rover==CPlayer->mo->InvSel ? 0x10000 : 0x6666; + double trans = rover==CPlayer->mo->InvSel ? 1.0 : 0.4; DrawImageToBox(TexMan[AltIcon.isValid()? AltIcon : rover->Icon], x, y, 19, 25, trans); if (rover->Amount>1) @@ -845,7 +845,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y) { screen->DrawTexture(invgems[2 + !!(level.time&4)], x-10, y, DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0x6666, TAG_DONE); + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE); } } } diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index d6e5f6dbf3..33b47f15de 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1270,7 +1270,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_AlphaChannel, alphaMap, DTA_FillColor, 0, TAG_DONE); @@ -1287,7 +1287,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, TAG_DONE); } } @@ -1347,7 +1347,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, DTA_AlphaChannel, alphaMap, DTA_FillColor, 0, TAG_DONE); @@ -1364,7 +1364,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, TAG_DONE); } } @@ -1487,7 +1487,7 @@ public: screen->DrawTexture(character, srx, sry, DTA_DestWidthF, rw, DTA_DestHeightF, rh, - DTA_AlphaF, salpha, + DTA_Alpha, salpha, DTA_FillColor, 0, TAG_DONE); } @@ -1495,7 +1495,7 @@ public: DTA_DestWidthF, rw, DTA_DestHeightF, rh, DTA_Translation, remap, - DTA_AlphaF, Alpha, + DTA_Alpha, Alpha, TAG_DONE); if(script->spacingCharacter == '\0') ax += width + spacing - (character->LeftOffset+1); diff --git a/src/g_statusbar/strife_sbar.cpp b/src/g_statusbar/strife_sbar.cpp index d2511c42de..4ce1cf1985 100644 --- a/src/g_statusbar/strife_sbar.cpp +++ b/src/g_statusbar/strife_sbar.cpp @@ -451,7 +451,7 @@ private: screen->DrawTexture (Images[CursorImage], 42 + 35*i + ST_X, 12 + ST_Y, DTA_Bottom320x200, Scaled, - DTA_AlphaF, 1. - ItemFlash, + DTA_Alpha, 1. - ItemFlash, TAG_DONE); } if (item->Icon.isValid()) @@ -523,7 +523,7 @@ private: DTA_HUDRules, HUD_Normal, DTA_LeftOffset, cursor->GetWidth(), DTA_TopOffset, cursor->GetHeight(), - DTA_AlphaF, ItemFlash, + DTA_Alpha, ItemFlash, TAG_DONE); } DrINumberOuter (CPlayer->mo->InvSel->Amount, -51, -10, false, 7); @@ -547,7 +547,7 @@ private: { screen->DrawTexture (Images[CursorImage], -100+i*35, -21, DTA_HUDRules, HUD_HorizCenter, - DTA_Alpha, TRANSLUC75, + DTA_Alpha, 0.75, TAG_DONE); } if (item->Icon.isValid()) @@ -580,7 +580,7 @@ private: left = screen->GetWidth()/2 - 160*CleanXfac; top = bottom + height * yscale; - screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_AlphaF, 0.75, TAG_DONE); + screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, 0.75, TAG_DONE); screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE); @@ -874,7 +874,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center, else if (val == 0) { screen->DrawTexture(Images[imgINumbers], x + 1, y + 1, - DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, + DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); screen->DrawTexture(Images[imgINumbers], x, y, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); @@ -888,7 +888,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center, while (val != 0) { screen->DrawTexture(Images[imgINumbers + val % 10], x + 1, y + 1, - DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, + DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); x -= w; val /= 10; @@ -896,7 +896,7 @@ void DStrifeStatusBar::DrINumberOuter(signed int val, int x, int y, bool center, if (negative) { screen->DrawTexture(Images[imgNEGATIVE], x + 1, y + 1, - DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, + DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); } @@ -947,7 +947,7 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size pic = BigFont->GetChar('0', &v); screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_AlphaF, HR_SHADOW, + DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); @@ -972,7 +972,7 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size pic = BigFont->GetChar('0' + val % 10, &v); screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_AlphaF, HR_SHADOW, + DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); @@ -986,7 +986,7 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size { screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_AlphaF, HR_SHADOW, + DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 2612bdd63d..9c3353b60c 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -630,7 +630,7 @@ void DIntermissionScreenCast::Drawer () DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y, DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, DTA_RenderStyle, mDefaults->RenderStyle, - DTA_AlphaF, mDefaults->Alpha, + DTA_Alpha, mDefaults->Alpha, DTA_Translation, casttranslation, TAG_DONE); } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index acec65f902..c047a145da 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -305,7 +305,7 @@ void DMenu::Drawer () } else { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_AlphaF, BackbuttonAlpha, TAG_DONE); + screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); } } } diff --git a/src/menu/readthis.cpp b/src/menu/readthis.cpp index f1e82cd515..06d4620da1 100644 --- a/src/menu/readthis.cpp +++ b/src/menu/readthis.cpp @@ -105,7 +105,7 @@ void DReadThisMenu::Drawer() { screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); } - screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_AlphaF, alpha, TAG_DONE); + screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE); } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index ac6c2bc230..a77a7358d5 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1061,10 +1061,10 @@ public: mysnprintf(goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0); screen->DrawText(SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true, - DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); + DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE); screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon), 3, 190, DTA_320x200, true, - DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); + DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE); screen->DrawText(SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE); screen->DrawTexture(TexMan(((AInventory *)GetDefaultByType(cointype))->Icon), 2, 189, DTA_320x200, true, TAG_DONE); diff --git a/src/r_things.cpp b/src/r_things.cpp index 730448706a..8aaf0dcfe7 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1720,7 +1720,7 @@ void R_DrawRemainingPlayerSprites() DTA_ClipTop, viewwindowy, DTA_ClipRight, viewwindowx + viewwidth, DTA_ClipBottom, viewwindowy + viewheight, - DTA_AlphaF, vis->Style.Alpha, + DTA_Alpha, vis->Style.Alpha, DTA_RenderStyle, vis->RenderStyle, DTA_FillColor, vis->FillColor, DTA_SpecialColormap, special, diff --git a/src/v_draw.cpp b/src/v_draw.cpp index cf1e4c6881..e5896958a8 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -431,6 +431,37 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double return false; } +static void ListEnd(va_list &tags) +{ + va_end(tags); +} + +static int ListGetInt(va_list &tags) +{ + return va_arg(tags, int); +} + +static inline double ListGetDouble(va_list &tags) +{ + return va_arg(tags, double); +} + +static inline FRemapTable* ListGetTranslation(va_list &tags) +{ + return va_arg(tags, FRemapTable*); +} + +// 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) +{ + return va_arg(tags, FSpecialColormap *); +} + +static inline FColormapStyle * ListGetColormapStyle(va_list &tags) +{ + return va_arg(tags, FColormapStyle *); +} + bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool fortext) const { INTBOOL boolval; @@ -442,7 +473,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag { if (img == NULL || img->UseType == FTexture::TEX_Null) { - va_end(tags); + ListEnd(tags); return false; } } @@ -450,7 +481,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag // Do some sanity checks on the coordinates. if (x < -16383 || x > 16383 || y < -16383 || y > 16383) { - va_end(tags); + ListEnd(tags); return false; } @@ -497,39 +528,39 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag switch (tag) { default: - data = va_arg(tags, DWORD); + ListGetInt(tags); break; case DTA_DestWidth: assert(fortext == false); if (fortext) return false; parms->cleanmode = DTA_Base; - parms->destwidth = va_arg(tags, int); + parms->destwidth = ListGetInt(tags); break; case DTA_DestWidthF: assert(fortext == false); if (fortext) return false; parms->cleanmode = DTA_Base; - parms->destwidth = va_arg(tags, double); + parms->destwidth = ListGetDouble(tags); break; case DTA_DestHeight: assert(fortext == false); if (fortext) return false; parms->cleanmode = DTA_Base; - parms->destheight = va_arg(tags, int); + parms->destheight = ListGetInt(tags); break; case DTA_DestHeightF: assert(fortext == false); if (fortext) return false; parms->cleanmode = DTA_Base; - parms->destheight = va_arg(tags, double); + parms->destheight = ListGetDouble(tags); break; case DTA_Clean: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { parms->scalex = 1; @@ -539,7 +570,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_CleanNoMove: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { parms->scalex = CleanXfac; @@ -549,7 +580,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_CleanNoMove_1: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { parms->scalex = CleanXfac_1; @@ -559,7 +590,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_320x200: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { parms->cleanmode = DTA_Base; @@ -571,7 +602,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_Bottom320x200: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { parms->cleanmode = DTA_Base; @@ -584,32 +615,32 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_HUDRules: - intval = va_arg(tags, int); + intval = ListGetInt(tags); parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules; break; case DTA_VirtualWidth: parms->cleanmode = DTA_Base; - parms->virtWidth = va_arg(tags, int); + parms->virtWidth = ListGetInt(tags); break; case DTA_VirtualWidthF: parms->cleanmode = DTA_Base; - parms->virtWidth = va_arg(tags, double); + parms->virtWidth = ListGetDouble(tags); break; case DTA_VirtualHeight: parms->cleanmode = DTA_Base; - parms->virtHeight = va_arg(tags, int); + parms->virtHeight = ListGetInt(tags); break; case DTA_VirtualHeightF: parms->cleanmode = DTA_Base; - parms->virtHeight = va_arg(tags, double); + parms->virtHeight = ListGetDouble(tags); break; case DTA_Fullscreen: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { assert(fortext == false); @@ -621,24 +652,20 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_Alpha: - parms->Alpha = FIXED2FLOAT(MIN(OPAQUE, va_arg (tags, fixed_t))); - break; - - case DTA_AlphaF: - parms->Alpha = (float)(MIN(1., va_arg(tags, double))); + parms->Alpha = (float)(MIN(1., ListGetDouble(tags))); break; case DTA_AlphaChannel: - parms->alphaChannel = va_arg(tags, INTBOOL); + parms->alphaChannel = ListGetInt(tags); break; case DTA_FillColor: - parms->fillcolor = va_arg(tags, uint32); + parms->fillcolor = ListGetInt(tags); fillcolorset = true; break; case DTA_Translation: - parms->remap = va_arg(tags, FRemapTable *); + parms->remap = ListGetTranslation(tags); if (parms->remap != NULL && parms->remap->Inactive) { // If it's inactive, pretend we were passed NULL instead. parms->remap = NULL; @@ -646,41 +673,41 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ColorOverlay: - parms->colorOverlay = va_arg(tags, DWORD); + parms->colorOverlay = ListGetInt(tags); break; case DTA_FlipX: - parms->flipX = va_arg(tags, INTBOOL); + parms->flipX = ListGetInt(tags); break; case DTA_TopOffset: assert(fortext == false); if (fortext) return false; - parms->top = va_arg(tags, int); + parms->top = ListGetInt(tags); break; case DTA_TopOffsetF: assert(fortext == false); if (fortext) return false; - parms->top = va_arg(tags, double); + parms->top = ListGetDouble(tags); break; case DTA_LeftOffset: assert(fortext == false); if (fortext) return false; - parms->left = va_arg(tags, int); + parms->left = ListGetInt(tags); break; case DTA_LeftOffsetF: assert(fortext == false); if (fortext) return false; - parms->left = va_arg(tags, double); + parms->left = ListGetDouble(tags); break; case DTA_CenterOffset: assert(fortext == false); if (fortext) return false; - if (va_arg(tags, int)) + if (ListGetInt(tags)) { parms->left = img->GetScaledWidthDouble() * 0.5; parms->top = img->GetScaledHeightDouble() * 0.5; @@ -690,7 +717,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag case DTA_CenterBottomOffset: assert(fortext == false); if (fortext) return false; - if (va_arg(tags, int)) + if (ListGetInt(tags)) { parms->left = img->GetScaledWidthDouble() * 0.5; parms->top = img->GetScaledHeightDouble(); @@ -700,29 +727,29 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag case DTA_WindowLeft: assert(fortext == false); if (fortext) return false; - parms->windowleft = va_arg(tags, int); + parms->windowleft = ListGetInt(tags); break; case DTA_WindowLeftF: assert(fortext == false); if (fortext) return false; - parms->windowleft = va_arg(tags, double); + parms->windowleft = ListGetDouble(tags); break; case DTA_WindowRight: assert(fortext == false); if (fortext) return false; - parms->windowright = va_arg(tags, int); + parms->windowright = ListGetInt(tags); break; case DTA_WindowRightF: assert(fortext == false); if (fortext) return false; - parms->windowright = va_arg(tags, double); + parms->windowright = ListGetDouble(tags); break; case DTA_ClipTop: - parms->uclip = va_arg(tags, int); + parms->uclip = ListGetInt(tags); if (parms->uclip < 0) { parms->uclip = 0; @@ -730,7 +757,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ClipBottom: - parms->dclip = va_arg(tags, int); + parms->dclip = ListGetInt(tags); if (parms->dclip > this->GetHeight()) { parms->dclip = this->GetHeight(); @@ -738,7 +765,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ClipLeft: - parms->lclip = va_arg(tags, int); + parms->lclip = ListGetInt(tags); if (parms->lclip < 0) { parms->lclip = 0; @@ -746,7 +773,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ClipRight: - parms->rclip = va_arg(tags, int); + parms->rclip = ListGetInt(tags); if (parms->rclip > this->GetWidth()) { parms->rclip = this->GetWidth(); @@ -754,18 +781,18 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ShadowAlpha: - parms->shadowAlpha = MIN(OPAQUE, va_arg (tags, fixed_t)); + parms->shadowAlpha = (float)MIN(1., ListGetDouble(tags)); break; case DTA_ShadowColor: - parms->shadowColor = va_arg(tags, int); + parms->shadowColor = ListGetInt(tags); break; case DTA_Shadow: - boolval = va_arg(tags, INTBOOL); + boolval = ListGetInt(tags); if (boolval) { - parms->shadowAlpha = FRACUNIT/2; + parms->shadowAlpha = 0.5; parms->shadowColor = 0; } else @@ -775,45 +802,45 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_Masked: - parms->masked = va_arg(tags, INTBOOL); + parms->masked = ListGetInt(tags); break; case DTA_BilinearFilter: - parms->bilinear = va_arg(tags, INTBOOL); + parms->bilinear = ListGetInt(tags); break; case DTA_KeepRatio: // I think this is a terribly misleading name, since it actually turns // *off* aspect ratio correction. - parms->keepratio = va_arg(tags, INTBOOL); + parms->keepratio = ListGetInt(tags); break; case DTA_RenderStyle: - parms->style.AsDWORD = va_arg(tags, DWORD); + parms->style.AsDWORD = ListGetInt(tags); break; case DTA_SpecialColormap: - parms->specialcolormap = va_arg(tags, FSpecialColormap *); + parms->specialcolormap = ListGetSpecialColormap(tags); break; case DTA_ColormapStyle: - parms->colormapstyle = va_arg(tags, FColormapStyle *); + parms->colormapstyle = ListGetColormapStyle(tags); break; case DTA_TextLen: - parms->maxstrlen = va_arg(tags, int); + parms->maxstrlen = ListGetInt(tags); break; case DTA_CellX: - parms->cellx = va_arg(tags, int); + parms->cellx = ListGetInt(tags); break; case DTA_CellY: - parms->celly = va_arg(tags, int); + parms->celly = ListGetInt(tags); break; } - tag = va_arg(tags, DWORD); + tag = ListGetInt(tags); } va_end (tags); diff --git a/src/v_video.h b/src/v_video.h index e9bb1f6a4b..a33ea22f28 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -75,7 +75,6 @@ enum DTA_DestWidth, // width of area to draw to DTA_DestHeight, // height of area to draw to DTA_Alpha, // alpha value for translucency - DTA_AlphaF, // 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_Translation, // translation table to recolor the source DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor @@ -163,7 +162,7 @@ struct DrawParms uint32 colorOverlay; INTBOOL alphaChannel; INTBOOL flipX; - fixed_t shadowAlpha; + float shadowAlpha; int shadowColor; INTBOOL keepratio; INTBOOL masked; diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index eb1c7d2fac..46be7d8c9e 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -724,7 +724,7 @@ static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRang int width; screen->DrawTexture(font->GetChar(charcode, &width), x, y, nomove ? DTA_CleanNoMove : DTA_Clean, true, - DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : OPAQUE/2, + DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : 0.5, DTA_Translation, font->GetColorTranslation(translation), TAG_DONE); return x - width; From 43d759782d136c77b4abf9be88415ed1f51b2ee3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 16:23:14 +0100 Subject: [PATCH 05/20] - fixed: Stack based local VM object pointers should not be subjected to a read barrier. This isn't done for register based variables so for consistency it should not be done for stack based variables, too. This difference in handling made it impossible to check the target of a hitscan attack if it was destroyed by getting damaged. --- src/scripting/codegeneration/codegen.cpp | 4 +++- src/scripting/vm/vmexec.h | 12 ++++++++++++ src/scripting/vm/vmops.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index e6cd1989cd..a23811390b 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -6553,7 +6553,9 @@ ExpEmit FxStackVariable::Emit(VMFunctionBuilder *build) if (membervar->BitValue == -1) { if (offsetreg == -1) offsetreg = build->GetConstantInt(0); - build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, build->FramePointer.RegNum, offsetreg); + auto op = membervar->Type->GetLoadOp(); + if (op == OP_LO) op = OP_LOS; + build->Emit(op, loc.RegNum, build->FramePointer.RegNum, offsetreg); } else { diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index fc6a53bee1..0e34aa0315 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -209,6 +209,18 @@ begin: reg.a[a] = GC::ReadBarrier(*(DObject **)ptr); reg.atag[a] = ATAG_OBJECT; NEXTOP; + OP(LOS): + ASSERTA(a); ASSERTA(B); ASSERTKD(C); + GETADDR(PB,KC,X_READ_NIL); + reg.a[a] = *(DObject **)ptr; + reg.atag[a] = ATAG_OBJECT; + NEXTOP; + OP(LOS_R): + ASSERTA(a); ASSERTA(B); ASSERTD(C); + GETADDR(PB,RC,X_READ_NIL); + reg.a[a] = *(DObject **)ptr; + reg.atag[a] = ATAG_OBJECT; + NEXTOP; OP(LP): ASSERTA(a); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); diff --git a/src/scripting/vm/vmops.h b/src/scripting/vm/vmops.h index 86554940ea..3fc3d7643f 100644 --- a/src/scripting/vm/vmops.h +++ b/src/scripting/vm/vmops.h @@ -44,6 +44,8 @@ xx(LS, ls, RSRPKI, LS_R, 4, REGT_INT), // load string xx(LS_R, ls, RSRPRI, NOP, 0, 0), xx(LO, lo, RPRPKI, LO_R, 4, REGT_INT), // load object xx(LO_R, lo, RPRPRI, NOP, 0, 0), +xx(LOS, los, RPRPKI, LOS_R, 4, REGT_INT), // load object (stack version without read barrier) +xx(LOS_R, lo, RPRPRI, NOP, 0, 0), xx(LP, lp, RPRPKI, LP_R, 4, REGT_INT), // load pointer xx(LP_R, lp, RPRPRI, NOP, 0, 0), xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2 From ec15c7f4c31a4879543d3a3d8e0d0893556965ec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 16:29:01 +0100 Subject: [PATCH 06/20] - removed the fatal errors for invalid actor->movedir. These can be silently mapped to DI_NODIR to let the engine get the actor back on track. --- src/b_move.cpp | 8 ++++---- src/p_enemy.cpp | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/b_move.cpp b/src/b_move.cpp index b31e4acbef..2a3d40bcbf 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -65,11 +65,11 @@ bool DBot::Move (ticcmd_t *cmd) bool try_ok; int good; - if (player->mo->movedir == DI_NODIR) + if (player->mo->movedir >= DI_NODIR) + { + player->mo->movedir = DI_NODIR; // make sure it's valid. return false; - - if ((unsigned)player->mo->movedir >= 8) - I_Error ("Weird bot movedir!"); + } tryx = player->mo->X() + 8*xspeed[player->mo->movedir]; tryy = player->mo->Y() + 8*yspeed[player->mo->movedir]; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 2926e4e8cf..bd5a9cb17e 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -570,8 +570,9 @@ bool P_Move (AActor *actor) return true; } - if (actor->movedir == DI_NODIR) + if (actor->movedir >= DI_NODIR) { + actor->movedir = DI_NODIR; // make sure it's valid. return false; } @@ -585,9 +586,6 @@ bool P_Move (AActor *actor) return false; } - if ((unsigned)actor->movedir >= 8) - I_Error ("Weird actor->movedir!"); - // killough 10/98: allow dogs to drop off of taller ledges sometimes. // dropoff==1 means always allow it, dropoff==2 means only up to 128 high, // and only if the target is immediately on the other side of the line. From d662cece15f868ff0eccad813b8df6625473fff5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 16:44:43 +0100 Subject: [PATCH 07/20] - fixed calculations in AdjusrPlayerAngle. --- wadsrc/static/zscript/hexen/baseweapons.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/hexen/baseweapons.txt b/wadsrc/static/zscript/hexen/baseweapons.txt index f087946485..e0394996a8 100644 --- a/wadsrc/static/zscript/hexen/baseweapons.txt +++ b/wadsrc/static/zscript/hexen/baseweapons.txt @@ -40,7 +40,7 @@ extend class Actor void AdjustPlayerAngle(FTranslatedLineTarget t) { - double difference = t.angleFromSource; + double difference = deltaangle(angle, t.angleFromSource); if (abs(difference) > MAX_ANGLE_ADJUST) { if (difference > 0) From e8c2444dddf4fce546d73c746173fad1e6034f79 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 4 Feb 2017 18:10:30 +0200 Subject: [PATCH 08/20] Fixed compilation with GCC/Clang error: use of undeclared identifier 'op' error: no matching function for call to 'ListEnd' error: no matching function for call to 'ListGetInt' error: no matching function for call to 'ListGetDouble' ... --- src/scripting/vm/vmexec.h | 2 +- src/v_draw.cpp | 2 +- src/v_video.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 0e34aa0315..38dbbc411c 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -774,7 +774,7 @@ begin: OP(NEW_K): OP(NEW): { - PClass *cls = (PClass*)(op == OP_NEW ? reg.a[C] : konsta[C].v); + PClass *cls = (PClass*)(pc->op == OP_NEW ? reg.a[C] : konsta[C].v); reg.a[B] = cls->CreateNew(); NEXTOP; } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index e5896958a8..8c66c3d382 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -462,7 +462,7 @@ static inline FColormapStyle * ListGetColormapStyle(va_list &tags) return va_arg(tags, FColormapStyle *); } -bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool fortext) const +bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list& tags, DrawParms *parms, bool fortext) const { INTBOOL boolval; int intval; diff --git a/src/v_video.h b/src/v_video.h index a33ea22f28..968408b627 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -275,7 +275,7 @@ protected: 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); - bool ParseDrawTextureTags (FTexture *img, double x, double y, uint32 tag, va_list tags, DrawParms *parms, bool fortext) const; + bool ParseDrawTextureTags (FTexture *img, double x, double y, uint32 tag, va_list& tags, DrawParms *parms, bool fortext) const; DCanvas() {} From a1028077377ad32f297991052c3e5b12c18ac543 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 19:36:39 +0100 Subject: [PATCH 09/20] - atags for null pointers have no meaning so do not assert on them. --- src/scripting/vm/vmbuilder.cpp | 4 ++-- src/v_draw.cpp | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scripting/vm/vmbuilder.cpp b/src/scripting/vm/vmbuilder.cpp index 46553ab722..19fe81c32b 100644 --- a/src/scripting/vm/vmbuilder.cpp +++ b/src/scripting/vm/vmbuilder.cpp @@ -281,8 +281,8 @@ unsigned VMFunctionBuilder::GetConstantAddress(void *ptr, VM_ATAG tag) AddrKonst *locp = AddressConstantMap.CheckKey(ptr); if (locp != NULL) { - // There should only be one tag associated with a memory location. - assert(locp->Tag == tag); + // There should only be one tag associated with a memory location. Exceptions are made for null pointers that got allocated through constant arrays. + assert(ptr == nullptr || locp->Tag == tag); return locp->KonstNum; } else diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 8c66c3d382..a12b27bfcc 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -523,8 +523,6 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag // doubles when passed as function arguments.) while (tag != TAG_DONE) { - DWORD data; - switch (tag) { default: From 6dea3eef8e9ddbccfe1124e2bd2178d3355fb39a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 22:09:49 +0100 Subject: [PATCH 10/20] - exported DrawTexture to scripting. This uses templates to avoid source duplication of ParseDrawTextureTags. Not tested yet. --- src/scripting/vm/vm.h | 1 + src/scripting/vm/vmframe.cpp | 4 ++ src/v_draw.cpp | 79 ++++++++++++++++++++++++++++++++++-- src/v_video.h | 11 ++++- 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index 060fa0a762..1a5c10b4e5 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -193,6 +193,7 @@ enum enum EVMAbortException { + X_OTHER, X_READ_NIL, X_WRITE_NIL, X_TOO_MANY_TRIES, diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index 7615a4f0f1..c44fbb2ea6 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -554,6 +554,10 @@ CVMAbortException::CVMAbortException(EVMAbortException reason, const char *morei AppendMessage("string format failed."); break; + case X_OTHER: + // no prepended message. + break; + default: { size_t len = strlen(m_Message); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index a12b27bfcc..c678e8282c 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -126,6 +126,7 @@ static int PalFromRGB(uint32 rgb) return LastPal; } + void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...) { va_list tags; @@ -141,6 +142,31 @@ void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, .. DrawTextureParms(img, parms); } +static int ListGetInt(VMVa_List &tags); + +void DCanvas::DrawTexture(FTexture *img, double x, double y, VMVa_List &args) +{ + DrawParms parms; + uint32_t tag = ListGetInt(args); + bool res = ParseDrawTextureTags(img, x, y, tag, args, &parms, false); + if (!res) return; + DrawTextureParms(img, parms); +} + +DEFINE_ACTION_FUNCTION(_Screen, DrawTexture) +{ + PARAM_PROLOGUE; + PARAM_INT(texid); + PARAM_BOOL(animate); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + + FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)]; + VMVa_List args = { param + 4, 0, numparam - 4 }; + screen->DrawTexture(tex, x, y, args); + return 0; +} + DEFINE_ACTION_FUNCTION(_Screen, DrawHUDTexture) { PARAM_PROLOGUE; @@ -462,7 +488,50 @@ static inline FColormapStyle * ListGetColormapStyle(va_list &tags) return va_arg(tags, FColormapStyle *); } -bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list& tags, DrawParms *parms, bool fortext) const +static void ListEnd(VMVa_List &tags) +{ +} + +static int ListGetInt(VMVa_List &tags) +{ + if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_INT) + { + return tags.args[tags.curindex++].i; + } + ThrowAbortException(X_OTHER, "Invalid parameter in draw function, int expected"); + return 0; +} + +static inline double ListGetDouble(VMVa_List &tags) +{ + if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_FLOAT) + { + return tags.args[tags.curindex++].f; + } + ThrowAbortException(X_OTHER, "Invalid parameter in draw function, float expected"); + return 0; +} + +static inline FRemapTable* ListGetTranslation(VMVa_List &tags) +{ + ThrowAbortException(X_OTHER, "Invalid tag in draw function"); + return nullptr; +} + +static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags) +{ + ThrowAbortException(X_OTHER, "Invalid tag in draw function"); + return nullptr; +} + +static inline FColormapStyle * ListGetColormapStyle(VMVa_List &tags) +{ + ThrowAbortException(X_OTHER, "Invalid tag in draw function"); + return nullptr; +} + +template +bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, T& tags, DrawParms *parms, bool fortext) const { INTBOOL boolval; int intval; @@ -626,7 +695,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag parms->cleanmode = DTA_Base; parms->virtWidth = ListGetDouble(tags); break; - + case DTA_VirtualHeight: parms->cleanmode = DTA_Base; parms->virtHeight = ListGetInt(tags); @@ -840,7 +909,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag } tag = ListGetInt(tags); } - va_end (tags); + ListEnd(tags); if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip) { @@ -885,6 +954,10 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag } return true; } +// 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, VMVa_List& tags, DrawParms *parms, bool fortext) const; void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom, bool handleaspect) const diff --git a/src/v_video.h b/src/v_video.h index 968408b627..2f42b9807e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -177,6 +177,12 @@ struct DrawParms bool virtBottom; }; +struct VMVa_List +{ + VMValue *args; + int curindex; + int numargs; +}; // // VIDEO // @@ -251,6 +257,7 @@ public: // 2D Texture drawing bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; void DrawTexture (FTexture *img, double x, double y, int tags, ...); + void DrawTexture(FTexture *img, double x, double y, VMVa_List &); void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const; @@ -275,7 +282,9 @@ protected: 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); - bool ParseDrawTextureTags (FTexture *img, double x, double y, uint32 tag, va_list& tags, DrawParms *parms, bool fortext) const; + + template + bool ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, T& tags, DrawParms *parms, bool fortext) const; DCanvas() {} From d50e52ea59ae8f16fd36aef9784b03e657a71d61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 22:50:23 +0100 Subject: [PATCH 11/20] - use DrawChar to draw font characters instead of calling DrawTexture directly. Mostly done to remove uses of DTA_Translation. --- src/g_statusbar/strife_sbar.cpp | 18 ++++++------------ src/v_draw.cpp | 9 +++++---- src/wi_stuff.cpp | 4 ++-- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/g_statusbar/strife_sbar.cpp b/src/g_statusbar/strife_sbar.cpp index 4ce1cf1985..8e13744913 100644 --- a/src/g_statusbar/strife_sbar.cpp +++ b/src/g_statusbar/strife_sbar.cpp @@ -945,15 +945,13 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size if (val == 0) { pic = BigFont->GetChar('0', &v); - screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, '0', DTA_HUDRules, HUD_Normal, DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); - screen->DrawTexture(pic, xpos - v / 2, y, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '0', DTA_HUDRules, HUD_Normal, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); return; } @@ -970,11 +968,10 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size while (val != 0) { pic = BigFont->GetChar('0' + val % 10, &v); - screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, DTA_HUDRules, HUD_Normal, DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); val /= 10; xpos -= w; @@ -984,11 +981,10 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size pic = BigFont->GetChar('-', &v); if (pic != NULL) { - screen->DrawTexture(pic, xpos - v / 2 + 2, y + 2, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, '-', DTA_HUDRules, HUD_Normal, DTA_Alpha, HR_SHADOW, DTA_FillColor, 0, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); } } @@ -999,9 +995,8 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size while (val != 0) { pic = BigFont->GetChar('0' + val % 10, &v); - screen->DrawTexture(pic, xpos - v / 2, y, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '0', DTA_HUDRules, HUD_Normal, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); val /= 10; xpos -= w; @@ -1011,9 +1006,8 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size pic = BigFont->GetChar('-', &v); if (pic != NULL) { - screen->DrawTexture(pic, xpos - v / 2, y, + screen->DrawChar(BigFont, CR_UNTRANSLATED, xpos - v / 2, y, '-', DTA_HUDRules, HUD_Normal, - DTA_Translation, BigFont->GetColorTranslation(CR_UNTRANSLATED), TAG_DONE); } } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index c678e8282c..3961c1ec10 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -733,10 +733,6 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, case DTA_Translation: parms->remap = ListGetTranslation(tags); - if (parms->remap != NULL && parms->remap->Inactive) - { // If it's inactive, pretend we were passed NULL instead. - parms->remap = NULL; - } break; case DTA_ColorOverlay: @@ -911,6 +907,11 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, } ListEnd(tags); + if (parms->remap != nullptr && parms->remap->Inactive) + { // If it's inactive, pretend we were passed NULL instead. + parms->remap = nullptr; + } + if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip) { return false; diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 46be7d8c9e..73a5b9742e 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -722,10 +722,10 @@ void WI_drawBackground() static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRange translation=CR_UNTRANSLATED, bool nomove=false) { int width; - screen->DrawTexture(font->GetChar(charcode, &width), x, y, + font->GetChar(charcode, &width); + screen->DrawChar(font, translation, x, y, charcode, nomove ? DTA_CleanNoMove : DTA_Clean, true, DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : 0.5, - DTA_Translation, font->GetColorTranslation(translation), TAG_DONE); return x - width; } From dadc8e2ec2ad95a77f2e17fa729dad0a480039df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 4 Feb 2017 23:26:28 +0100 Subject: [PATCH 12/20] - removed all uses of DTA_Translation except for the single one that passes a custom built table. This means that with the exception of 3 pointers the DrawTexture interface only accepts numeric values now. Still need to get rid of the last 3 to have this ready for scripting. --- src/am_map.cpp | 2 +- src/g_statusbar/sbarinfo.cpp | 37 ++++++++++++++++--------------- src/g_statusbar/strife_sbar.cpp | 5 ++--- src/intermission/intermission.cpp | 20 +++++------------ src/intermission/intermission.h | 2 +- src/menu/menuinput.cpp | 6 +---- src/menu/playerdisplay.cpp | 5 ++--- src/r_things.cpp | 2 +- src/v_draw.cpp | 6 ++++- src/v_text.cpp | 2 +- src/v_video.h | 3 ++- 11 files changed, 41 insertions(+), 49 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 19f10f0675..be92fd37ab 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2934,7 +2934,7 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust, DTA_ClipLeft, f_x, DTA_ClipRight, f_x + f_w, DTA_FlipX, flip, - DTA_Translation, TranslationToTable(translation), + DTA_TranslationIndex, translation, DTA_Alpha, alpha, DTA_FillColor, fillcolor, DTA_RenderStyle, DWORD(renderstyle), diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index 33b47f15de..2fd21737f2 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1267,7 +1267,7 @@ public: DTA_ClipTop, static_cast(dcy), DTA_ClipRight, static_cast(MIN(INT_MAX, dcr)), DTA_ClipBottom, static_cast(MIN(INT_MAX, dcb)), - DTA_Translation, translate ? GetTranslation() : 0, + DTA_TranslationIndex, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_Alpha, Alpha, @@ -1284,7 +1284,7 @@ public: DTA_ClipTop, static_cast(dcy), DTA_ClipRight, static_cast(MIN(INT_MAX, dcr)), DTA_ClipBottom, static_cast(MIN(INT_MAX, dcb)), - DTA_Translation, translate ? GetTranslation() : 0, + DTA_TranslationIndex, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_Alpha, Alpha, @@ -1344,7 +1344,7 @@ public: DTA_ClipTop, static_cast(rcy), DTA_ClipRight, static_cast(rcr), DTA_ClipBottom, static_cast(rcb), - DTA_Translation, translate ? GetTranslation() : 0, + DTA_TranslationIndex, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_Alpha, Alpha, @@ -1361,7 +1361,7 @@ public: DTA_ClipTop, static_cast(rcy), DTA_ClipRight, static_cast(rcr), DTA_ClipBottom, static_cast(rcb), - DTA_Translation, translate ? GetTranslation() : 0, + DTA_TranslationIndex, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, DTA_Alpha, Alpha, @@ -1382,7 +1382,7 @@ public: const BYTE* str = (const BYTE*) cstring; const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); - FRemapTable *remap = font->GetColorTranslation(translation); + int fontcolor = translation; if(fullScreenOffsets) { @@ -1408,7 +1408,7 @@ public: { EColorRange newColor = V_ParseFontColor(++str, translation, boldTranslation); if(newColor != CR_UNDEFINED) - remap = font->GetColorTranslation(newColor); + fontcolor = newColor; continue; } @@ -1417,20 +1417,22 @@ public: width = font->GetCharWidth((unsigned char) *str); else width = font->GetCharWidth((unsigned char) script->spacingCharacter); - FTexture* character = font->GetChar((unsigned char) *str, &width); - if(character == NULL) //missing character. + FTexture* c = font->GetChar((unsigned char) *str, &width); + if(c == NULL) //missing character. { str++; continue; } + int character = (unsigned char)*str; + if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset - ax += (character->LeftOffset+1); //ignore x offsets since we adapt to character size + ax += (c->LeftOffset+1); //ignore x offsets since we adapt to character size double rx, ry, rw, rh; rx = ax + xOffset; ry = ay + yOffset; - rw = character->GetScaledWidthDouble(); - rh = character->GetScaledHeightDouble(); + rw = c->GetScaledWidthDouble(); + rh = c->GetScaledHeightDouble(); if(script->spacingCharacter != '\0') { @@ -1484,32 +1486,31 @@ public: double salpha = (Alpha *HR_SHADOW); double srx = rx + (shadowX*xScale); double sry = ry + (shadowY*yScale); - screen->DrawTexture(character, srx, sry, + screen->DrawChar(font, CR_UNTRANSLATED, srx, sry, character, DTA_DestWidthF, rw, DTA_DestHeightF, rh, DTA_Alpha, salpha, DTA_FillColor, 0, TAG_DONE); } - screen->DrawTexture(character, rx, ry, + screen->DrawChar(font, fontcolor, rx, ry, character, DTA_DestWidthF, rw, DTA_DestHeightF, rh, - DTA_Translation, remap, DTA_Alpha, Alpha, TAG_DONE); if(script->spacingCharacter == '\0') - ax += width + spacing - (character->LeftOffset+1); + ax += width + spacing - (c->LeftOffset+1); else //width gets changed at the call to GetChar() ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing; str++; } } - FRemapTable* GetTranslation() const + uint32_t GetTranslation() const { if(gameinfo.gametype & GAME_Raven) - return translationtables[TRANSLATION_PlayersExtra][int(CPlayer - players)]; - return translationtables[TRANSLATION_Players][int(CPlayer - players)]; + return TRANSLATION(TRANSLATION_PlayersExtra, int(CPlayer - players)); + return TRANSLATION(TRANSLATION_Players, int(CPlayer - players)); } AInventory *ammo1, *ammo2; diff --git a/src/g_statusbar/strife_sbar.cpp b/src/g_statusbar/strife_sbar.cpp index 8e13744913..177117eb2b 100644 --- a/src/g_statusbar/strife_sbar.cpp +++ b/src/g_statusbar/strife_sbar.cpp @@ -849,7 +849,7 @@ private: void DrINumberOuter(signed int val, int x, int y, bool center = false, int w = 9) const; void DrBNumberOuterFont(signed int val, int x, int y, int w = 3) const; void DrawDimImage(FTexture *image, int x, int y, bool dimmed) const; - void DrawImage(FTexture *image, int x, int y, FRemapTable *translation = NULL) const; + void DrawImage(FTexture *image, int x, int y/*, FRemapTable *translation = NULL*/) const; }; @@ -1022,12 +1022,11 @@ void DStrifeStatusBar::DrBNumberOuterFont(signed int val, int x, int y, int size //--------------------------------------------------------------------------- void DStrifeStatusBar::DrawImage(FTexture *img, - int x, int y, FRemapTable *translation) const + int x, int y) const { if (img != NULL) { screen->DrawTexture(img, x + ST_X, y + ST_Y, - DTA_Translation, translation, DTA_Bottom320x200, Scaled, TAG_DONE); } diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 9c3353b60c..8310914bef 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -388,15 +388,8 @@ void DIntermissionScreenText::Drawer () w *= CleanXfac; if (cx + w > SCREENWIDTH) continue; - if (pic != NULL) - { - screen->DrawTexture (pic, - cx, - cy, - DTA_Translation, range, - DTA_CleanNoMove, true, - TAG_DONE); - } + + screen->DrawChar(SmallFont, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE); cx += w; } } @@ -432,16 +425,15 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) { advplayerstate = mDefaults->MissileState; - casttranslation = translationtables[TRANSLATION_Players][consoleplayer]; + casttranslation = TRANSLATION(TRANSLATION_Players, consoleplayer); } else { advplayerstate = NULL; - casttranslation = NULL; + casttranslation = 0; if (mDefaults->Translation != 0) { - casttranslation = translationtables[GetTranslationType(mDefaults->Translation)] - [GetTranslationIndex(mDefaults->Translation)]; + casttranslation = mDefaults->Translation; } } castdeath = false; @@ -631,7 +623,7 @@ void DIntermissionScreenCast::Drawer () DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, DTA_RenderStyle, mDefaults->RenderStyle, DTA_Alpha, mDefaults->Alpha, - DTA_Translation, casttranslation, + DTA_TranslationIndex, casttranslation, TAG_DONE); } } diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 0f2c38dde1..cdc100d888 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -234,7 +234,7 @@ class DIntermissionScreenCast : public DIntermissionScreen TArray mCastSounds; int casttics; - const FRemapTable *casttranslation; // [RH] Draw "our hero" with their chosen suit color + uint32_t casttranslation; // [RH] Draw "our hero" with their chosen suit color FState* caststate; FState* basestate; FState* advplayerstate; diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index cca4756f5b..b590802786 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -336,15 +336,11 @@ void DTextEnterMenu::Drawer () // The highlighted character is yellow; the rest are dark gray. color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; - remap = SmallFont->GetColorTranslation(color); if (pic != NULL) { // Draw a normal character. - screen->DrawTexture(pic, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, - DTA_Translation, remap, - DTA_CleanNoMove, true, - TAG_DONE); + screen->DrawChar(SmallFont, color, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, ch, DTA_CleanNoMove, true, TAG_DONE); } else if (ch == ' ') { diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index aaec6fba3b..9b26d7471f 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -605,13 +605,12 @@ void DListMenuItemPlayerDisplay::Drawer(bool selected) FTexture *tex = TexMan(sprframe->Texture[mRotation]); if (tex != NULL && tex->UseType != FTexture::TEX_Null) { - FRemapTable *trans = NULL; - if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS); + int trans = mTranslate? TRANSLATION(TRANSLATION_Players, MAXPLAYERS) : 0; screen->DrawTexture (tex, x + 36*CleanXfac, y + 71*CleanYfac, DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * Scale.X, DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * Scale.Y, - DTA_Translation, trans, + DTA_TranslationIndex, trans, DTA_FlipX, sprframe->Flip & (1 << mRotation), TAG_DONE); } diff --git a/src/r_things.cpp b/src/r_things.cpp index 8aaf0dcfe7..3d0ce269ec 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1712,7 +1712,7 @@ void R_DrawRemainingPlayerSprites() viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5, DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale), DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale, - DTA_Translation, TranslationToTable(vis->Translation), + DTA_TranslationIndex, vis->Translation, DTA_FlipX, flip, DTA_TopOffset, 0, DTA_LeftOffset, 0, diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 3961c1ec10..b61d83b011 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -201,7 +201,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) { parms.colorOverlay = PalEntry(parms.colorOverlay).InverseColor(); } - // Note that this overrides DTA_Translation in software, but not in hardware. + // Note that this overrides the translation in software, but not in hardware. FDynamicColormap *colormap = GetSpecialLights(MAKERGB(255,255,255), parms.colorOverlay & MAKEARGB(0,255,255,255), 0); translation = &colormap->Maps[(APART(parms.colorOverlay)*NUMCOLORMAPS/255)*256]; @@ -735,6 +735,10 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, parms->remap = ListGetTranslation(tags); break; + case DTA_TranslationIndex: + parms->remap = TranslationToTable(ListGetInt(tags)); + break; + case DTA_ColorOverlay: parms->colorOverlay = ListGetInt(tags); break; diff --git a/src/v_text.cpp b/src/v_text.cpp index 5772b078c0..3fcac55411 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -52,7 +52,7 @@ // // Write a single character using the given font // -void DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...) +void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...) { if (font == NULL) return; diff --git a/src/v_video.h b/src/v_video.h index 2f42b9807e..f52e8b8aa8 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -77,6 +77,7 @@ enum 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_Translation, // translation table to recolor the source + DTA_TranslationIndex, 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 @@ -270,7 +271,7 @@ public: #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, int x, int y, BYTE character, int tag_first, ...); + void DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); protected: BYTE *Buffer; From 470dc138c68b2f8d41ccaf5e166be147188f7c25 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 00:17:29 +0100 Subject: [PATCH 13/20] - got rid of all DTA_Translation uses. --- src/menu/menuinput.cpp | 6 +++--- src/menu/playerdisplay.cpp | 9 +++++---- src/r_data/r_translate.cpp | 2 ++ src/v_draw.cpp | 15 --------------- src/v_video.h | 3 +-- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index b590802786..71646410d4 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -332,7 +332,6 @@ void DTextEnterMenu::Drawer () const int ch = InputGridChars[y * INPUTGRID_WIDTH + x]; FTexture *pic = SmallFont->GetChar(ch, &width); EColorRange color; - FRemapTable *remap; // The highlighted character is yellow; the rest are dark gray. color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; @@ -344,13 +343,14 @@ void DTextEnterMenu::Drawer () } else if (ch == ' ') { + FRemapTable *remap = SmallFont->GetColorTranslation(color); // Draw the space as a box outline. We also draw it 50% wider than it really is. const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; const int x2 = x1 + width * 3 * CleanXfac / 2; const int y1 = yy + top_padding; const int y2 = y1 + SmallFont->GetHeight() * CleanYfac; - const int palentry = remap->Remap[remap->NumEntries*2/3]; - const uint32 palcolor = remap->Palette[remap->NumEntries*2/3]; + const int palentry = remap->Remap[remap->NumEntries * 2 / 3]; + const uint32 palcolor = remap->Palette[remap->NumEntries * 2 / 3]; screen->Clear(x1, y1, x2, y1+CleanYfac, palentry, palcolor); // top screen->Clear(x1, y2, x2, y2+CleanYfac, palentry, palcolor); // bottom screen->Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palentry, palcolor); // left diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index 9b26d7471f..57c8ecf262 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -360,13 +360,14 @@ DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu { mOwner = menu; + FRemapTable *bdremap = translationtables[TRANSLATION_Players][MAXPLAYERS + 1]; for (int i = 0; i < 256; i++) { int r = c1.r + c2.r * i / 255; int g = c1.g + c2.g * i / 255; int b = c1.b + c2.b * i / 255; - mRemap.Remap[i] = ColorMatcher.Pick (r, g, b); - mRemap.Palette[i] = PalEntry(255, r, g, b); + bdremap->Remap[i] = ColorMatcher.Pick (r, g, b); + bdremap->Palette[i] = PalEntry(255, r, g, b); } mBackdrop = new FBackdropTexture; mPlayerClass = NULL; @@ -574,10 +575,10 @@ void DListMenuItemPlayerDisplay::Drawer(bool selected) int x = (mXpos - 160) * CleanXfac + (SCREENWIDTH>>1); int y = (mYpos - 100) * CleanYfac + (SCREENHEIGHT>>1); - screen->DrawTexture (mBackdrop, x, y - 1, + screen->DrawTexture(mBackdrop, x, y - 1, DTA_DestWidth, 72 * CleanXfac, DTA_DestHeight, 80 * CleanYfac, - DTA_Translation, &mRemap, + DTA_TranslationIndex, TRANSLATION(TRANSLATION_Players, MAXPLAYERS + 1), DTA_Masked, true, TAG_DONE); diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 78d6e22c9f..64f490b302 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -740,6 +740,8 @@ void R_InitTranslationTables () } // The menu player also gets a separate translation table PushIdentityTable(TRANSLATION_Players); + // This one is for the backdrop in the menu + PushIdentityTable(TRANSLATION_Players); // The three standard translations from Doom or Heretic (seven for Strife), // plus the generic ice translation. diff --git a/src/v_draw.cpp b/src/v_draw.cpp index b61d83b011..331be97129 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -472,11 +472,6 @@ static inline double ListGetDouble(va_list &tags) return va_arg(tags, double); } -static inline FRemapTable* ListGetTranslation(va_list &tags) -{ - return va_arg(tags, FRemapTable*); -} - // 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) { @@ -512,12 +507,6 @@ static inline double ListGetDouble(VMVa_List &tags) return 0; } -static inline FRemapTable* ListGetTranslation(VMVa_List &tags) -{ - ThrowAbortException(X_OTHER, "Invalid tag in draw function"); - return nullptr; -} - static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags) { ThrowAbortException(X_OTHER, "Invalid tag in draw function"); @@ -731,10 +720,6 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag, fillcolorset = true; break; - case DTA_Translation: - parms->remap = ListGetTranslation(tags); - break; - case DTA_TranslationIndex: parms->remap = TranslationToTable(ListGetInt(tags)); break; diff --git a/src/v_video.h b/src/v_video.h index f52e8b8aa8..18bb310e1f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -76,8 +76,7 @@ enum 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_Translation, // translation table to recolor the source - DTA_TranslationIndex, + 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 From 5cfac78116b7d706d6bab023ee68360243ec9c9e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 01:52:09 +0100 Subject: [PATCH 14/20] - added write barriers to the menu code. The GC was causing some crash issues with the items not having been subjected to a write barrier. --- src/menu/colorpickermenu.cpp | 4 ++++ src/menu/joystickmenu.cpp | 8 ++++++++ src/menu/listmenu.cpp | 4 ++++ src/menu/menu.h | 2 ++ src/menu/menudef.cpp | 25 +++++++++++++++++++++++++ src/menu/optionmenu.cpp | 4 ++++ 6 files changed, 47 insertions(+) diff --git a/src/menu/colorpickermenu.cpp b/src/menu/colorpickermenu.cpp index 6ace5bd704..df96b37a02 100644 --- a/src/menu/colorpickermenu.cpp +++ b/src/menu/colorpickermenu.cpp @@ -89,6 +89,10 @@ public: desc->mItems[mStartItem+5] = new DOptionMenuItemStaticText(" ", false); desc->mItems[mStartItem+6] = new DOptionMenuItemCommand("Undo changes", "undocolorpic"); desc->mItems[mStartItem+7] = new DOptionMenuItemStaticText(" ", false); + for (auto &p : desc->mItems) + { + GC::WriteBarrier(p); + } desc->mSelectedItem = mStartItem + 2; Init(parent, desc); desc->mIndent = 0; diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 702a6b09f0..21bb370b4a 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -322,6 +322,10 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) opt->mItems.Push(it); } } + for (auto &p : opt->mItems) + { + GC::WriteBarrier(p); + } opt->mScrollPos = 0; opt->mSelectedItem = -1; opt->mIndent = 0; @@ -402,6 +406,10 @@ void UpdateJoystickMenu(IJoystickConfig *selected) if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); } } + for (auto &p : opt->mItems) + { + GC::WriteBarrier(p); + } if (opt->mSelectedItem >= (int)opt->mItems.Size()) { opt->mSelectedItem = opt->mItems.Size() - 1; diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 4605246bd9..020a540c54 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -44,6 +44,10 @@ IMPLEMENT_CLASS(DListMenu, false, false) +IMPLEMENT_POINTERS_START(DListMenu) +IMPLEMENT_POINTER(mFocusControl) +IMPLEMENT_POINTERS_END + //============================================================================= // // diff --git a/src/menu/menu.h b/src/menu/menu.h index e789604a82..23a4e87187 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -520,6 +520,7 @@ public: class DListMenu : public DMenu { DECLARE_CLASS(DListMenu, DMenu) + HAS_OBJECT_POINTERS; protected: FListMenuDescriptor *mDesc; @@ -609,6 +610,7 @@ extern FOptionMap OptionValues; class DOptionMenu : public DMenu { DECLARE_CLASS(DOptionMenu, DMenu) + HAS_OBJECT_POINTERS; bool CanScrollUp; bool CanScrollDown; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 08e44fbabc..efb444d5c2 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -475,6 +475,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.ScriptError("Unknown keyword '%s'", sc.String); } } + for (auto &p : desc->mItems) + { + GC::WriteBarrier(p); + } } //============================================================================= @@ -927,6 +931,10 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) sc.ScriptError("Unknown keyword '%s'", sc.String); } } + for (auto &p : desc->mItems) + { + GC::WriteBarrier(p); + } } //============================================================================= @@ -1101,6 +1109,10 @@ static void BuildEpisodeMenu() ld->mAutoselect = ld->mSelectedItem; } success = true; + for (auto &p : ld->mItems) + { + GC::WriteBarrier(p); + } } } } @@ -1125,6 +1137,7 @@ static void BuildEpisodeMenu() { DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); od->mItems.Push(it); + GC::WriteBarrier(it); } } } @@ -1230,6 +1243,10 @@ static void BuildPlayerclassMenu() } } success = true; + for (auto &p : ld->mItems) + { + GC::WriteBarrier(p); + } } } } @@ -1261,11 +1278,13 @@ static void BuildPlayerclassMenu() { DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i); od->mItems.Push(it); + GC::WriteBarrier(it); } } } DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1); od->mItems.Push(it); + GC::WriteBarrier(it); } } @@ -1355,6 +1374,10 @@ static void InitKeySections() menu->mItems.Push(item); } } + for (auto &p : menu->mItems) + { + GC::WriteBarrier(p); + } } } } @@ -1488,6 +1511,7 @@ void M_StartupSkillMenu(FGameStartup *gs) pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i); } ld->mItems.Push(li); + GC::WriteBarrier(li); y += ld->mLinespacing; } if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) @@ -1541,6 +1565,7 @@ fail: } li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); od->mItems.Push(li); + GC::WriteBarrier(li); if (!done) { done = true; diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index f6e129ebca..e27ae20a2b 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -66,6 +66,10 @@ void M_DrawConText (int color, int x, int y, const char *str) IMPLEMENT_CLASS(DOptionMenu, false, false) +IMPLEMENT_POINTERS_START(DOptionMenu) +IMPLEMENT_POINTER(mFocusControl) +IMPLEMENT_POINTERS_END + //============================================================================= // // From b570d0819b9a46e350efd12a38a93ac37dd122b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Feb 2017 13:14:22 +0100 Subject: [PATCH 15/20] - 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 4340cc3f88..493625bf94 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 9a966e6d57..573c190716 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 7468b6dabb..e4d9fc177b 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 2726ebff11..8cbe799662 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 d2358d8b36..a7a3860bb2 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 a23811390b..a3641269f8 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 69ad192f58..6438e0868c 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 6d7a6ef7cb..dcb7acab6c 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 2854be8c2b..6a4f60826b 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 b31c51471b..124f29a4e7 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 bdc1ce3ae5..4d567d3ca6 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 b84d72a51a..f1df373c37 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 752de80168..1ae88ab856 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 970478caec..4c7311b56c 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 16/20] 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 dcb7acab6c..a577056aff 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 17/20] - 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 6a4f60826b..00d3b10f70 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 124f29a4e7..4c78b3007e 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 3fcac55411..47fbf6f1b1 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 f1df373c37..cb5239a37d 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 18/20] - 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 47fbf6f1b1..324e22bc0b 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 3baf62af7e..bd24be4058 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 cb5239a37d..57ec1b6df3 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 19/20] - 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 331be97129..52f8cde7a9 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 324e22bc0b..3394e448a0 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 18bb310e1f..a594fa8fe9 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 57ec1b6df3..802c220c96 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 20/20] - 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 f89a560ab9..c732ea18ca 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 24afe68e99..9b6f42b88a 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 802c220c96..175f8341d5 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