mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- backend update from GZDoom.
This commit is contained in:
parent
8b03abcd00
commit
c82d9d2908
28 changed files with 178 additions and 53 deletions
|
@ -169,7 +169,7 @@ public:
|
|||
float screenFade = 1.f;
|
||||
DVector2 offset;
|
||||
public:
|
||||
int fullscreenautoaspect = 0;
|
||||
int fullscreenautoaspect = 3;
|
||||
int cliptop = -1, clipleft = -1, clipwidth = -1, clipheight = -1;
|
||||
|
||||
int AddCommand(const RenderCommand *data);
|
||||
|
|
|
@ -350,9 +350,9 @@ void CalcFullscreenScale(DrawParms *parms, double srcwidth, double srcheight, in
|
|||
}
|
||||
|
||||
double aspect;
|
||||
if (srcheight == 200) aspect = srcwidth / 240.;
|
||||
else if (srcheight == 400) aspect = srcwidth / 480;
|
||||
else aspect = srcwidth / srcheight;
|
||||
if (srcheight == 200) srcheight = 240.;
|
||||
else if (srcheight == 400) srcheight = 480;
|
||||
aspect = srcwidth / srcheight;
|
||||
rect.left = rect.top = 0;
|
||||
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
|
||||
if (autoaspect == FSMode_ScaleToFit43 || autoaspect == FSMode_ScaleToFit43Top || autoaspect == FSMode_ScaleToFit43Bottom)
|
||||
|
@ -366,7 +366,7 @@ void CalcFullscreenScale(DrawParms *parms, double srcwidth, double srcheight, in
|
|||
double width4_3 = srcheight * (4. / 3.);
|
||||
rect.width = (double)GetWidth() * srcwidth / width4_3;
|
||||
rect.height = GetHeight() * screenratio * (3. / 4.); // use 4:3 for the image
|
||||
rect.left = -(srcwidth - width4_3) / 2;
|
||||
rect.left = (double)GetWidth() * (-(srcwidth - width4_3) / 2) / width4_3;
|
||||
switch (oautoaspect)
|
||||
{
|
||||
default:
|
||||
|
@ -410,7 +410,15 @@ void CalcFullscreenScale(DrawParms *parms, double srcwidth, double srcheight, in
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, GetFullscreenRect)
|
||||
void GetFullscreenRect(double width, double height, int fsmode, DoubleRect* rect)
|
||||
{
|
||||
DrawParms parms;
|
||||
parms.viewport.width = twod->GetWidth();
|
||||
parms.viewport.height = twod->GetHeight();
|
||||
CalcFullscreenScale(&parms, width, height, fsmode, *rect);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Screen, GetFullscreenRect, GetFullscreenRect)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_FLOAT(virtw);
|
||||
|
|
|
@ -254,6 +254,8 @@ template<class T>
|
|||
void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms);
|
||||
bool SetTextureParms(F2DDrawer *drawer, DrawParms* parms, FGameTexture* img, double x, double y);
|
||||
|
||||
void GetFullscreenRect(double width, double height, int fsmode, DoubleRect* rect);
|
||||
|
||||
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...);
|
||||
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...);
|
||||
void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...);
|
||||
|
|
|
@ -50,7 +50,7 @@ int eventhead;
|
|||
int eventtail;
|
||||
event_t events[MAXEVENTS];
|
||||
|
||||
CVAR(Float, m_sensitivity_x, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, m_sensitivity_x, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, m_sensitivity_y, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
|
|
|
@ -1247,7 +1247,7 @@ void FScanner::AddSymbol(const char* name, uint64_t value)
|
|||
Symbol sym;
|
||||
sym.tokenType = TK_UIntConst;
|
||||
sym.Number = value;
|
||||
sym.Float = value;
|
||||
sym.Float = (double)value;
|
||||
symbols.Insert(name, sym);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ class FSingleLumpFont : public FFont
|
|||
{
|
||||
public:
|
||||
FSingleLumpFont (const char *fontname, int lump);
|
||||
void RecordAllTextureColors(uint32_t* usedcolors) override;
|
||||
|
||||
protected:
|
||||
void CheckFON1Chars (double *luminosity);
|
||||
|
@ -649,6 +650,32 @@ void FSingleLumpFont::FixupPalette (uint8_t *identity, double *luminosity, const
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// RecordAllTextureColors
|
||||
//
|
||||
// Given a 256 entry buffer, sets every entry that corresponds to a color
|
||||
// used by the font.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::RecordAllTextureColors(uint32_t* usedcolors)
|
||||
{
|
||||
double luminosity[256];
|
||||
uint8_t identity[256];
|
||||
PalEntry local_palette[256];
|
||||
|
||||
if (FontType == BMFFONT || FontType == FONT2)
|
||||
{
|
||||
FixupPalette(identity, luminosity, PaletteData, RescalePalette, local_palette);
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (identity[i] != 0) usedcolors[identity[i]]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFont *CreateSingleLumpFont (const char *fontname, int lump)
|
||||
{
|
||||
return new FSingleLumpFont(fontname, lump);
|
||||
|
|
|
@ -85,7 +85,8 @@ static int TranslationMapCompare (const void *a, const void *b);
|
|||
extern int PrintColors[];
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont, * CurrentConsoleFont, * OriginalSmallFont, * AlternativeSmallFont, * OriginalBigFont;
|
||||
FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont,
|
||||
* CurrentConsoleFont, * OriginalSmallFont, * AlternativeSmallFont, * OriginalBigFont, *AlternativeBigFont;
|
||||
|
||||
FFont *FFont::FirstFont = nullptr;
|
||||
int NumTextColors;
|
||||
|
|
|
@ -127,7 +127,7 @@ public:
|
|||
void SetCursor(char c) { Cursor = c; }
|
||||
void SetKerning(int c) { GlobalKerning = c; }
|
||||
bool NoTranslate() const { return noTranslate; }
|
||||
void RecordAllTextureColors(uint32_t *usedcolors);
|
||||
virtual void RecordAllTextureColors(uint32_t *usedcolors);
|
||||
virtual void SetDefaultTranslation(uint32_t *colors);
|
||||
void CheckCase();
|
||||
|
||||
|
@ -182,7 +182,7 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont, *OriginalSmallFont, *AlternativeSmallFont, *OriginalBigFont;
|
||||
extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont, *OriginalSmallFont, *AlternativeSmallFont, *OriginalBigFont, *AlternativeBigFont;
|
||||
|
||||
void V_InitFonts();
|
||||
void V_ClearFonts();
|
||||
|
|
|
@ -276,7 +276,18 @@ void UpdateGenericUI(bool cvar)
|
|||
AlternativeSmallFont = NewSmallFont;
|
||||
}
|
||||
|
||||
// Todo: Do the same for the BigFont
|
||||
if (CheckFontComplete(BigFont))
|
||||
{
|
||||
AlternativeBigFont = BigFont;
|
||||
}
|
||||
else if (OriginalBigFont && CheckFontComplete(OriginalBigFont))
|
||||
{
|
||||
AlternativeBigFont = OriginalBigFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
AlternativeBigFont = NewSmallFont;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -435,7 +435,7 @@ DObject *PClass::CreateNew()
|
|||
else
|
||||
memset (mem, 0, Size);
|
||||
|
||||
if (ConstructNative == nullptr)
|
||||
if (ConstructNative == nullptr || bAbstract)
|
||||
{
|
||||
M_Free(mem);
|
||||
I_Error("Attempt to instantiate abstract class %s.", TypeName.GetChars());
|
||||
|
|
|
@ -36,8 +36,11 @@ public:
|
|||
|
||||
void SetAABBTree(hwrenderer::LevelAABBTree* tree)
|
||||
{
|
||||
mAABBTree = tree;
|
||||
mNewTree = true;
|
||||
if (mAABBTree != tree)
|
||||
{
|
||||
mAABBTree = tree;
|
||||
mNewTree = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCollectLights(std::function<void()> func)
|
||||
|
|
|
@ -445,6 +445,7 @@ DEFINE_GLOBAL(ConFont)
|
|||
DEFINE_GLOBAL(NewConsoleFont)
|
||||
DEFINE_GLOBAL(NewSmallFont)
|
||||
DEFINE_GLOBAL(AlternativeSmallFont)
|
||||
DEFINE_GLOBAL(AlternativeBigFont)
|
||||
DEFINE_GLOBAL(OriginalSmallFont)
|
||||
DEFINE_GLOBAL(OriginalBigFont)
|
||||
DEFINE_GLOBAL(IntermissionFont)
|
||||
|
|
|
@ -6055,6 +6055,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
}
|
||||
|
||||
if (compileEnvironment.CheckSpecialGlobalIdentifier)
|
||||
{
|
||||
auto result = compileEnvironment.CheckSpecialGlobalIdentifier(this, ctx);
|
||||
if (result != this) return result;
|
||||
}
|
||||
|
||||
if (auto *cvar = FindCVar(Identifier.GetChars(), nullptr))
|
||||
{
|
||||
if (cvar->GetFlags() & CVAR_USERINFO)
|
||||
|
@ -8540,6 +8546,13 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (!result) return nullptr;
|
||||
}
|
||||
|
||||
// [Player701] Catch attempts to call abstract functions directly at compile time
|
||||
if (NoVirtual && Function->Variants[0].Implementation->VarFlags & VARF_Abstract)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Cannot call abstract function %s", Function->Variants[0].Implementation->PrintableName.GetChars());
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CallingFunction = ctx.Function;
|
||||
if (ArgList.Size() > 0)
|
||||
|
|
|
@ -2131,6 +2131,7 @@ struct CompileEnvironment
|
|||
FxExpression* (*SpecialTypeCast)(FxTypeCast* func, FCompileContext& ctx);
|
||||
bool (*CheckForCustomAddition)(FxAddSub* func, FCompileContext& ctx);
|
||||
FxExpression* (*CheckSpecialIdentifier)(FxIdentifier* func, FCompileContext& ctx);
|
||||
FxExpression* (*CheckSpecialGlobalIdentifier)(FxIdentifier* func, FCompileContext& ctx);
|
||||
FxExpression* (*ResolveSpecialIdentifier)(FxIdentifier* func, FxExpression*& object, PContainerType* objtype, FCompileContext& ctx);
|
||||
FxExpression* (*CheckSpecialMember)(FxStructMember* func, FCompileContext& ctx);
|
||||
FxExpression* (*CheckCustomGlobalFunctions)(FxFunctionCall* func, FCompileContext& ctx);
|
||||
|
|
|
@ -767,13 +767,16 @@ FFunctionBuildList FunctionBuildList;
|
|||
|
||||
VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo &ver, PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
|
||||
{
|
||||
auto func = code->GetDirectFunction(functype, ver);
|
||||
if (func != nullptr)
|
||||
if (code != nullptr)
|
||||
{
|
||||
delete code;
|
||||
auto func = code->GetDirectFunction(functype, ver);
|
||||
if (func != nullptr)
|
||||
{
|
||||
delete code;
|
||||
|
||||
|
||||
return func;
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
||||
//Printf("Adding %s\n", name.GetChars());
|
||||
|
@ -815,6 +818,10 @@ void FFunctionBuildList::Build()
|
|||
|
||||
for (auto &item : mItems)
|
||||
{
|
||||
// [Player701] Do not emit code for abstract functions
|
||||
bool isAbstract = item.Func->Variants[0].Implementation->VarFlags & VARF_Abstract;
|
||||
if (isAbstract) continue;
|
||||
|
||||
assert(item.Code != NULL);
|
||||
|
||||
// We don't know the return type in advance for anonymous functions.
|
||||
|
|
|
@ -87,11 +87,12 @@ template<class T> void ArrayDelete(T *self, int index, int count)
|
|||
|
||||
template<class T, class U, int fill = 1> void ArrayInsert(T *self, int index, U val)
|
||||
{
|
||||
//int oldSize = self->Size();
|
||||
int oldSize = self->Size();
|
||||
self->Insert(index, static_cast<typename T::value_type>(val));
|
||||
// Is this even necessary? All Insert does is inserting one defined element into the array and moving the rest.
|
||||
// It never creates empty tailing entries. fillcount in the macro will always be 0
|
||||
//if (fill) { DYNARRAY_FILL_ITEMS_SKIP(1); }
|
||||
if constexpr (fill)
|
||||
{
|
||||
for (unsigned i = oldSize; i < self->Size() - 1; i++) (*self)[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void ArrayShrinkToFit(T *self)
|
||||
|
@ -879,8 +880,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_Obj, Delete, ArrayDelete<FDynArray_Obj>)
|
|||
|
||||
void ObjArrayInsert(FDynArray_Obj *self,int index, DObject *obj)
|
||||
{
|
||||
int oldSize = self->Size();
|
||||
GC::WriteBarrier(obj);
|
||||
self->Insert(index, obj);
|
||||
for (unsigned i = oldSize; i < self->Size() - 1; i++) (*self)[i] = nullptr;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_Obj, Insert, ObjArrayInsert)
|
||||
|
|
|
@ -1042,7 +1042,7 @@ PName::PName()
|
|||
{
|
||||
mDescriptiveName = "Name";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FName) == alignof(FName));
|
||||
static_assert(sizeof(FName) == alignof(FName), "Name not properly aligned");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1172,7 +1172,7 @@ PTextureID::PTextureID()
|
|||
{
|
||||
mDescriptiveName = "TextureID";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FTextureID) == alignof(FTextureID));
|
||||
static_assert(sizeof(FTextureID) == alignof(FTextureID), "TextureID not properly aligned");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1214,7 +1214,7 @@ PSound::PSound()
|
|||
{
|
||||
mDescriptiveName = "Sound";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FSoundID) == alignof(FSoundID));
|
||||
static_assert(sizeof(FSoundID) == alignof(FSoundID), "SoundID not properly aligned");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1263,7 +1263,7 @@ PColor::PColor()
|
|||
{
|
||||
mDescriptiveName = "Color";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(PalEntry) == alignof(PalEntry));
|
||||
static_assert(sizeof(PalEntry) == alignof(PalEntry), "PalEntry not properly aligned");
|
||||
}
|
||||
|
||||
/* PStateLabel *****************************************************************/
|
||||
|
|
|
@ -36,6 +36,7 @@ enum
|
|||
VARF_Play = (1<<21), // [ZZ] play: object is playsim-scope only (can't access ui)
|
||||
VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only)
|
||||
VARF_ClearScope = (1<<23), // [ZZ] clearscope: this method ignores the member access chain that leads to it and is always plain data.
|
||||
VARF_Abstract = (1<<24), // [Player701] Function does not have a body and must be overridden in subclasses
|
||||
};
|
||||
|
||||
// Basic information shared by all types ------------------------------------
|
||||
|
|
|
@ -1214,6 +1214,7 @@ decl_flag(X) ::= READONLY(T). { X.Int = ZCC_ReadOnly; X.SourceLoc = T.SourceLoc
|
|||
decl_flag(X) ::= INTERNAL(T). { X.Int = ZCC_Internal; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= VIRTUAL(T). { X.Int = ZCC_Virtual; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= OVERRIDE(T). { X.Int = ZCC_Override; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= ABSTRACT(T). { X.Int = ZCC_Abstract; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= VARARG(T). { X.Int = ZCC_VarArg; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= UI(T). { X.Int = ZCC_UIFlag; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= PLAY(T). { X.Int = ZCC_Play; X.SourceLoc = T.SourceLoc; }
|
||||
|
|
|
@ -2042,7 +2042,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
} while (t != f->Type);
|
||||
}
|
||||
|
||||
int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Abstract | ZCC_Internal;
|
||||
int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Internal;
|
||||
|
||||
if (f->Flags & notallowed)
|
||||
{
|
||||
|
@ -2088,6 +2088,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
if (f->Flags & ZCC_Deprecated) varflags |= VARF_Deprecated;
|
||||
if (f->Flags & ZCC_Virtual) varflags |= VARF_Virtual;
|
||||
if (f->Flags & ZCC_Override) varflags |= VARF_Override;
|
||||
if (f->Flags & ZCC_Abstract) varflags |= VARF_Abstract;
|
||||
if (f->Flags & ZCC_VarArg) varflags |= VARF_VarArg;
|
||||
if (f->Flags & ZCC_FuncConst) varflags |= VARF_ReadOnly; // FuncConst method is internally marked as VARF_ReadOnly
|
||||
if (mVersion >= MakeVersion(2, 4, 0))
|
||||
|
@ -2131,7 +2132,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (varflags & VARF_Override) varflags &= ~VARF_Virtual; // allow 'virtual override'.
|
||||
// Only one of these flags may be used.
|
||||
static int exclude[] = { ZCC_Virtual, ZCC_Override, ZCC_Action, ZCC_Static };
|
||||
static int exclude[] = { ZCC_Abstract, ZCC_Virtual, ZCC_Override, ZCC_Action, ZCC_Static };
|
||||
int excludeflags = 0;
|
||||
int fc = 0;
|
||||
for (size_t i = 0; i < countof(exclude); i++)
|
||||
|
@ -2147,7 +2148,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
Error(f, "Invalid combination of qualifiers %s on function %s", FlagsToString(excludeflags).GetChars(), FName(f->Name).GetChars());
|
||||
varflags |= VARF_Method;
|
||||
}
|
||||
if (varflags & VARF_Override) varflags |= VARF_Virtual; // Now that the flags are checked, make all override functions virtual as well.
|
||||
if (varflags & (VARF_Override | VARF_Abstract)) varflags |= VARF_Virtual; // Now that the flags are checked, make all override and abstract functions virtual as well.
|
||||
|
||||
// [ZZ] this doesn't make sense either.
|
||||
if ((varflags&(VARF_ReadOnly | VARF_Method)) == VARF_ReadOnly) // non-method const function
|
||||
|
@ -2180,6 +2181,12 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (f->Flags & ZCC_Native)
|
||||
{
|
||||
if (varflags & VARF_Abstract)
|
||||
{
|
||||
Error(f, "Native functions cannot be abstract");
|
||||
return;
|
||||
}
|
||||
|
||||
varflags |= VARF_Native;
|
||||
afd = FindFunction(c->Type(), FName(f->Name).GetChars());
|
||||
if (afd == nullptr)
|
||||
|
@ -2371,19 +2378,20 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (!(f->Flags & ZCC_Native))
|
||||
{
|
||||
if (f->Body == nullptr)
|
||||
if (f->Body != nullptr && (varflags & VARF_Abstract))
|
||||
{
|
||||
Error(f, "Abstract function %s cannot have a body", FName(f->Name).GetChars());
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->Body == nullptr && !(varflags & VARF_Abstract))
|
||||
{
|
||||
Error(f, "Empty function %s", FName(f->Name).GetChars());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto code = ConvertAST(c->Type(), f->Body);
|
||||
if (code != nullptr)
|
||||
{
|
||||
newfunc = FunctionBuildList.AddFunction(OutNamespace, mVersion, sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
}
|
||||
}
|
||||
|
||||
FxExpression* code = f->Body != nullptr ? ConvertAST(c->Type(), f->Body) : nullptr;
|
||||
newfunc = FunctionBuildList.AddFunction(OutNamespace, mVersion, sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
}
|
||||
if (sym->Variants[0].Implementation != nullptr && hasdefault) // do not copy empty default lists, they only waste space and processing time.
|
||||
{
|
||||
|
@ -2408,6 +2416,12 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (forclass)
|
||||
{
|
||||
if ((varflags & VARF_Abstract) && !clstype->bAbstract)
|
||||
{
|
||||
Error(f, "Abstract functions can only be defined in abstract classes");
|
||||
return;
|
||||
}
|
||||
|
||||
auto parentfunc = clstype->ParentClass? dyn_cast<PFunction>(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr;
|
||||
|
||||
int vindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType);
|
||||
|
@ -2526,6 +2540,18 @@ void ZCCCompiler::InitFunctions()
|
|||
{
|
||||
CompileFunction(c, f, true);
|
||||
}
|
||||
|
||||
// [Player701] Make sure all abstract functions are overridden
|
||||
if (!c->ClassType()->bAbstract)
|
||||
{
|
||||
for (auto v : c->ClassType()->Virtuals)
|
||||
{
|
||||
if (v->VarFlags & VARF_Abstract)
|
||||
{
|
||||
Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,6 +284,13 @@ static bool CanJit(VMScriptFunction *func)
|
|||
|
||||
int VMScriptFunction::FirstScriptCall(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
||||
{
|
||||
// [Player701] Check that we aren't trying to call an abstract function.
|
||||
// This shouldn't happen normally, but if it does, let's catch this explicitly
|
||||
// rather than let GZDoom crash.
|
||||
if (func->VarFlags & VARF_Abstract)
|
||||
{
|
||||
ThrowAbortException(X_OTHER, "attempt to call abstract function %s.", func->PrintableName.GetChars());
|
||||
}
|
||||
#ifdef HAVE_VM_JIT
|
||||
if (vm_jit && CanJit(static_cast<VMScriptFunction*>(func)))
|
||||
{
|
||||
|
@ -654,7 +661,11 @@ CVMAbortException::CVMAbortException(EVMAbortException reason, const char *morei
|
|||
}
|
||||
if (moreinfo != nullptr)
|
||||
{
|
||||
AppendMessage(" ");
|
||||
// [Player701] avoid double space
|
||||
if (reason != X_OTHER)
|
||||
{
|
||||
AppendMessage(" ");
|
||||
}
|
||||
size_t len = strlen(m_Message);
|
||||
myvsnprintf(m_Message + len, MAX_ERRORTEXT - len, moreinfo, ap);
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ struct _ native // These are the global variables, the struct is only here to av
|
|||
native readonly Font NewConsoleFont;
|
||||
native readonly Font NewSmallFont;
|
||||
native readonly Font AlternativeSmallFont;
|
||||
native readonly Font AlternativeBigFont;
|
||||
native readonly Font OriginalSmallFont;
|
||||
native readonly Font OriginalBigFont;
|
||||
native readonly Font intermissionfont;
|
||||
|
|
|
@ -147,7 +147,7 @@ class ListMenu : Menu
|
|||
override bool MenuEvent (int mkey, bool fromcontroller)
|
||||
{
|
||||
int oldSelect = mDesc.mSelectedItem;
|
||||
int startedAt = mDesc.mSelectedItem;
|
||||
int startedAt = max(0, mDesc.mSelectedItem);
|
||||
|
||||
switch (mkey)
|
||||
{
|
||||
|
|
|
@ -293,13 +293,13 @@ class ListMenuItemTextItem : ListMenuItemSelectable
|
|||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
let font = generic_ui ? NewSmallFont : mFont;
|
||||
let font = menuDelegate.PickFont(mFont);
|
||||
DrawText(desc, font, selected ? mColorSelected : mColor, mXpos, mYpos, mText);
|
||||
}
|
||||
|
||||
|
||||
override int GetWidth()
|
||||
{
|
||||
let font = generic_ui? NewSmallFont : mFont;
|
||||
let font = menuDelegate.PickFont(mFont);
|
||||
return max(1, font.StringWidth(StringTable.Localize(mText)));
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ class ListMenuItemCaptionItem : ListMenuItem
|
|||
|
||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||
{
|
||||
let font = generic_ui || !desc.mFont ? NewSmallFont : desc.mFont;
|
||||
let font = menuDelegate.PickFont(desc.mFont);
|
||||
if (font && mText.Length() > 0)
|
||||
{
|
||||
menuDelegate.DrawCaption(mText, font, 0, true);
|
||||
|
|
|
@ -129,7 +129,7 @@ class LoadSaveMenu : ListMenu
|
|||
double wScale = Width43 / 640.;
|
||||
|
||||
savepicLeft = Left43 + int(20 * wScale);
|
||||
savepicTop = mDesc.mYpos * screen.GetHeight() / 200 ;
|
||||
savepicTop = int(mDesc.mYpos * screen.GetHeight() / 200);
|
||||
savepicWidth = int(240 * wScale);
|
||||
savepicHeight = int(180 * wScale);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class MenuDelegateBase ui
|
|||
{
|
||||
virtual int DrawCaption(String title, Font fnt, int y, bool drawit)
|
||||
{
|
||||
screen.DrawText(fnt, OptionMenuSettings.mTitleColor, (screen.GetWidth() - fnt.StringWidth(title) * CleanXfac_1) / 2, 10 * CleanYfac_1, title, DTA_CleanNoMove_1, true);
|
||||
if (drawit) screen.DrawText(fnt, OptionMenuSettings.mTitleColor, (screen.GetWidth() - fnt.StringWidth(title) * CleanXfac_1) / 2, 10 * CleanYfac_1, title, DTA_CleanNoMove_1, true);
|
||||
return (y + fnt.GetHeight()) * CleanYfac_1; // return is spacing in screen pixels.
|
||||
}
|
||||
|
||||
|
@ -22,4 +22,11 @@ class MenuDelegateBase ui
|
|||
// overriding this allows to execute special actions when the menu closes
|
||||
}
|
||||
|
||||
virtual Font PickFont(Font fnt)
|
||||
{
|
||||
if (generic_ui || !fnt) return NewSmallFont;
|
||||
if (fnt == SmallFont) return AlternativeSmallFont;
|
||||
if (fnt == BigFont) return AlternativeBigFont;
|
||||
return fnt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class MessageBoxMenu : Menu
|
|||
int mr2 = destWidth/2 + 10 + textFont.StringWidth(Stringtable.Localize("$TXT_NO"));
|
||||
mMouseRight = MAX(mr1, mr2);
|
||||
mParentMenu = parent;
|
||||
mMessage = textFont.BreakLines(Stringtable.Localize(message), 300/NotifyFontScale);
|
||||
mMessage = textFont.BreakLines(Stringtable.Localize(message), int(300/NotifyFontScale));
|
||||
mMessageMode = messagemode;
|
||||
if (playsound)
|
||||
{
|
||||
|
@ -106,8 +106,9 @@ class MessageBoxMenu : Menu
|
|||
|
||||
override void Drawer ()
|
||||
{
|
||||
int i, y;
|
||||
int fontheight = textFont.GetHeight() * NotifyFontScale;
|
||||
int i;
|
||||
double y;
|
||||
let fontheight = textFont.GetHeight() * NotifyFontScale;
|
||||
|
||||
y = destHeight / 2;
|
||||
|
||||
|
@ -124,7 +125,7 @@ class MessageBoxMenu : Menu
|
|||
if (mMessageMode == 0)
|
||||
{
|
||||
y += fontheight;
|
||||
mMouseY = y;
|
||||
mMouseY = int(y);
|
||||
screen.DrawText(textFont, messageSelection == 0? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, destWidth / 2, y, Stringtable.Localize("$TXT_YES"), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true, DTA_ScaleX, NotifyFontScale, DTA_ScaleY, NotifyFontScale);
|
||||
screen.DrawText(textFont, messageSelection == 1? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, destWidth / 2, y + fontheight, Stringtable.Localize("$TXT_NO"), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true, DTA_ScaleX, NotifyFontScale, DTA_ScaleY, NotifyFontScale);
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ class OptionMenu : Menu
|
|||
|
||||
if (y <= 0)
|
||||
{
|
||||
y = DrawCaption(mDesc.mTitle, y, false);
|
||||
y = DrawCaption(mDesc.mTitle, -y, false);
|
||||
}
|
||||
y *= CleanYfac_1;
|
||||
int rowheight = OptionMenuSettings.mLinespacing * CleanYfac_1;
|
||||
|
@ -430,7 +430,7 @@ class OptionMenu : Menu
|
|||
|
||||
virtual int DrawCaption(String title, int y, bool drawit)
|
||||
{
|
||||
let font = generic_ui || !mDesc.mFont ? NewSmallFont : mDesc.mFont;
|
||||
let font = menuDelegate.PickFont(mDesc.mFont);
|
||||
if (font && mDesc.mTitle.Length() > 0)
|
||||
{
|
||||
return menuDelegate.DrawCaption(title, font, y, drawit);
|
||||
|
|
Loading…
Reference in a new issue