mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
Merge remote-tracking branch 'gzdoom/master'
This commit is contained in:
commit
942f90a759
24 changed files with 529 additions and 152 deletions
|
@ -972,7 +972,7 @@ public:
|
||||||
{
|
{
|
||||||
SetOrigin(Pos() + vel, true);
|
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)
|
void SetOrigin(const DVector3 & npos, bool moving)
|
||||||
{
|
{
|
||||||
SetOrigin(npos.X, npos.Y, npos.Z, moving);
|
SetOrigin(npos.X, npos.Y, npos.Z, moving);
|
||||||
|
|
|
@ -1756,11 +1756,10 @@ void C_MidPrintBold (FFont *font, const char *msg)
|
||||||
DEFINE_ACTION_FUNCTION(_Console, MidPrint)
|
DEFINE_ACTION_FUNCTION(_Console, MidPrint)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_STRING(font);
|
PARAM_POINTER_NOT_NULL(fnt, FFont);
|
||||||
PARAM_STRING(text);
|
PARAM_STRING(text);
|
||||||
PARAM_BOOL_DEF(bold);
|
PARAM_BOOL_DEF(bold);
|
||||||
|
|
||||||
FFont *fnt = FFont::FindFont(font);
|
|
||||||
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
|
const char *txt = text[0] == '$'? GStrings(&text[1]) : text.GetChars();
|
||||||
if (!bold) C_MidPrint(fnt, txt);
|
if (!bold) C_MidPrint(fnt, txt);
|
||||||
else C_MidPrintBold(fnt, txt);
|
else C_MidPrintBold(fnt, txt);
|
||||||
|
|
|
@ -2464,6 +2464,9 @@ void D_DoomMain (void)
|
||||||
TexMan.Init();
|
TexMan.Init();
|
||||||
C_InitConback();
|
C_InitConback();
|
||||||
|
|
||||||
|
StartScreen->Progress();
|
||||||
|
V_InitFonts();
|
||||||
|
|
||||||
// [CW] Parse any TEAMINFO lumps.
|
// [CW] Parse any TEAMINFO lumps.
|
||||||
if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n");
|
if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n");
|
||||||
TeamLibrary.ParseTeamInfo ();
|
TeamLibrary.ParseTeamInfo ();
|
||||||
|
|
|
@ -88,6 +88,7 @@ PColor *TypeColor;
|
||||||
PTextureID *TypeTextureID;
|
PTextureID *TypeTextureID;
|
||||||
PSpriteID *TypeSpriteID;
|
PSpriteID *TypeSpriteID;
|
||||||
PStatePointer *TypeState;
|
PStatePointer *TypeState;
|
||||||
|
PPointer *TypeFont;
|
||||||
PStateLabel *TypeStateLabel;
|
PStateLabel *TypeStateLabel;
|
||||||
PStruct *TypeVector2;
|
PStruct *TypeVector2;
|
||||||
PStruct *TypeVector3;
|
PStruct *TypeVector3;
|
||||||
|
@ -437,6 +438,7 @@ void PType::StaticInit()
|
||||||
TypeVoidPtr = NewPointer(TypeVoid, false);
|
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.
|
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);
|
TypeStringStruct = NewNativeStruct("Stringstruct", nullptr);
|
||||||
|
TypeFont = NewPointer(NewNativeStruct("Font", nullptr));
|
||||||
#ifdef __BIG_ENDIAN__
|
#ifdef __BIG_ENDIAN__
|
||||||
TypeColorStruct->AddField(NAME_a, TypeUInt8);
|
TypeColorStruct->AddField(NAME_a, TypeUInt8);
|
||||||
TypeColorStruct->AddField(NAME_r, TypeUInt8);
|
TypeColorStruct->AddField(NAME_r, TypeUInt8);
|
||||||
|
|
|
@ -940,6 +940,7 @@ extern PStruct *TypeVector3;
|
||||||
extern PStruct *TypeColorStruct;
|
extern PStruct *TypeColorStruct;
|
||||||
extern PStruct *TypeStringStruct;
|
extern PStruct *TypeStringStruct;
|
||||||
extern PStatePointer *TypeState;
|
extern PStatePointer *TypeState;
|
||||||
|
extern PPointer *TypeFont;
|
||||||
extern PStateLabel *TypeStateLabel;
|
extern PStateLabel *TypeStateLabel;
|
||||||
extern PPointer *TypeNullPtr;
|
extern PPointer *TypeNullPtr;
|
||||||
extern PPointer *TypeVoidPtr;
|
extern PPointer *TypeVoidPtr;
|
||||||
|
|
|
@ -866,6 +866,14 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
// This should be done after postprocessing, not before.
|
// This should be done after postprocessing, not before.
|
||||||
mBuffers->BindCurrentFB();
|
mBuffers->BindCurrentFB();
|
||||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
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);
|
DrawBlend(lviewsector);
|
||||||
}
|
}
|
||||||
mDrawingScene2D = false;
|
mDrawingScene2D = false;
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
#include "math/cmath.h"
|
#include "math/cmath.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||||
|
|
||||||
|
@ -6913,3 +6914,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetSize)
|
||||||
|
|
||||||
ACTION_RETURN_BOOL(true);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -3196,6 +3196,7 @@ void P_NightmareRespawn (AActor *mobj)
|
||||||
|
|
||||||
// spawn it
|
// spawn it
|
||||||
mo = AActor::StaticSpawn(mobj->GetClass(), DVector3(mobj->SpawnPoint.X, mobj->SpawnPoint.Y, z), NO_REPLACE, true);
|
mo = AActor::StaticSpawn(mobj->GetClass(), DVector3(mobj->SpawnPoint.X, mobj->SpawnPoint.Y, z), NO_REPLACE, true);
|
||||||
|
mo->health = mobj->SpawnHealth();
|
||||||
|
|
||||||
if (z == ONFLOORZ)
|
if (z == ONFLOORZ)
|
||||||
{
|
{
|
||||||
|
|
|
@ -331,8 +331,6 @@ void R_Init ()
|
||||||
{
|
{
|
||||||
atterm (R_Shutdown);
|
atterm (R_Shutdown);
|
||||||
|
|
||||||
StartScreen->Progress();
|
|
||||||
V_InitFonts();
|
|
||||||
StartScreen->Progress();
|
StartScreen->Progress();
|
||||||
// Colormap init moved back to InitPalette()
|
// Colormap init moved back to InitPalette()
|
||||||
//R_InitColormaps ();
|
//R_InitColormaps ();
|
||||||
|
|
|
@ -1420,6 +1420,76 @@ ExpEmit FxSoundCast::Emit(VMFunctionBuilder *build)
|
||||||
return to;
|
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
|
// generic type cast operator
|
||||||
|
@ -1649,6 +1719,14 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
goto basereturn;
|
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.
|
// todo: pointers to class objects.
|
||||||
// All other types are only compatible to themselves and have already been handled above by the equality check.
|
// 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.
|
// Anything that falls through here is not compatible and must print an error.
|
||||||
|
|
|
@ -294,6 +294,7 @@ enum EFxType
|
||||||
EFX_StrLen,
|
EFX_StrLen,
|
||||||
EFX_ColorLiteral,
|
EFX_ColorLiteral,
|
||||||
EFX_GetDefaultByType,
|
EFX_GetDefaultByType,
|
||||||
|
EFX_FontCast,
|
||||||
EFX_COUNT
|
EFX_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -488,6 +489,13 @@ public:
|
||||||
isresolved = true;
|
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)
|
FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos)
|
||||||
{
|
{
|
||||||
value.pointer = nullptr;
|
value.pointer = nullptr;
|
||||||
|
@ -664,6 +672,18 @@ public:
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FxFontCast : public FxExpression
|
||||||
|
{
|
||||||
|
FxExpression *basex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FxFontCast(FxExpression *x);
|
||||||
|
~FxFontCast();
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxTypeCast
|
// FxTypeCast
|
||||||
|
|
|
@ -2187,17 +2187,17 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon
|
||||||
{
|
{
|
||||||
if (arc.isWriting())
|
if (arc.isWriting())
|
||||||
{
|
{
|
||||||
const char *n = font->GetName();
|
FName n = font->GetName();
|
||||||
return arc.StringPtr(key, n);
|
return arc(key, n);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *n;
|
FName n;
|
||||||
arc.StringPtr(key, n);
|
arc(key, n);
|
||||||
font = V_GetFont(n);
|
font = V_GetFont(n);
|
||||||
if (font == nullptr)
|
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;
|
font = SmallFont;
|
||||||
}
|
}
|
||||||
return arc;
|
return arc;
|
||||||
|
|
|
@ -129,12 +129,12 @@ static int PalFromRGB(uint32 rgb)
|
||||||
|
|
||||||
void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...)
|
void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...)
|
||||||
{
|
{
|
||||||
va_list tags;
|
Va_List tags;
|
||||||
va_start(tags, tags_first);
|
va_start(tags.list, tags_first);
|
||||||
DrawParms parms;
|
DrawParms parms;
|
||||||
|
|
||||||
bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false);
|
bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false);
|
||||||
va_end(tags);
|
va_end(tags.list);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -142,7 +142,7 @@ void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ..
|
||||||
DrawTextureParms(img, parms);
|
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)
|
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;
|
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.
|
// 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 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)
|
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.
|
// 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;
|
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,
|
void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
|
||||||
|
|
116
src/v_font.cpp
116
src/v_font.cpp
|
@ -94,6 +94,7 @@ The FON2 header is followed by variable length data:
|
||||||
#include "r_data/r_translate.h"
|
#include "r_data/r_translate.h"
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
|
#include "v_text.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -340,6 +341,14 @@ FFont *V_GetFont(const char *name)
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FFont, GetFont)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_NAME(name);
|
||||||
|
ACTION_RETURN_POINTER(V_GetFont(name.GetChars()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FFont :: FFont
|
// FFont :: FFont
|
||||||
|
@ -366,7 +375,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
LastChar = first + count - 1;
|
LastChar = first + count - 1;
|
||||||
FontHeight = 0;
|
FontHeight = 0;
|
||||||
GlobalKerning = false;
|
GlobalKerning = false;
|
||||||
Name = copystring (name);
|
FontName = name;
|
||||||
Next = FirstFont;
|
Next = FirstFont;
|
||||||
FirstFont = this;
|
FirstFont = this;
|
||||||
Cursor = '_';
|
Cursor = '_';
|
||||||
|
@ -478,11 +487,6 @@ FFont::~FFont ()
|
||||||
delete[] PatchRemap;
|
delete[] PatchRemap;
|
||||||
PatchRemap = NULL;
|
PatchRemap = NULL;
|
||||||
}
|
}
|
||||||
if (Name)
|
|
||||||
{
|
|
||||||
delete[] Name;
|
|
||||||
Name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FFont **prev = &FirstFont;
|
FFont **prev = &FirstFont;
|
||||||
FFont *font = *prev;
|
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;
|
FFont *font = FirstFont;
|
||||||
|
|
||||||
while (font != NULL)
|
while (font != nullptr)
|
||||||
{
|
{
|
||||||
if (stricmp (font->Name, name) == 0)
|
if (font->FontName == name) return font;
|
||||||
break;
|
|
||||||
font = font->Next;
|
font = font->Next;
|
||||||
}
|
}
|
||||||
return font;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FFont, FindFont)
|
DEFINE_ACTION_FUNCTION(FFont, FindFont)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
PARAM_STRING(name);
|
PARAM_NAME(name);
|
||||||
ACTION_RETURN_POINTER(FFont::FindFont(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;
|
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
|
// FFont :: LoadTranslations
|
||||||
|
@ -935,7 +997,7 @@ FFont::FFont (int lump)
|
||||||
Lump = lump;
|
Lump = lump;
|
||||||
Chars = NULL;
|
Chars = NULL;
|
||||||
PatchRemap = NULL;
|
PatchRemap = NULL;
|
||||||
Name = NULL;
|
FontName = NAME_None;
|
||||||
Cursor = '_';
|
Cursor = '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,7 +1013,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
|
||||||
{
|
{
|
||||||
assert(lump >= 0);
|
assert(lump >= 0);
|
||||||
|
|
||||||
Name = copystring (name);
|
FontName = name;
|
||||||
|
|
||||||
FMemLump data1 = Wads.ReadLump (lump);
|
FMemLump data1 = Wads.ReadLump (lump);
|
||||||
const BYTE *data = (const BYTE *)data1.GetMem();
|
const BYTE *data = (const BYTE *)data1.GetMem();
|
||||||
|
@ -1189,7 +1251,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
||||||
if (destSize < 0)
|
if (destSize < 0)
|
||||||
{
|
{
|
||||||
i += FirstChar;
|
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];
|
FTexture *pic = TexMan[picnum];
|
||||||
|
|
||||||
Name = copystring(picname);
|
FontName = picname;
|
||||||
FontHeight = pic->GetScaledHeight();
|
FontHeight = pic->GetScaledHeight();
|
||||||
SpaceWidth = pic->GetScaledWidth();
|
SpaceWidth = pic->GetScaledWidth();
|
||||||
GlobalKerning = 0;
|
GlobalKerning = 0;
|
||||||
|
@ -1905,7 +1967,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
|
|
||||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
||||||
|
|
||||||
Name = copystring(name);
|
FontName = name;
|
||||||
Chars = new CharData[count];
|
Chars = new CharData[count];
|
||||||
charlumps = new FTexture*[count];
|
charlumps = new FTexture*[count];
|
||||||
PatchRemap = new BYTE[256];
|
PatchRemap = new BYTE[256];
|
||||||
|
@ -2492,6 +2554,13 @@ EColorRange V_FindFontColor (FName name)
|
||||||
return CR_UNTRANSLATED;
|
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
|
// V_LogColorFromColorRange
|
||||||
|
@ -2666,12 +2735,3 @@ void V_ClearFonts()
|
||||||
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
|
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void V_RetranslateFonts()
|
|
||||||
{
|
|
||||||
FFont *font = FFont::FirstFont;
|
|
||||||
while(font)
|
|
||||||
{
|
|
||||||
font->LoadTranslations();
|
|
||||||
font = font->Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -88,9 +88,9 @@ public:
|
||||||
int GetDefaultKerning () const { return GlobalKerning; }
|
int GetDefaultKerning () const { return GlobalKerning; }
|
||||||
virtual void LoadTranslations();
|
virtual void LoadTranslations();
|
||||||
void Preload() const;
|
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();
|
static void StaticPreloadFonts();
|
||||||
|
|
||||||
// Return width of string in pixels (unscaled)
|
// Return width of string in pixels (unscaled)
|
||||||
|
@ -127,14 +127,13 @@ protected:
|
||||||
BYTE *PatchRemap;
|
BYTE *PatchRemap;
|
||||||
|
|
||||||
int Lump;
|
int Lump;
|
||||||
char *Name;
|
FName FontName;
|
||||||
FFont *Next;
|
FFont *Next;
|
||||||
|
|
||||||
static FFont *FirstFont;
|
static FFont *FirstFont;
|
||||||
friend struct FontsDeleter;
|
friend struct FontsDeleter;
|
||||||
|
|
||||||
friend void V_ClearFonts();
|
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);
|
EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor);
|
||||||
FFont *V_GetFont(const char *);
|
FFont *V_GetFont(const char *);
|
||||||
void V_InitFontColors();
|
void V_InitFontColors();
|
||||||
void V_RetranslateFonts();
|
|
||||||
|
|
||||||
#endif //__V_FONT_H__
|
#endif //__V_FONT_H__
|
||||||
|
|
253
src/v_text.cpp
253
src/v_text.cpp
|
@ -47,11 +47,16 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
|
||||||
|
int ListGetInt(VMVa_List &tags);
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DrawChar
|
// DrawChar
|
||||||
//
|
//
|
||||||
// Write a single character using the given font
|
// Write a single character using the given font
|
||||||
//
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...)
|
void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...)
|
||||||
{
|
{
|
||||||
if (font == NULL)
|
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)))
|
if (NULL != (pic = font->GetChar (character, &dummy)))
|
||||||
{
|
{
|
||||||
DrawParms parms;
|
DrawParms parms;
|
||||||
va_list tags;
|
Va_List tags;
|
||||||
va_start(tags, tag_first);
|
va_start(tags.list, tag_first);
|
||||||
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
|
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
|
||||||
va_end(tags);
|
va_end(tags.list);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
return;
|
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
|
// DrawText
|
||||||
//
|
//
|
||||||
// Write a string using the given font
|
// 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;
|
int w;
|
||||||
const BYTE *ch;
|
const BYTE *ch;
|
||||||
int c;
|
int c;
|
||||||
int cx;
|
double cx;
|
||||||
int cy;
|
double cy;
|
||||||
int boldcolor;
|
int boldcolor;
|
||||||
FRemapTable *range;
|
FRemapTable *range;
|
||||||
int kerning;
|
int kerning;
|
||||||
FTexture *pic;
|
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;
|
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
|
||||||
parms.celly *= parms.scaley;
|
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;
|
normalcolor = CR_UNTRANSLATED;
|
||||||
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
|
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;
|
ch = (const BYTE *)string;
|
||||||
cx = x;
|
cx = x;
|
||||||
cy = y;
|
cy = y;
|
||||||
|
|
||||||
|
|
||||||
while ((const char *)ch - string < parms.maxstrlen)
|
while ((const char *)ch - string < parms.maxstrlen)
|
||||||
{
|
{
|
||||||
c = *ch++;
|
c = *ch++;
|
||||||
|
@ -135,14 +164,14 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
|
||||||
|
|
||||||
if (c == TEXTCOLOR_ESCAPE)
|
if (c == TEXTCOLOR_ESCAPE)
|
||||||
{
|
{
|
||||||
EColorRange newcolor = V_ParseFontColor (ch, normalcolor, boldcolor);
|
EColorRange newcolor = V_ParseFontColor(ch, normalcolor, boldcolor);
|
||||||
if (newcolor != CR_UNDEFINED)
|
if (newcolor != CR_UNDEFINED)
|
||||||
{
|
{
|
||||||
range = font->GetColorTranslation (newcolor);
|
range = font->GetColorTranslation(newcolor);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
cx = x;
|
cx = x;
|
||||||
|
@ -150,7 +179,7 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != (pic = font->GetChar (c, &w)))
|
if (NULL != (pic = font->GetChar(c, &w)))
|
||||||
{
|
{
|
||||||
parms.remap = range;
|
parms.remap = range;
|
||||||
SetTextureParms(&parms, pic, cx, cy);
|
SetTextureParms(&parms, pic, cx, cy);
|
||||||
|
@ -166,52 +195,61 @@ 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, ...)
|
||||||
//
|
|
||||||
// Find string width using this font
|
|
||||||
//
|
|
||||||
int FFont::StringWidth (const BYTE *string) const
|
|
||||||
{
|
{
|
||||||
int w = 0;
|
Va_List tags;
|
||||||
int maxw = 0;
|
DrawParms parms;
|
||||||
|
|
||||||
while (*string)
|
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)
|
return;
|
||||||
{
|
|
||||||
++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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
DrawTextCommon(font, normalcolor, x, y, string, parms);
|
||||||
return MAX (maxw, w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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)
|
static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const BYTE *stop, FString &linecolor)
|
||||||
{
|
{
|
||||||
if (!linecolor.IsEmpty())
|
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);
|
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;
|
const BYTE *space = NULL, *start = string;
|
||||||
size_t i, ii;
|
|
||||||
int c, w, nw;
|
int c, w, nw;
|
||||||
FString lastcolor, linecolor;
|
FString lastcolor, linecolor;
|
||||||
bool lastWasSpace = false;
|
bool lastWasSpace = false;
|
||||||
int kerning = font->GetDefaultKerning ();
|
int kerning = font->GetDefaultKerning ();
|
||||||
|
|
||||||
i = w = 0;
|
w = 0;
|
||||||
|
|
||||||
while ( (c = *string++) && i < countof(lines) )
|
while ( (c = *string++) )
|
||||||
{
|
{
|
||||||
if (c == TEXTCOLOR_ESCAPE)
|
if (c == TEXTCOLOR_ESCAPE)
|
||||||
{
|
{
|
||||||
|
@ -283,14 +320,14 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
|
||||||
if (!space)
|
if (!space)
|
||||||
space = string - 1;
|
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)
|
if (c == '\n' && !preservecolor)
|
||||||
{
|
{
|
||||||
lastcolor = ""; // Why, oh why, did I do it like this?
|
lastcolor = ""; // Why, oh why, did I do it like this?
|
||||||
}
|
}
|
||||||
linecolor = lastcolor;
|
linecolor = lastcolor;
|
||||||
|
|
||||||
i++;
|
|
||||||
w = 0;
|
w = 0;
|
||||||
lastWasSpace = false;
|
lastWasSpace = false;
|
||||||
start = space;
|
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'
|
// String here is pointing one character after the '\0'
|
||||||
if (i < countof(lines) && --string - start >= 1)
|
if (--string - start >= 1)
|
||||||
{
|
{
|
||||||
const BYTE *s = start;
|
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 there is any non-white space in the remainder of the string, add it.
|
||||||
if (!isspace (*s++))
|
if (!isspace (*s++))
|
||||||
{
|
{
|
||||||
breakit (&lines[i++], font, start, string, linecolor);
|
auto i = Lines.Reserve(1);
|
||||||
|
breakit (&Lines[i], font, start, string, linecolor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a copy of the broken lines and return them
|
// 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;
|
return broken;
|
||||||
}
|
}
|
||||||
|
@ -346,3 +388,56 @@ void V_FreeBrokenLines (FBrokenLines *lines)
|
||||||
delete[] 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));
|
||||||
|
}
|
||||||
|
|
10
src/v_text.h
10
src/v_text.h
|
@ -75,11 +75,11 @@ struct FBrokenLines
|
||||||
#define TEXTCOLOR_CHAT "\034*"
|
#define TEXTCOLOR_CHAT "\034*"
|
||||||
#define TEXTCOLOR_TEAMCHAT "\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);
|
void V_FreeBrokenLines (FBrokenLines *lines);
|
||||||
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false)
|
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); }
|
{ return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor, count); }
|
||||||
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false)
|
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); }
|
{ return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor, count); }
|
||||||
|
|
||||||
#endif //__V_TEXT_H__
|
#endif //__V_TEXT_H__
|
||||||
|
|
|
@ -1530,7 +1530,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
|
||||||
cy1 = MAX(cheight / designheight, 1);
|
cy1 = MAX(cheight / designheight, 1);
|
||||||
cx2 = MAX(realwidth / designwidth, 1);
|
cx2 = MAX(realwidth / designwidth, 1);
|
||||||
cy2 = MAX(realheight / designheight, 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.
|
{ // e.g. 640x360 looks better with this.
|
||||||
*cleanx = cx1;
|
*cleanx = cx1;
|
||||||
*cleany = cy1;
|
*cleany = cy1;
|
||||||
|
|
|
@ -177,6 +177,11 @@ struct DrawParms
|
||||||
bool virtBottom;
|
bool virtBottom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Va_List
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
};
|
||||||
|
|
||||||
struct VMVa_List
|
struct VMVa_List
|
||||||
{
|
{
|
||||||
VMValue *args;
|
VMValue *args;
|
||||||
|
@ -270,8 +275,10 @@ public:
|
||||||
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
|
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
|
||||||
#endif
|
#endif
|
||||||
// 2D Text drawing
|
// 2D Text drawing
|
||||||
void DrawText (FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...);
|
void DrawText(FFont *font, int normalcolor, double x, double 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, 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:
|
protected:
|
||||||
BYTE *Buffer;
|
BYTE *Buffer;
|
||||||
|
@ -281,6 +288,8 @@ protected:
|
||||||
int LockCount;
|
int LockCount;
|
||||||
bool Bgra;
|
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;
|
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;
|
void DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) = delete;
|
||||||
virtual void DrawTextureParms(FTexture *img, DrawParms &parms);
|
virtual void DrawTextureParms(FTexture *img, DrawParms &parms);
|
||||||
|
|
|
@ -1417,6 +1417,9 @@ TXT_KILLED_ORACLE = "You've Killed The Oracle!";
|
||||||
TXT_KILLED_MACIL = "You Killed Macil!";
|
TXT_KILLED_MACIL = "You Killed Macil!";
|
||||||
TXT_KILLED_LOREMASTER = "You've Killed the Loremaster!";
|
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
|
// Strife pickup messages
|
||||||
|
|
||||||
TXT_METALARMOR = "You picked up the Metal Armor.";
|
TXT_METALARMOR = "You picked up the Metal Armor.";
|
||||||
|
|
|
@ -498,6 +498,7 @@ class Actor : Thinker native
|
||||||
native bool UsePuzzleItem(int PuzzleItemType);
|
native bool UsePuzzleItem(int PuzzleItemType);
|
||||||
native float AccuracyFactor();
|
native float AccuracyFactor();
|
||||||
native bool MorphMonster (Class<Actor> spawntype, int duration, int style, Class<Actor> enter_flash, Class<Actor> exit_flash);
|
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
|
// DECORATE compatible functions
|
||||||
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
||||||
|
|
|
@ -32,6 +32,64 @@ struct TexMan
|
||||||
native static TextureID CheckForTexture(String name, int usetype, int flags = TryAny);
|
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
|
struct Screen native
|
||||||
{
|
{
|
||||||
enum EColorRange
|
enum EColorRange
|
||||||
|
@ -66,17 +124,33 @@ struct Screen native
|
||||||
native static int GetWidth();
|
native static int GetWidth();
|
||||||
native static int GetHeight();
|
native static int GetHeight();
|
||||||
native static void DrawHUDTexture(TextureID tex, double x, double y);
|
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
|
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
|
struct Console native
|
||||||
{
|
{
|
||||||
native static void HideConsole();
|
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
|
struct DamageTypeDefinition native
|
||||||
|
@ -345,7 +419,7 @@ struct StringStruct native
|
||||||
{
|
{
|
||||||
native void Replace(String pattern, String replacement);
|
native void Replace(String pattern, String replacement);
|
||||||
native static vararg String Format(String fmt, ...);
|
native static vararg String Format(String fmt, ...);
|
||||||
native vararg void AppendFormat(String fmt, ...);
|
native vararg void AppendFormat(String fmt, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Floor : Thinker native
|
class Floor : Thinker native
|
||||||
|
|
|
@ -9,7 +9,9 @@ extend class Object
|
||||||
|
|
||||||
deprecated static void C_MidPrint(string fontname, string textlabel, bool bold = false) // deprecated for 2.4.x
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -632,7 +632,7 @@ class RaiseAlarm : DummyStrifeItem
|
||||||
dropper.target.SoundAlert(dropper.target);
|
dropper.target.SoundAlert(dropper.target);
|
||||||
if (dropper.target.CheckLocalView(consoleplayer))
|
if (dropper.target.CheckLocalView(consoleplayer))
|
||||||
{
|
{
|
||||||
A_Log("You Fool! You've set off the alarm.");
|
Console.MidPrint(SmallFont, "$TXT_YOUFOOL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Destroy ();
|
Destroy ();
|
||||||
|
@ -672,7 +672,7 @@ class CloseDoor222 : DummyStrifeItem
|
||||||
{
|
{
|
||||||
if (dropper.target.CheckLocalView(consoleplayer))
|
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);
|
dropper.target.SoundAlert(dropper.target);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue