Merge remote-tracking branch 'gzdoom/master'

This commit is contained in:
Rachael Alexanderson 2017-02-05 16:07:48 -05:00
commit 942f90a759
24 changed files with 529 additions and 152 deletions

View file

@ -972,7 +972,7 @@ public:
{
SetOrigin(Pos() + vel, true);
}
void SetOrigin(double x, double y, double z, bool moving);
virtual void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(const DVector3 & npos, bool moving)
{
SetOrigin(npos.X, npos.Y, npos.Z, moving);

View file

@ -1756,11 +1756,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);

View file

@ -2464,6 +2464,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 ();

View file

@ -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);

View file

@ -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;

View file

@ -866,6 +866,14 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
// This should be done after postprocessing, not before.
mBuffers->BindCurrentFB();
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
if (!toscreen)
{
gl_RenderState.mViewMatrix.loadIdentity();
gl_RenderState.mProjectionMatrix.ortho(mScreenViewport.left, mScreenViewport.width, mScreenViewport.height, mScreenViewport.top, -1.0f, 1.0f);
gl_RenderState.ApplyMatrices();
}
DrawBlend(lviewsector);
}
mDrawingScene2D = false;

View file

@ -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;
}

View file

@ -3196,6 +3196,7 @@ void P_NightmareRespawn (AActor *mobj)
// spawn it
mo = AActor::StaticSpawn(mobj->GetClass(), DVector3(mobj->SpawnPoint.X, mobj->SpawnPoint.Y, z), NO_REPLACE, true);
mo->health = mobj->SpawnHealth();
if (z == ONFLOORZ)
{

View file

@ -331,8 +331,6 @@ void R_Init ()
{
atterm (R_Shutdown);
StartScreen->Progress();
V_InitFonts();
StartScreen->Progress();
// Colormap init moved back to InitPalette()
//R_InitColormaps ();

View file

@ -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<FxConstant *>(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.

View file

@ -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

View file

@ -2187,17 +2187,17 @@ 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)
{
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;

View file

@ -129,12 +129,12 @@ static int PalFromRGB(uint32 rgb)
void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...)
{
va_list tags;
va_start(tags, tags_first);
Va_List tags;
va_start(tags.list, tags_first);
DrawParms parms;
bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false);
va_end(tags);
va_end(tags.list);
if (!res)
{
return;
@ -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)
{
@ -427,37 +427,37 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double
return false;
}
static void ListEnd(va_list &tags)
static void ListEnd(Va_List &tags)
{
va_end(tags);
va_end(tags.list);
}
static int ListGetInt(va_list &tags)
static int ListGetInt(Va_List &tags)
{
return va_arg(tags, int);
return va_arg(tags.list, int);
}
static inline double ListGetDouble(va_list &tags)
static inline double ListGetDouble(Va_List &tags)
{
return va_arg(tags, double);
return va_arg(tags.list, double);
}
// These two options are only being used by the D3D version of the HUD weapon drawer, they serve no purpose anywhere else.
static inline FSpecialColormap * ListGetSpecialColormap(va_list &tags)
static inline FSpecialColormap * ListGetSpecialColormap(Va_List &tags)
{
return va_arg(tags, FSpecialColormap *);
return va_arg(tags.list, FSpecialColormap *);
}
static inline FColormapStyle * ListGetColormapStyle(va_list &tags)
static inline FColormapStyle * ListGetColormapStyle(Va_List &tags)
{
return va_arg(tags, FColormapStyle *);
return va_arg(tags.list, FColormapStyle *);
}
static void ListEnd(VMVa_List &tags)
{
}
static int ListGetInt(VMVa_List &tags)
int ListGetInt(VMVa_List &tags)
{
if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_INT)
{
@ -916,7 +916,7 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, DWORD tag,
}
// explicitly instantiate both versions for v_text.cpp.
template bool DCanvas::ParseDrawTextureTags<va_list>(FTexture *img, double x, double y, DWORD tag, va_list& tags, DrawParms *parms, bool fortext) const;
template bool DCanvas::ParseDrawTextureTags<Va_List>(FTexture *img, double x, double y, DWORD tag, Va_List& tags, DrawParms *parms, bool fortext) const;
template bool DCanvas::ParseDrawTextureTags<VMVa_List>(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,

View file

@ -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 ------------------------------------------------------------------
@ -340,6 +341,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 +375,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 +487,6 @@ FFont::~FFont ()
delete[] PatchRemap;
PatchRemap = NULL;
}
if (Name)
{
delete[] Name;
Name = NULL;
}
FFont **prev = &FirstFont;
FFont *font = *prev;
@ -508,27 +512,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));
}
@ -843,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
@ -935,7 +997,7 @@ FFont::FFont (int lump)
Lump = lump;
Chars = NULL;
PatchRemap = NULL;
Name = NULL;
FontName = NAME_None;
Cursor = '_';
}
@ -951,7 +1013,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 +1251,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 +1553,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
FTexture *pic = TexMan[picnum];
Name = copystring(picname);
FontName = picname;
FontHeight = pic->GetScaledHeight();
SpaceWidth = pic->GetScaledWidth();
GlobalKerning = 0;
@ -1905,7 +1967,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];
@ -2492,6 +2554,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 +2735,3 @@ void V_ClearFonts()
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
}
void V_RetranslateFonts()
{
FFont *font = FFont::FirstFont;
while(font)
{
font->LoadTranslations();
font = font->Next;
}
}

View file

@ -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,14 +127,13 @@ protected:
BYTE *PatchRemap;
int Lump;
char *Name;
FName FontName;
FFont *Next;
static FFont *FirstFont;
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__

View file

@ -47,11 +47,16 @@
#include "doomstat.h"
#include "templates.h"
int ListGetInt(VMVa_List &tags);
//==========================================================================
//
// 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)
@ -66,10 +71,10 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch
if (NULL != (pic = font->GetChar (character, &dummy)))
{
DrawParms parms;
va_list tags;
va_start(tags, tag_first);
Va_List tags;
va_start(tags.list, tag_first);
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
va_end(tags);
va_end(tags.list);
if (!res)
{
return;
@ -79,37 +84,61 @@ 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
//
// Write a string using the given font
//
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;
@ -118,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++;
@ -135,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;
@ -150,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);
@ -166,52 +195,61 @@ 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
void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...)
{
int w = 0;
int maxw = 0;
while (*string)
Va_List tags;
DrawParms parms;
if (font == NULL || string == NULL)
return;
va_start(tags.list, tag_first);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
va_end(tags.list);
if (!res)
{
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;
}
return MAX (maxw, w);
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;
}
//==========================================================================
//
// 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())
@ -223,20 +261,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<FBrokenLines> 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)
{
@ -283,14 +320,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;
@ -312,7 +349,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;
@ -321,20 +358,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;
}
@ -346,3 +388,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));
}

View file

@ -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__

View file

@ -1530,7 +1530,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
cy1 = MAX(cheight / designheight, 1);
cx2 = MAX(realwidth / designwidth, 1);
cy2 = MAX(realheight / designheight, 1);
if (abs(cx1 - cy1) <= abs(cx2 - cy2))
if (abs(cx1 - cy1) <= abs(cx2 - cy2) || cx1 >= 4)
{ // e.g. 640x360 looks better with this.
*cleanx = cx1;
*cleany = cy1;

View file

@ -177,6 +177,11 @@ struct DrawParms
bool virtBottom;
};
struct Va_List
{
va_list list;
};
struct VMVa_List
{
VMValue *args;
@ -270,8 +275,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;
@ -281,6 +288,8 @@ protected:
int LockCount;
bool Bgra;
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);

View file

@ -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.";

View file

@ -498,6 +498,7 @@ class Actor : Thinker native
native bool UsePuzzleItem(int PuzzleItemType);
native float AccuracyFactor();
native bool MorphMonster (Class<Actor> spawntype, int duration, int style, Class<Actor> enter_flash, Class<Actor> exit_flash);
native void SetCamera(Actor cam, bool revert = false);
// DECORATE compatible functions
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);

View file

@ -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
@ -66,17 +124,33 @@ 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
{
native int Count();
native int StringWidth(int line);
native String StringAt(int line);
}
struct Font native
{
native static Font FindFont(String name);
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);
native static BrokenLines BreakLines(String text, int maxlen);
}
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
@ -345,7 +419,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

View file

@ -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);
}
}

View file

@ -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);
}