diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index 060fa0a76..1a5c10b4e 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 7615a4f0f..c44fbb2ea 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 a12b27bfc..c678e8282 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 968408b62..2f42b9807 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() {}