mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-20 19:12:07 +00:00
gave translations a dedicated scripted type.
This is needed for implementing reliable serialization of custom translations. As long as they are merely ints they cannot be restored on loading a savegame because the serialization code does not know that these variables are special.
This commit is contained in:
parent
3781c43aec
commit
f0c9b1765e
19 changed files with 341 additions and 34 deletions
|
@ -182,6 +182,7 @@ xx(Voidptr)
|
|||
xx(StateLabel)
|
||||
xx(SpriteID)
|
||||
xx(TextureID)
|
||||
xx(TranslationID)
|
||||
xx(Overlay)
|
||||
xx(IsValid)
|
||||
xx(IsNull)
|
||||
|
@ -272,6 +273,7 @@ xx(BuiltinFRandom)
|
|||
xx(BuiltinNameToClass)
|
||||
xx(BuiltinClassCast)
|
||||
xx(BuiltinFunctionPtrCast)
|
||||
xx(BuiltinFindTranslation)
|
||||
|
||||
xx(ScreenJobRunner)
|
||||
xx(Action)
|
||||
|
|
|
@ -42,6 +42,46 @@ struct FRemapTable
|
|||
private:
|
||||
};
|
||||
|
||||
|
||||
struct FTranslationID
|
||||
{
|
||||
public:
|
||||
FTranslationID() = default;
|
||||
|
||||
private:
|
||||
constexpr FTranslationID(int id) : ID(id)
|
||||
{
|
||||
}
|
||||
public:
|
||||
static constexpr FTranslationID fromInt(int i)
|
||||
{
|
||||
return FTranslationID(i);
|
||||
}
|
||||
FTranslationID(const FTranslationID& other) = default;
|
||||
FTranslationID& operator=(const FTranslationID& other) = default;
|
||||
bool operator !=(FTranslationID other) const
|
||||
{
|
||||
return ID != other.ID;
|
||||
}
|
||||
bool operator ==(FTranslationID other) const
|
||||
{
|
||||
return ID == other.ID;
|
||||
}
|
||||
bool operator ==(int other) const = delete;
|
||||
bool operator !=(int other) const = delete;
|
||||
constexpr int index() const
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
constexpr bool isvalid() const
|
||||
{
|
||||
return ID > 0;
|
||||
}
|
||||
private:
|
||||
|
||||
int ID;
|
||||
};
|
||||
|
||||
// A class that initializes unusued pointers to NULL. This is used so that when
|
||||
// the TAutoGrowArray below is expanded, the new elements will be NULLed.
|
||||
class FRemapTablePtr
|
||||
|
|
|
@ -167,7 +167,7 @@ std2:
|
|||
'vector2' { RET(TK_Vector2); }
|
||||
'vector3' { RET(TK_Vector3); }
|
||||
'map' { RET(TK_Map); }
|
||||
'mapiterator' { RET(TK_MapIterator); }
|
||||
'mapiterator' { RET(ParseVersion >= MakeVersion(4, 10, 0)? TK_MapIterator : TK_Identifier); }
|
||||
'array' { RET(TK_Array); }
|
||||
'function' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_FunctionType : TK_Identifier); }
|
||||
'in' { RET(TK_In); }
|
||||
|
|
|
@ -1196,6 +1196,21 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
|||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval)
|
||||
{
|
||||
int v = value.index();
|
||||
int* defv = (int*)defval;
|
||||
Serialize(arc, key, v, defv);
|
||||
value = FTranslationID::fromInt(v);
|
||||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This never uses defval and instead uses 'null' as default
|
||||
|
|
|
@ -20,6 +20,7 @@ class FSoundID;
|
|||
union FRenderStyle;
|
||||
class DObject;
|
||||
class FTextureID;
|
||||
struct FTranslationID;
|
||||
|
||||
inline bool nullcmp(const void *buffer, size_t length)
|
||||
{
|
||||
|
@ -240,6 +241,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
|
|||
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &sid, struct ModelOverride *def);
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
|
||||
|
||||
void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p);
|
||||
|
||||
|
|
|
@ -43,11 +43,13 @@
|
|||
#include "texturemanager.h"
|
||||
#include "m_random.h"
|
||||
#include "v_font.h"
|
||||
#include "palettecontainer.h"
|
||||
|
||||
|
||||
extern FRandom pr_exrandom;
|
||||
FMemArena FxAlloc(65536);
|
||||
CompileEnvironment compileEnvironment;
|
||||
int R_FindCustomTranslation(FName name);
|
||||
|
||||
struct FLOP
|
||||
{
|
||||
|
@ -161,6 +163,12 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos)
|
|||
PType* expected = ReturnProto->ReturnTypes[i];
|
||||
PType* actual = proto->ReturnTypes[i];
|
||||
if (swapped) std::swap(expected, actual);
|
||||
// this must pass for older ZScripts.
|
||||
if (Version < MakeVersion(4, 12, 0))
|
||||
{
|
||||
if (expected == TypeTranslationID) expected = TypeSInt32;
|
||||
if (actual == TypeTranslationID) actual = TypeSInt32;
|
||||
}
|
||||
|
||||
if (expected != actual && !AreCompatiblePointerTypes(expected, actual))
|
||||
{ // Incompatible
|
||||
|
@ -993,6 +1001,19 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
|||
|
||||
if (basex->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (basex->ValueType == TypeTranslationID)
|
||||
{
|
||||
// translation IDs must be entirely incompatible with ints, not even allowing an explicit conversion,
|
||||
// but since the type was only introduced in version 4.12, older ZScript versions must allow this conversion.
|
||||
if (ctx.Version < MakeVersion(4, 12, 0))
|
||||
{
|
||||
FxExpression* x = basex;
|
||||
x->ValueType = ValueType;
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
if (basex->ValueType->isNumeric() || Explicit) // names can be converted to int, but only with an explicit type cast.
|
||||
{
|
||||
FxExpression *x = basex;
|
||||
|
@ -1006,7 +1027,7 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
|||
// Ugh. This should abort, but too many mods fell into this logic hole somewhere, so this serious error needs to be reduced to a warning. :(
|
||||
// At least in ZScript, MSG_OPTERROR always means to report an error, not a warning so the problem only exists in DECORATE.
|
||||
if (!basex->isConstant())
|
||||
ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a name");
|
||||
ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a %s", basex->ValueType->DescriptiveName());
|
||||
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||
FxExpression * x = new FxConstant(0, ScriptPosition);
|
||||
delete this;
|
||||
|
@ -1127,7 +1148,8 @@ FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
|
|||
{
|
||||
// Ugh. This should abort, but too many mods fell into this logic hole somewhere, so this seroious error needs to be reduced to a warning. :(
|
||||
// At least in ZScript, MSG_OPTERROR always means to report an error, not a warning so the problem only exists in DECORATE.
|
||||
if (!basex->isConstant()) ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a name");
|
||||
if (!basex->isConstant())
|
||||
ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a %s", basex->ValueType->DescriptiveName());
|
||||
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||
FxExpression *x = new FxConstant(0.0, ScriptPosition);
|
||||
delete this;
|
||||
|
@ -1534,6 +1556,107 @@ ExpEmit FxSoundCast::Emit(VMFunctionBuilder *build)
|
|||
return to;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxTranslationCast::FxTranslationCast(FxExpression* x)
|
||||
: FxExpression(EFX_TranslationCast, x->ScriptPosition)
|
||||
{
|
||||
basex = x;
|
||||
ValueType = TypeTranslationID;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxTranslationCast::~FxTranslationCast()
|
||||
{
|
||||
SAFE_DELETE(basex);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression* FxTranslationCast::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(basex, ctx);
|
||||
|
||||
if (basex->ValueType->isInt())
|
||||
{
|
||||
// 0 is a valid constant for translations, meaning 'no translation at all'. note that this conversion ONLY allows a constant!
|
||||
if (basex->isConstant() && static_cast<FxConstant*>(basex)->GetValue().GetInt() == 0)
|
||||
{
|
||||
FxExpression* x = basex;
|
||||
x->ValueType = TypeTranslationID;
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
if (ctx.Version < MakeVersion(4, 12, 0))
|
||||
{
|
||||
// only allow this conversion as a fallback
|
||||
FxExpression* x = basex;
|
||||
x->ValueType = TypeTranslationID;
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
else if (basex->ValueType == TypeString || basex->ValueType == TypeName)
|
||||
{
|
||||
if (basex->isConstant())
|
||||
{
|
||||
ExpVal constval = static_cast<FxConstant*>(basex)->GetValue();
|
||||
FxExpression* x = new FxConstant(R_FindCustomTranslation(constval.GetName()), ScriptPosition);
|
||||
x->ValueType = TypeTranslationID;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
else if (basex->ValueType == TypeString)
|
||||
{
|
||||
basex = new FxNameCast(basex, true);
|
||||
basex = basex->Resolve(ctx);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
ScriptPosition.Message(MSG_ERROR, "Cannot convert to translation ID");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxTranslationCast::Emit(VMFunctionBuilder* build)
|
||||
{
|
||||
ExpEmit to(build, REGT_POINTER);
|
||||
|
||||
VMFunction* callfunc;
|
||||
auto sym = FindBuiltinFunction(NAME_BuiltinFindTranslation);
|
||||
|
||||
assert(sym);
|
||||
callfunc = sym->Variants[0].Implementation;
|
||||
|
||||
FunctionCallEmitter emitters(callfunc);
|
||||
emitters.AddParameter(build, basex);
|
||||
emitters.AddReturn(REGT_INT);
|
||||
return emitters.EmitCall(build);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1766,6 +1889,14 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
delete this;
|
||||
return x;
|
||||
}
|
||||
else if (ValueType == TypeTranslationID)
|
||||
{
|
||||
FxExpression* x = new FxTranslationCast(basex);
|
||||
x = x->Resolve(ctx);
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
else if (ValueType == TypeColor)
|
||||
{
|
||||
FxExpression *x = new FxColorCast(basex);
|
||||
|
@ -4639,6 +4770,7 @@ ExpEmit FxConcat::Emit(VMFunctionBuilder *build)
|
|||
else if (left->ValueType == TypeColor) cast = CAST_Co2S;
|
||||
else if (left->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
||||
else if (left->ValueType == TypeTextureID) cast = CAST_TID2S;
|
||||
else if (left->ValueType == TypeTranslationID) cast = CAST_U2S;
|
||||
else if (op1.RegType == REGT_POINTER) cast = CAST_P2S;
|
||||
else if (op1.RegType == REGT_INT) cast = CAST_I2S;
|
||||
else assert(false && "Bad type for string concatenation");
|
||||
|
@ -4672,6 +4804,7 @@ ExpEmit FxConcat::Emit(VMFunctionBuilder *build)
|
|||
else if (right->ValueType == TypeColor) cast = CAST_Co2S;
|
||||
else if (right->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
||||
else if (right->ValueType == TypeTextureID) cast = CAST_TID2S;
|
||||
else if (right->ValueType == TypeTranslationID) cast = CAST_U2S;
|
||||
else if (op2.RegType == REGT_POINTER) cast = CAST_P2S;
|
||||
else if (op2.RegType == REGT_INT) cast = CAST_I2S;
|
||||
else assert(false && "Bad type for string concatenation");
|
||||
|
@ -5143,11 +5276,24 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx)
|
|||
ValueType = truex->ValueType;
|
||||
else if (falsex->IsPointer() && truex->ValueType == TypeNullPtr)
|
||||
ValueType = falsex->ValueType;
|
||||
// translation IDs need a bit of glue for compatibility and the 0 literal.
|
||||
else if (truex->IsInteger() && falsex->ValueType == TypeTranslationID)
|
||||
{
|
||||
truex = new FxTranslationCast(truex);
|
||||
truex = truex->Resolve(ctx);
|
||||
ValueType = ctx.Version < MakeVersion(4, 12, 0)? TypeSInt32 : TypeTranslationID;
|
||||
}
|
||||
else if (falsex->IsInteger() && truex->ValueType == TypeTranslationID)
|
||||
{
|
||||
falsex = new FxTranslationCast(falsex);
|
||||
falsex = falsex->Resolve(ctx);
|
||||
ValueType = ctx.Version < MakeVersion(4, 12, 0) ? TypeSInt32 : TypeTranslationID;
|
||||
}
|
||||
|
||||
else
|
||||
ValueType = TypeVoid;
|
||||
//else if (truex->ValueType != falsex->ValueType)
|
||||
|
||||
if (ValueType->GetRegType() == REGT_NIL)
|
||||
if (truex == nullptr || falsex == nullptr || ValueType->GetRegType() == REGT_NIL)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible types for ?: operator");
|
||||
delete this;
|
||||
|
@ -8279,6 +8425,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
|||
MethodName == NAME_Name ? TypeName :
|
||||
MethodName == NAME_SpriteID ? TypeSpriteID :
|
||||
MethodName == NAME_TextureID ? TypeTextureID :
|
||||
MethodName == NAME_TranslationID ? TypeTranslationID :
|
||||
MethodName == NAME_State ? TypeState :
|
||||
MethodName == NAME_Color ? TypeColor : (PType*)TypeSound;
|
||||
|
||||
|
|
|
@ -232,6 +232,7 @@ enum EFxType
|
|||
EFX_StringCast,
|
||||
EFX_ColorCast,
|
||||
EFX_SoundCast,
|
||||
EFX_TranslationCast,
|
||||
EFX_TypeCast,
|
||||
EFX_PlusSign,
|
||||
EFX_MinusSign,
|
||||
|
@ -715,6 +716,19 @@ public:
|
|||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
class FxTranslationCast : public FxExpression
|
||||
{
|
||||
FxExpression* basex;
|
||||
|
||||
public:
|
||||
|
||||
FxTranslationCast(FxExpression* x);
|
||||
~FxTranslationCast();
|
||||
FxExpression* Resolve(FCompileContext&);
|
||||
|
||||
ExpEmit Emit(VMFunctionBuilder* build);
|
||||
};
|
||||
|
||||
class FxFontCast : public FxExpression
|
||||
{
|
||||
FxExpression *basex;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "printf.h"
|
||||
#include "textureid.h"
|
||||
#include "maps.h"
|
||||
#include "palettecontainer.h"
|
||||
|
||||
|
||||
FTypeTable TypeTable;
|
||||
|
@ -58,6 +59,7 @@ PName *TypeName;
|
|||
PSound *TypeSound;
|
||||
PColor *TypeColor;
|
||||
PTextureID *TypeTextureID;
|
||||
PTranslationID* TypeTranslationID;
|
||||
PSpriteID *TypeSpriteID;
|
||||
PStatePointer *TypeState;
|
||||
PPointer *TypeFont;
|
||||
|
@ -322,6 +324,7 @@ void PType::StaticInit()
|
|||
TypeTable.AddType(TypeNullPtr = new PPointer, NAME_Pointer);
|
||||
TypeTable.AddType(TypeSpriteID = new PSpriteID, NAME_SpriteID);
|
||||
TypeTable.AddType(TypeTextureID = new PTextureID, NAME_TextureID);
|
||||
TypeTable.AddType(TypeTranslationID = new PTranslationID, NAME_TranslationID);
|
||||
|
||||
TypeVoidPtr = NewPointer(TypeVoid, false);
|
||||
TypeRawFunction = new PPointer;
|
||||
|
@ -1321,6 +1324,48 @@ bool PTextureID::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
|||
return true;
|
||||
}
|
||||
|
||||
/* PTranslationID ******************************************************************/
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PTranslationID Default Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PTranslationID::PTranslationID()
|
||||
: PInt(sizeof(FTranslationID), true, false)
|
||||
{
|
||||
mDescriptiveName = "TranslationID";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
static_assert(sizeof(FTranslationID) == alignof(FTranslationID), "TranslationID not properly aligned");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PTranslationID :: WriteValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PTranslationID::WriteValue(FSerializer& ar, const char* key, const void* addr) const
|
||||
{
|
||||
FTranslationID val = *(FTranslationID*)addr;
|
||||
ar(key, val);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PTranslationID :: ReadValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool PTranslationID::ReadValue(FSerializer& ar, const char* key, void* addr) const
|
||||
{
|
||||
FTranslationID val;
|
||||
ar(key, val);
|
||||
*(FTranslationID*)addr = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* PSound *****************************************************************/
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -383,6 +383,15 @@ public:
|
|||
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
||||
};
|
||||
|
||||
class PTranslationID : public PInt
|
||||
{
|
||||
public:
|
||||
PTranslationID();
|
||||
|
||||
void WriteValue(FSerializer& ar, const char* key, const void* addr) const override;
|
||||
bool ReadValue(FSerializer& ar, const char* key, void* addr) const override;
|
||||
};
|
||||
|
||||
class PColor : public PInt
|
||||
{
|
||||
public:
|
||||
|
@ -712,6 +721,7 @@ extern PName *TypeName;
|
|||
extern PSound *TypeSound;
|
||||
extern PColor *TypeColor;
|
||||
extern PTextureID *TypeTextureID;
|
||||
extern PTranslationID* TypeTranslationID;
|
||||
extern PSpriteID *TypeSpriteID;
|
||||
extern PStruct* TypeVector2;
|
||||
extern PStruct* TypeVector3;
|
||||
|
|
|
@ -1886,6 +1886,12 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
retval = TypeTextureID;
|
||||
break;
|
||||
|
||||
case NAME_TranslationID:
|
||||
retval = TypeTranslationID;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
|
||||
break;
|
||||
|
|
|
@ -1372,3 +1372,38 @@ DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindFunction, FindFunctionPointer)
|
|||
ACTION_RETURN_POINTER(FindFunctionPointer(cls, fn.GetIndex()));
|
||||
}
|
||||
|
||||
int R_FindCustomTranslation(FName name);
|
||||
|
||||
static int ZFindTranslation(int intname)
|
||||
{
|
||||
return R_FindCustomTranslation(ENamedName(intname));
|
||||
}
|
||||
|
||||
static int MakeTransID(int g, int s)
|
||||
{
|
||||
return TRANSLATION(g, s);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Translation, GetID, ZFindTranslation)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(t);
|
||||
ACTION_RETURN_INT(ZFindTranslation(t));
|
||||
}
|
||||
|
||||
// same as above for the compiler which needs a class to look this up.
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinFindTranslation, ZFindTranslation)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(t);
|
||||
ACTION_RETURN_INT(ZFindTranslation(t));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Translation, MakeID, MakeTransID)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(g);
|
||||
PARAM_INT(t);
|
||||
ACTION_RETURN_INT(MakeTransID(g, t));
|
||||
}
|
||||
|
||||
|
|
|
@ -666,13 +666,6 @@ int R_FindCustomTranslation(FName name)
|
|||
return (t != nullptr)? *t : -1;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Translation, GetID)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_NAME(t);
|
||||
ACTION_RETURN_INT(R_FindCustomTranslation(t));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -218,7 +218,7 @@ class Actor : Thinker native
|
|||
native Inventory Inv;
|
||||
native uint8 smokecounter;
|
||||
native uint8 FriendPlayer;
|
||||
native uint Translation;
|
||||
native TranslationID Translation;
|
||||
native sound AttackSound;
|
||||
native sound DeathSound;
|
||||
native sound SeeSound;
|
||||
|
@ -253,7 +253,7 @@ class Actor : Thinker native
|
|||
native double StealthAlpha;
|
||||
native int WoundHealth; // Health needed to enter wound state
|
||||
native readonly color BloodColor;
|
||||
native readonly int BloodTranslation;
|
||||
native readonly TranslationID BloodTranslation;
|
||||
native int RenderHidden;
|
||||
native int RenderRequired;
|
||||
native int FriendlySeeBlocks;
|
||||
|
|
|
@ -2667,7 +2667,7 @@ class PSprite : Object native play
|
|||
native Bool firstTic;
|
||||
native bool InterpolateTic;
|
||||
native int Tics;
|
||||
native uint Translation;
|
||||
native TranslationID Translation;
|
||||
native bool bAddWeapon;
|
||||
native bool bAddBob;
|
||||
native bool bPowDouble;
|
||||
|
|
|
@ -51,25 +51,21 @@ extend struct Console
|
|||
|
||||
extend struct Translation
|
||||
{
|
||||
Color colors[256];
|
||||
|
||||
native int AddTranslation();
|
||||
native static bool SetPlayerTranslation(int group, int num, int plrnum, PlayerClass pclass);
|
||||
native static int GetID(Name transname);
|
||||
}
|
||||
|
||||
// This is needed because Actor contains a field named 'translation' which shadows the above.
|
||||
struct Translate version("4.5")
|
||||
{
|
||||
static int MakeID(int group, int num)
|
||||
static TranslationID MakeID(int group, int num)
|
||||
{
|
||||
return (group << 16) + num;
|
||||
return Translation.MakeID(group, num);
|
||||
}
|
||||
static bool SetPlayerTranslation(int group, int num, int plrnum, PlayerClass pclass)
|
||||
{
|
||||
return Translation.SetPlayerTranslation(group, num, plrnum, pclass);
|
||||
}
|
||||
static int GetID(Name transname)
|
||||
static TranslationID GetID(Name transname)
|
||||
{
|
||||
return Translation.GetID(transname);
|
||||
}
|
||||
|
@ -115,6 +111,7 @@ extend struct GameInfoStruct
|
|||
extend class Object
|
||||
{
|
||||
private native static Object BuiltinNewDoom(Class<Object> cls, int outerclass, int compatibility);
|
||||
private native static TranslationID BuiltinFindTranslation(Name nm);
|
||||
private native static int BuiltinCallLineSpecial(int special, Actor activator, int arg1, int arg2, int arg3, int arg4, int arg5);
|
||||
// These really should be global functions...
|
||||
native static String G_SkillName();
|
||||
|
|
|
@ -919,10 +919,11 @@ struct StringStruct native
|
|||
|
||||
struct Translation version("2.4")
|
||||
{
|
||||
static int MakeID(int group, int num)
|
||||
{
|
||||
return (group << 16) + num;
|
||||
}
|
||||
Color colors[256];
|
||||
|
||||
native TranslationID AddTranslation();
|
||||
native static TranslationID MakeID(int group, int num);
|
||||
native static TranslationID GetID(Name transname);
|
||||
}
|
||||
|
||||
// Convenient way to attach functions to Quat
|
||||
|
|
|
@ -141,12 +141,12 @@ class BlackScreen : ScreenJob
|
|||
class ImageScreen : SkippableScreenJob
|
||||
{
|
||||
int tilenum;
|
||||
int trans;
|
||||
TranslationID trans;
|
||||
int waittime; // in ms.
|
||||
bool cleared;
|
||||
TextureID texid;
|
||||
|
||||
ScreenJob Init(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0)
|
||||
ScreenJob Init(TextureID tile, int fade = fadein | fadeout, int wait = 3000, TranslationID translation = 0)
|
||||
{
|
||||
Super.Init(fade);
|
||||
waittime = wait;
|
||||
|
@ -156,7 +156,7 @@ class ImageScreen : SkippableScreenJob
|
|||
return self;
|
||||
}
|
||||
|
||||
ScreenJob InitNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0)
|
||||
ScreenJob InitNamed(String tex, int fade = fadein | fadeout, int wait = 3000, TranslationID translation = 0)
|
||||
{
|
||||
Super.Init(fade);
|
||||
waittime = wait;
|
||||
|
@ -166,12 +166,12 @@ class ImageScreen : SkippableScreenJob
|
|||
return self;
|
||||
}
|
||||
|
||||
static ScreenJob Create(TextureID tile, int fade = fadein | fadeout, int wait = 3000, int translation = 0)
|
||||
static ScreenJob Create(TextureID tile, int fade = fadein | fadeout, int wait = 3000, TranslationID translation = 0)
|
||||
{
|
||||
return new("ImageScreen").Init(tile, fade, wait, translation);
|
||||
}
|
||||
|
||||
static ScreenJob CreateNamed(String tex, int fade = fadein | fadeout, int wait = 3000, int translation = 0)
|
||||
static ScreenJob CreateNamed(String tex, int fade = fadein | fadeout, int wait = 3000, TranslationID translation = 0)
|
||||
{
|
||||
return new("ImageScreen").InitNamed(tex, fade, wait, translation);
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ class ListMenuItemPlayerDisplay : ListMenuItem
|
|||
|
||||
if (sprite.IsValid())
|
||||
{
|
||||
int trans = mTranslate? Translation.MakeID(TRANSLATION_Players, MAXPLAYERS) : 0;
|
||||
let trans = mTranslate? Translation.MakeID(TRANSLATION_Players, MAXPLAYERS) : 0;
|
||||
let tscale = TexMan.GetScaledSize(sprite);
|
||||
Scale.X *= sx * tscale.X;
|
||||
Scale.Y *= sy * tscale.Y;
|
||||
|
@ -357,7 +357,7 @@ class PlayerMenuPlayerDisplay : ListMenuItemPlayerDisplay
|
|||
|
||||
if (sprite.IsValid())
|
||||
{
|
||||
int trans = mTranslate? Translation.MakeID(TRANSLATION_Players, MAXPLAYERS) : 0;
|
||||
let trans = mTranslate? Translation.MakeID(TRANSLATION_Players, MAXPLAYERS) : 0;
|
||||
let tscale = TexMan.GetScaledSize(sprite);
|
||||
Scale.X *= CleanXfac_1 * tscale.X * 2;
|
||||
Scale.Y *= CleanYfac_1 * tscale.Y * 2;
|
||||
|
|
|
@ -755,7 +755,7 @@ class BaseStatusBar : StatusBarCore native
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
int GetTranslation() const
|
||||
TranslationID GetTranslation() const
|
||||
{
|
||||
if(gameinfo.gametype & GAME_Raven)
|
||||
return Translation.MakeID(TRANSLATION_PlayersExtra, CPlayer.mo.PlayerNumber());
|
||||
|
|
Loading…
Reference in a new issue