mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-22 12:11:17 +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
91eaa5411a
commit
990cf3eafc
27 changed files with 541 additions and 57 deletions
|
@ -182,6 +182,7 @@ xx(Voidptr)
|
||||||
xx(StateLabel)
|
xx(StateLabel)
|
||||||
xx(SpriteID)
|
xx(SpriteID)
|
||||||
xx(TextureID)
|
xx(TextureID)
|
||||||
|
xx(TranslationID)
|
||||||
xx(Overlay)
|
xx(Overlay)
|
||||||
xx(IsValid)
|
xx(IsValid)
|
||||||
xx(IsNull)
|
xx(IsNull)
|
||||||
|
@ -272,6 +273,7 @@ xx(BuiltinFRandom)
|
||||||
xx(BuiltinNameToClass)
|
xx(BuiltinNameToClass)
|
||||||
xx(BuiltinClassCast)
|
xx(BuiltinClassCast)
|
||||||
xx(BuiltinFunctionPtrCast)
|
xx(BuiltinFunctionPtrCast)
|
||||||
|
xx(BuiltinFindTranslation)
|
||||||
|
|
||||||
xx(ScreenJobRunner)
|
xx(ScreenJobRunner)
|
||||||
xx(Action)
|
xx(Action)
|
||||||
|
|
|
@ -820,4 +820,9 @@ bool FRemapTable::AddColors(int start, int count, const uint8_t*colors, int tran
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// placeholder
|
||||||
|
int R_FindCustomTranslation(FName name)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,46 @@ struct FRemapTable
|
||||||
private:
|
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
|
// 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.
|
// the TAutoGrowArray below is expanded, the new elements will be NULLed.
|
||||||
class FRemapTablePtr
|
class FRemapTablePtr
|
||||||
|
|
|
@ -167,7 +167,7 @@ std2:
|
||||||
'vector2' { RET(TK_Vector2); }
|
'vector2' { RET(TK_Vector2); }
|
||||||
'vector3' { RET(TK_Vector3); }
|
'vector3' { RET(TK_Vector3); }
|
||||||
'map' { RET(TK_Map); }
|
'map' { RET(TK_Map); }
|
||||||
'mapiterator' { RET(TK_MapIterator); }
|
'mapiterator' { RET(ParseVersion >= MakeVersion(4, 10, 0)? TK_MapIterator : TK_Identifier); }
|
||||||
'array' { RET(TK_Array); }
|
'array' { RET(TK_Array); }
|
||||||
'function' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_FunctionType : TK_Identifier); }
|
'function' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_FunctionType : TK_Identifier); }
|
||||||
'in' { RET(TK_In); }
|
'in' { RET(TK_In); }
|
||||||
|
|
|
@ -1196,6 +1196,21 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
||||||
return arc;
|
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
|
// This never uses defval and instead uses 'null' as default
|
||||||
|
|
|
@ -20,6 +20,7 @@ class FSoundID;
|
||||||
union FRenderStyle;
|
union FRenderStyle;
|
||||||
class DObject;
|
class DObject;
|
||||||
class FTextureID;
|
class FTextureID;
|
||||||
|
struct FTranslationID;
|
||||||
|
|
||||||
inline bool nullcmp(const void *buffer, size_t length)
|
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, FString &sid, FString *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *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, 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);
|
void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p);
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,13 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "v_font.h"
|
#include "v_font.h"
|
||||||
|
#include "palettecontainer.h"
|
||||||
|
|
||||||
|
|
||||||
extern FRandom pr_exrandom;
|
extern FRandom pr_exrandom;
|
||||||
FMemArena FxAlloc(65536);
|
FMemArena FxAlloc(65536);
|
||||||
CompileEnvironment compileEnvironment;
|
CompileEnvironment compileEnvironment;
|
||||||
|
int R_FindCustomTranslation(FName name);
|
||||||
|
|
||||||
struct FLOP
|
struct FLOP
|
||||||
{
|
{
|
||||||
|
@ -161,6 +163,12 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos)
|
||||||
PType* expected = ReturnProto->ReturnTypes[i];
|
PType* expected = ReturnProto->ReturnTypes[i];
|
||||||
PType* actual = proto->ReturnTypes[i];
|
PType* actual = proto->ReturnTypes[i];
|
||||||
if (swapped) std::swap(expected, actual);
|
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))
|
if (expected != actual && !AreCompatiblePointerTypes(expected, actual))
|
||||||
{ // Incompatible
|
{ // Incompatible
|
||||||
|
@ -993,6 +1001,19 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
if (basex->ValueType->GetRegType() == REGT_INT)
|
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.
|
if (basex->ValueType->isNumeric() || Explicit) // names can be converted to int, but only with an explicit type cast.
|
||||||
{
|
{
|
||||||
FxExpression *x = basex;
|
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. :(
|
// 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.
|
// 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())
|
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());
|
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||||
FxExpression * x = new FxConstant(0, ScriptPosition);
|
FxExpression * x = new FxConstant(0, ScriptPosition);
|
||||||
delete this;
|
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. :(
|
// 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.
|
// 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());
|
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||||
FxExpression *x = new FxConstant(0.0, ScriptPosition);
|
FxExpression *x = new FxConstant(0.0, ScriptPosition);
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -1534,6 +1556,107 @@ ExpEmit FxSoundCast::Emit(VMFunctionBuilder *build)
|
||||||
return to;
|
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;
|
delete this;
|
||||||
return x;
|
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)
|
else if (ValueType == TypeColor)
|
||||||
{
|
{
|
||||||
FxExpression *x = new FxColorCast(basex);
|
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 == TypeColor) cast = CAST_Co2S;
|
||||||
else if (left->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
else if (left->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
||||||
else if (left->ValueType == TypeTextureID) cast = CAST_TID2S;
|
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_POINTER) cast = CAST_P2S;
|
||||||
else if (op1.RegType == REGT_INT) cast = CAST_I2S;
|
else if (op1.RegType == REGT_INT) cast = CAST_I2S;
|
||||||
else assert(false && "Bad type for string concatenation");
|
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 == TypeColor) cast = CAST_Co2S;
|
||||||
else if (right->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
else if (right->ValueType == TypeSpriteID) cast = CAST_SID2S;
|
||||||
else if (right->ValueType == TypeTextureID) cast = CAST_TID2S;
|
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_POINTER) cast = CAST_P2S;
|
||||||
else if (op2.RegType == REGT_INT) cast = CAST_I2S;
|
else if (op2.RegType == REGT_INT) cast = CAST_I2S;
|
||||||
else assert(false && "Bad type for string concatenation");
|
else assert(false && "Bad type for string concatenation");
|
||||||
|
@ -5143,11 +5276,24 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx)
|
||||||
ValueType = truex->ValueType;
|
ValueType = truex->ValueType;
|
||||||
else if (falsex->IsPointer() && truex->ValueType == TypeNullPtr)
|
else if (falsex->IsPointer() && truex->ValueType == TypeNullPtr)
|
||||||
ValueType = falsex->ValueType;
|
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
|
else
|
||||||
ValueType = TypeVoid;
|
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");
|
ScriptPosition.Message(MSG_ERROR, "Incompatible types for ?: operator");
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -8279,6 +8425,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
MethodName == NAME_Name ? TypeName :
|
MethodName == NAME_Name ? TypeName :
|
||||||
MethodName == NAME_SpriteID ? TypeSpriteID :
|
MethodName == NAME_SpriteID ? TypeSpriteID :
|
||||||
MethodName == NAME_TextureID ? TypeTextureID :
|
MethodName == NAME_TextureID ? TypeTextureID :
|
||||||
|
MethodName == NAME_TranslationID ? TypeTranslationID :
|
||||||
MethodName == NAME_State ? TypeState :
|
MethodName == NAME_State ? TypeState :
|
||||||
MethodName == NAME_Color ? TypeColor : (PType*)TypeSound;
|
MethodName == NAME_Color ? TypeColor : (PType*)TypeSound;
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,7 @@ enum EFxType
|
||||||
EFX_StringCast,
|
EFX_StringCast,
|
||||||
EFX_ColorCast,
|
EFX_ColorCast,
|
||||||
EFX_SoundCast,
|
EFX_SoundCast,
|
||||||
|
EFX_TranslationCast,
|
||||||
EFX_TypeCast,
|
EFX_TypeCast,
|
||||||
EFX_PlusSign,
|
EFX_PlusSign,
|
||||||
EFX_MinusSign,
|
EFX_MinusSign,
|
||||||
|
@ -715,6 +716,19 @@ public:
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
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
|
class FxFontCast : public FxExpression
|
||||||
{
|
{
|
||||||
FxExpression *basex;
|
FxExpression *basex;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "textureid.h"
|
#include "textureid.h"
|
||||||
#include "maps.h"
|
#include "maps.h"
|
||||||
|
#include "palettecontainer.h"
|
||||||
|
|
||||||
|
|
||||||
FTypeTable TypeTable;
|
FTypeTable TypeTable;
|
||||||
|
@ -58,6 +59,7 @@ PName *TypeName;
|
||||||
PSound *TypeSound;
|
PSound *TypeSound;
|
||||||
PColor *TypeColor;
|
PColor *TypeColor;
|
||||||
PTextureID *TypeTextureID;
|
PTextureID *TypeTextureID;
|
||||||
|
PTranslationID* TypeTranslationID;
|
||||||
PSpriteID *TypeSpriteID;
|
PSpriteID *TypeSpriteID;
|
||||||
PStatePointer *TypeState;
|
PStatePointer *TypeState;
|
||||||
PPointer *TypeFont;
|
PPointer *TypeFont;
|
||||||
|
@ -322,6 +324,7 @@ void PType::StaticInit()
|
||||||
TypeTable.AddType(TypeNullPtr = new PPointer, NAME_Pointer);
|
TypeTable.AddType(TypeNullPtr = new PPointer, NAME_Pointer);
|
||||||
TypeTable.AddType(TypeSpriteID = new PSpriteID, NAME_SpriteID);
|
TypeTable.AddType(TypeSpriteID = new PSpriteID, NAME_SpriteID);
|
||||||
TypeTable.AddType(TypeTextureID = new PTextureID, NAME_TextureID);
|
TypeTable.AddType(TypeTextureID = new PTextureID, NAME_TextureID);
|
||||||
|
TypeTable.AddType(TypeTranslationID = new PTranslationID, NAME_TranslationID);
|
||||||
|
|
||||||
TypeVoidPtr = NewPointer(TypeVoid, false);
|
TypeVoidPtr = NewPointer(TypeVoid, false);
|
||||||
TypeRawFunction = new PPointer;
|
TypeRawFunction = new PPointer;
|
||||||
|
@ -1321,6 +1324,48 @@ bool PTextureID::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||||
return true;
|
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 *****************************************************************/
|
/* PSound *****************************************************************/
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -383,6 +383,15 @@ public:
|
||||||
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
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
|
class PColor : public PInt
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -712,6 +721,7 @@ extern PName *TypeName;
|
||||||
extern PSound *TypeSound;
|
extern PSound *TypeSound;
|
||||||
extern PColor *TypeColor;
|
extern PColor *TypeColor;
|
||||||
extern PTextureID *TypeTextureID;
|
extern PTextureID *TypeTextureID;
|
||||||
|
extern PTranslationID* TypeTranslationID;
|
||||||
extern PSpriteID *TypeSpriteID;
|
extern PSpriteID *TypeSpriteID;
|
||||||
extern PStruct* TypeVector2;
|
extern PStruct* TypeVector2;
|
||||||
extern PStruct* TypeVector3;
|
extern PStruct* TypeVector3;
|
||||||
|
|
|
@ -1886,6 +1886,12 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
||||||
retval = TypeTextureID;
|
retval = TypeTextureID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NAME_TranslationID:
|
||||||
|
retval = TypeTranslationID;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
|
retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1372,3 +1372,38 @@ DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindFunction, FindFunctionPointer)
|
||||||
ACTION_RETURN_POINTER(FindFunctionPointer(cls, fn.GetIndex()));
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ const char *GetVersionString();
|
||||||
#define RC_PRODUCTVERSION2 VERSIONSTR
|
#define RC_PRODUCTVERSION2 VERSIONSTR
|
||||||
// These are for content versioning.
|
// These are for content versioning.
|
||||||
#define VER_MAJOR 4
|
#define VER_MAJOR 4
|
||||||
#define VER_MINOR 11
|
#define VER_MINOR 12
|
||||||
#define VER_REVISION 100
|
#define VER_REVISION 0
|
||||||
|
|
||||||
#define ENG_MAJOR 1
|
#define ENG_MAJOR 1
|
||||||
#define ENG_MINOR 7
|
#define ENG_MINOR 7
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
version "4.11.100"
|
version "4.12"
|
||||||
|
|
||||||
|
// Generic engine code
|
||||||
#include "zscript/engine/base.zs"
|
#include "zscript/engine/base.zs"
|
||||||
#include "zscript/engine/dynarrays.zs"
|
#include "zscript/engine/dynarrays.zs"
|
||||||
#include "zscript/engine/inputevents.zs"
|
#include "zscript/engine/maps.zs"
|
||||||
#include "zscript/engine/dictionary.zs"
|
#include "zscript/engine/dictionary.zs"
|
||||||
#include "zscript/engine/screenjob.zs"
|
#include "zscript/engine/inputevents.zs"
|
||||||
|
#include "zscript/engine/service.zs"
|
||||||
#include "zscript/engine/ppshader.zs"
|
#include "zscript/engine/ppshader.zs"
|
||||||
|
#include "zscript/engine/screenjob.zs"
|
||||||
|
|
||||||
#include "zscript/engine/ui/menu/colorpickermenu.zs"
|
#include "zscript/engine/ui/menu/colorpickermenu.zs"
|
||||||
#include "zscript/engine/ui/menu/joystickmenu.zs"
|
#include "zscript/engine/ui/menu/joystickmenu.zs"
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct HudStats
|
||||||
int ammoselect;
|
int ammoselect;
|
||||||
|
|
||||||
Array<String> keyicons;
|
Array<String> keyicons;
|
||||||
Array<int> keytranslations;
|
Array<TranslationID> keytranslations;
|
||||||
|
|
||||||
Array<String> inventoryicons;
|
Array<String> inventoryicons;
|
||||||
Array<int> inventoryamounts; // negative values can be used for special states (-1: "ON", -2: "OFF", -3: "AUTO")
|
Array<int> inventoryamounts; // negative values can be used for special states (-1: "ON", -2: "OFF", -3: "AUTO")
|
||||||
|
@ -128,7 +128,7 @@ class AltHud ui
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void DrawImageToBox(TextureID tex, int x, int y, int w, int h, double trans = 0.75, bool animate = false, int translation = 0)
|
void DrawImageToBox(TextureID tex, int x, int y, int w, int h, double trans = 0.75, bool animate = false, TranslationID translation = 0)
|
||||||
{
|
{
|
||||||
double scale1, scale2;
|
double scale1, scale2;
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ class AltHud ui
|
||||||
|
|
||||||
if (icon.isValid())
|
if (icon.isValid())
|
||||||
{
|
{
|
||||||
int trans = 0;
|
TranslationID trans = 0;
|
||||||
if (currentStats.keytranslations.Size()) trans = currentStats.keytranslations[keyindex];
|
if (currentStats.keytranslations.Size()) trans = currentStats.keytranslations[keyindex];
|
||||||
DrawImageToBox(icon, x, y, 8, 10, 0.75, false, trans);
|
DrawImageToBox(icon, x, y, 8, 10, 0.75, false, trans);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -184,6 +184,7 @@ struct Vector3
|
||||||
struct _ native // These are the global variables, the struct is only here to avoid extending the parser for this.
|
struct _ native // These are the global variables, the struct is only here to avoid extending the parser for this.
|
||||||
{
|
{
|
||||||
native readonly Array<class> AllClasses;
|
native readonly Array<class> AllClasses;
|
||||||
|
native internal readonly Map<Name , Service> AllServices;
|
||||||
native readonly bool multiplayer;
|
native readonly bool multiplayer;
|
||||||
native @KeyBindings Bindings;
|
native @KeyBindings Bindings;
|
||||||
native @KeyBindings AutomapBindings;
|
native @KeyBindings AutomapBindings;
|
||||||
|
@ -752,6 +753,7 @@ class Object native
|
||||||
private native static void BuiltinRandomSeed(voidptr rng, int seed);
|
private native static void BuiltinRandomSeed(voidptr rng, int seed);
|
||||||
private native static Class<Object> BuiltinNameToClass(Name nm, Class<Object> filter);
|
private native static Class<Object> BuiltinNameToClass(Name nm, Class<Object> filter);
|
||||||
private native static Object BuiltinClassCast(Object inptr, Class<Object> test);
|
private native static Object BuiltinClassCast(Object inptr, Class<Object> test);
|
||||||
|
private native static Function<void> BuiltinFunctionPtrCast(Function<void> inptr, voidptr newtype);
|
||||||
|
|
||||||
native static uint MSTime();
|
native static uint MSTime();
|
||||||
native static double MSTimeF();
|
native static double MSTimeF();
|
||||||
|
@ -922,10 +924,11 @@ struct StringStruct native
|
||||||
|
|
||||||
struct Translation version("2.4")
|
struct Translation version("2.4")
|
||||||
{
|
{
|
||||||
static int MakeID(int group, int num)
|
Color colors[256];
|
||||||
{
|
|
||||||
return (group << 16) + num;
|
//native TranslationID AddTranslation(); // this still needs work.
|
||||||
}
|
native static TranslationID MakeID(int group, int num);
|
||||||
|
native static TranslationID GetID(Name transname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenient way to attach functions to Quat
|
// Convenient way to attach functions to Quat
|
||||||
|
|
|
@ -141,12 +141,12 @@ class BlackScreen : ScreenJob
|
||||||
class ImageScreen : SkippableScreenJob
|
class ImageScreen : SkippableScreenJob
|
||||||
{
|
{
|
||||||
int tilenum;
|
int tilenum;
|
||||||
int trans;
|
TranslationID trans;
|
||||||
int waittime; // in ms.
|
int waittime; // in ms.
|
||||||
bool cleared;
|
bool cleared;
|
||||||
TextureID texid;
|
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);
|
Super.Init(fade);
|
||||||
waittime = wait;
|
waittime = wait;
|
||||||
|
@ -156,7 +156,7 @@ class ImageScreen : SkippableScreenJob
|
||||||
return self;
|
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);
|
Super.Init(fade);
|
||||||
waittime = wait;
|
waittime = wait;
|
||||||
|
@ -166,12 +166,12 @@ class ImageScreen : SkippableScreenJob
|
||||||
return self;
|
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);
|
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);
|
return new("ImageScreen").InitNamed(tex, fade, wait, translation);
|
||||||
}
|
}
|
||||||
|
@ -622,13 +622,13 @@ class TextOverlay
|
||||||
{
|
{
|
||||||
int nHeight;
|
int nHeight;
|
||||||
double nCrawlY;
|
double nCrawlY;
|
||||||
int palette;
|
TranslationID palette;
|
||||||
int crange;
|
int crange;
|
||||||
bool drawclean;
|
bool drawclean;
|
||||||
BrokenLines screentext;
|
BrokenLines screentext;
|
||||||
Font myfont;
|
Font myfont;
|
||||||
|
|
||||||
void Init(String text, int cr = Font.CR_NATIVEPAL, int pal = 0, bool clean = false)
|
void Init(String text, int cr = Font.CR_NATIVEPAL, TranslationID pal = 0, bool clean = false)
|
||||||
{
|
{
|
||||||
myfont = SmallFont; // todo
|
myfont = SmallFont; // todo
|
||||||
screentext = myfont.BreakLines(StringTable.Localize(text), 320);
|
screentext = myfont.BreakLines(StringTable.Localize(text), 320);
|
||||||
|
|
155
wadsrc/static/zscript/engine/service.zs
Normal file
155
wadsrc/static/zscript/engine/service.zs
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* This is Service interface.
|
||||||
|
*/
|
||||||
|
class Service abstract
|
||||||
|
{
|
||||||
|
deprecated("4.6.1", "Use GetString() instead") virtual play String Get(String request)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated("4.6.1", "Use GetStringUI() instead") virtual ui String UiGet(String request)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play variants
|
||||||
|
virtual play String GetString(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual play int GetInt(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual play double GetDouble(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual play Object GetObject(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual play Name GetName(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// UI variants
|
||||||
|
virtual ui String GetStringUI(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ui int GetIntUI(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ui double GetDoubleUI(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ui Object GetObjectUI(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ui Name GetNameUI(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// data/clearscope variants
|
||||||
|
virtual clearscope String GetStringData(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual clearscope int GetIntData(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual clearscope double GetDoubleData(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual clearscope Object GetObjectData(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual clearscope Name GetNameData(String request, string stringArg = "", int intArg = 0, double doubleArg = 0, Object objectArg = null, Name nameArg = '')
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
static Service Find(class<Service> serviceName){
|
||||||
|
return AllServices.GetIfExists(serviceName.GetClassName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this class to find and iterate over services.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* ServiceIterator i = ServiceIterator.Find("MyService");
|
||||||
|
*
|
||||||
|
* Service s;
|
||||||
|
* while (s = i.Next())
|
||||||
|
* {
|
||||||
|
* String request = ...
|
||||||
|
* String answer = s.Get(request);
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* If no services are found, the all calls to Next() will return NULL.
|
||||||
|
*/
|
||||||
|
class ServiceIterator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a Service iterator for a service name. It will iterate over all existing Services
|
||||||
|
* with names that match @a serviceName or have it as a part of their names.
|
||||||
|
*
|
||||||
|
* Matching is case-independent.
|
||||||
|
*
|
||||||
|
* @param serviceName class name of service to find.
|
||||||
|
*/
|
||||||
|
static ServiceIterator Find(String serviceName)
|
||||||
|
{
|
||||||
|
let result = new("ServiceIterator");
|
||||||
|
result.mServiceName = serviceName.MakeLower();
|
||||||
|
result.it.Init(AllServices);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the service and advances the iterator.
|
||||||
|
*
|
||||||
|
* @returns service instance, or NULL if no more services found.
|
||||||
|
*/
|
||||||
|
Service Next()
|
||||||
|
{
|
||||||
|
while(it.Next())
|
||||||
|
{
|
||||||
|
String cName = it.GetKey();
|
||||||
|
if(cName.MakeLower().IndexOf(mServiceName) != -1)
|
||||||
|
return it.GetValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapIterator<Name, Service> it;
|
||||||
|
private String mServiceName;
|
||||||
|
}
|
|
@ -36,7 +36,7 @@
|
||||||
struct KeyBindings native version("2.4")
|
struct KeyBindings native version("2.4")
|
||||||
{
|
{
|
||||||
native static String NameKeys(int k1, int k2);
|
native static String NameKeys(int k1, int k2);
|
||||||
native static String NameAllKeys(array<int> list);
|
native static String NameAllKeys(array<int> list, bool colors = true);
|
||||||
|
|
||||||
native int, int GetKeysForCommand(String cmd);
|
native int, int GetKeysForCommand(String cmd);
|
||||||
native void GetAllKeysForCommand(out array<int> list, String cmd);
|
native void GetAllKeysForCommand(out array<int> list, String cmd);
|
||||||
|
@ -349,16 +349,16 @@ class Menu : Object native ui version("2.4")
|
||||||
return OptionFont().GetHeight();
|
return OptionFont().GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OptionWidth(String s)
|
static int OptionWidth(String s, bool localize = true)
|
||||||
{
|
{
|
||||||
return OptionFont().StringWidth(s);
|
return OptionFont().StringWidth(s, localize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawOptionText(int x, int y, int color, String text, bool grayed = false)
|
static void DrawOptionText(int x, int y, int color, String text, bool grayed = false, bool localize = true)
|
||||||
{
|
{
|
||||||
String label = Stringtable.Localize(text);
|
String label = localize ? Stringtable.Localize(text) : text;
|
||||||
int overlay = grayed? Color(96,48,0,0) : 0;
|
int overlay = grayed? Color(96,48,0,0) : 0;
|
||||||
screen.DrawText (OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay);
|
screen.DrawText (OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, DTA_Localize, localize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,9 @@ class OptionMenuItem : MenuItemBase
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawValue(int indent, int y, int color, String text, bool grayed = false)
|
protected void drawValue(int indent, int y, int color, String text, bool grayed = false, bool localize = true)
|
||||||
{
|
{
|
||||||
Menu.DrawOptionText(indent + CursorSpace(), y, color, text, grayed);
|
Menu.DrawOptionText(indent + CursorSpace(), y, color, text, grayed, localize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -999,7 +999,7 @@ class OptionMenuFieldBase : OptionMenuItem
|
||||||
{
|
{
|
||||||
bool grayed = mGrayCheck != null && !mGrayCheck.GetInt();
|
bool grayed = mGrayCheck != null && !mGrayCheck.GetInt();
|
||||||
drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, grayed);
|
drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, grayed);
|
||||||
drawValue(indent, y, OptionMenuSettings.mFontColorValue, Represent(), grayed);
|
drawValue(indent, y, OptionMenuSettings.mFontColorValue, Represent(), grayed, false);
|
||||||
return indent;
|
return indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,7 +1068,7 @@ class OptionMenuItemTextField : OptionMenuFieldBase
|
||||||
{
|
{
|
||||||
// reposition the text so that the cursor is visible when in entering mode.
|
// reposition the text so that the cursor is visible when in entering mode.
|
||||||
String text = Represent();
|
String text = Represent();
|
||||||
int tlen = Menu.OptionWidth(text) * CleanXfac_1;
|
int tlen = Menu.OptionWidth(text, false) * CleanXfac_1;
|
||||||
int newindent = screen.GetWidth() - tlen - CursorSpace();
|
int newindent = screen.GetWidth() - tlen - CursorSpace();
|
||||||
if (newindent < indent) indent = newindent;
|
if (newindent < indent) indent = newindent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,13 +108,13 @@ class StatusBarCore native ui
|
||||||
|
|
||||||
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
|
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
|
||||||
native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);
|
native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);
|
||||||
native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0, double clipwidth = -1);
|
native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, TranslationID translation = 0, double clipwidth = -1);
|
||||||
native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0, double clipwidth = -1);
|
native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, TranslationID translation = 0, double clipwidth = -1);
|
||||||
|
|
||||||
native void DrawTextureRotated(TextureID texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0);
|
native void DrawTextureRotated(TextureID texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, TranslationID translation = 0);
|
||||||
native void DrawImageRotated(String texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, int translation = 0);
|
native void DrawImageRotated(String texid, Vector2 pos, int flags, double angle, double alpha = 1, Vector2 scale = (1, 1), ERenderStyle style = STYLE_Translucent, Color col = 0xffffffff, TranslationID translation = 0);
|
||||||
|
|
||||||
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4, Vector2 scale = (1, 1), int pt = 0, ERenderStyle style = STYLE_Translucent);
|
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4, Vector2 scale = (1, 1), TranslationID pt = 0, ERenderStyle style = STYLE_Translucent);
|
||||||
native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0);
|
native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0);
|
||||||
native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
|
native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
|
||||||
native void SetClipRect(double x, double y, double w, double h, int flags = 0);
|
native void SetClipRect(double x, double y, double w, double h, int flags = 0);
|
||||||
|
|
|
@ -62,7 +62,7 @@ class ListMenuItemBloodTextItem : ListMenuItemTextItem
|
||||||
let gamefont = Raze.PickBigFont();
|
let gamefont = Raze.PickBigFont();
|
||||||
int xpos = mXpos - gamefont.StringWidth(mText) / 2;
|
int xpos = mXpos - gamefont.StringWidth(mText) / 2;
|
||||||
int cr = generic_ui? Font.CR_GRAY : Font.CR_NATIVEPAL;
|
int cr = generic_ui? Font.CR_GRAY : Font.CR_NATIVEPAL;
|
||||||
int trans = generic_ui? 0 : Translation.MakeID(Translation_Remap, pal);
|
TranslationID trans = generic_ui? 0 : Translation.MakeID(Translation_Remap, pal);
|
||||||
|
|
||||||
if (selected) shade = 32 - ((MSTime() * 120 / 1000) & 63);
|
if (selected) shade = 32 - ((MSTime() * 120 / 1000) & 63);
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ class BloodStatusBar : RazeStatusBar
|
||||||
DrawTexture(Blood.PowerUpIcon(power), (x, y + powerYoffs[order]), DI_SCREEN_LEFT_CENTER | DI_ITEM_RELCENTER, scale:(powerScale[order], powerScale[order]));
|
DrawTexture(Blood.PowerUpIcon(power), (x, y + powerYoffs[order]), DI_SCREEN_LEFT_CENTER | DI_ITEM_RELCENTER, scale:(powerScale[order], powerScale[order]));
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawStatNumber("%d", remainingSeconds, "SBarNumberInv", x + 15, y, 0, remainingSeconds > warningTime ? 0 : Translation.MakeID(Translation_Remap, 2), 0.5, DI_SCREEN_LEFT_CENTER);
|
DrawStatNumber("%d", remainingSeconds, "SBarNumberInv", x + 15, y, 0, remainingSeconds > warningTime ? 0 : 2, 0.5, DI_SCREEN_LEFT_CENTER);
|
||||||
y += 20;
|
y += 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,8 +452,8 @@ class BloodStatusBar : RazeStatusBar
|
||||||
}
|
}
|
||||||
|
|
||||||
bool meHaveBlueFlag = pPlayer.hasFlag & 1;
|
bool meHaveBlueFlag = pPlayer.hasFlag & 1;
|
||||||
int trans10 = Translation.MakeID(Translation_Remap, 10);
|
let trans10 = Translation.MakeID(Translation_Remap, 10);
|
||||||
int trans2 = Translation.MakeID(Translation_Remap, 2);
|
let trans2 = Translation.MakeID(Translation_Remap, 2);
|
||||||
DrawImage(meHaveBlueFlag ? "FlagHave" : "FlagHaveNot", (0, 75 - 100), DI_SCREEN_RIGHT_CENTER|DI_ITEM_RELCENTER, scale:(0.35, 0.35), translation:trans10);
|
DrawImage(meHaveBlueFlag ? "FlagHave" : "FlagHaveNot", (0, 75 - 100), DI_SCREEN_RIGHT_CENTER|DI_ITEM_RELCENTER, scale:(0.35, 0.35), translation:trans10);
|
||||||
if (gBlueFlagDropped)
|
if (gBlueFlagDropped)
|
||||||
DrawImage("FlagDropped", (305 - 320, 83 - 100), DI_SCREEN_RIGHT_CENTER|DI_ITEM_RELCENTER, translation:trans10);
|
DrawImage("FlagDropped", (305 - 320, 83 - 100), DI_SCREEN_RIGHT_CENTER|DI_ITEM_RELCENTER, translation:trans10);
|
||||||
|
@ -507,7 +507,7 @@ class BloodStatusBar : RazeStatusBar
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int DrawStatusBar(BloodPlayer pPlayer, int nPalette)
|
int DrawStatusBar(BloodPlayer pPlayer, TranslationID nPalette)
|
||||||
{
|
{
|
||||||
int th = texHeight("Statusbar");
|
int th = texHeight("Statusbar");
|
||||||
BeginStatusBar(false, 320, 200, th);
|
BeginStatusBar(false, 320, 200, th);
|
||||||
|
@ -583,7 +583,7 @@ class BloodStatusBar : RazeStatusBar
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int DrawHUD1(BloodPlayer pPlayer, int nPalette)
|
int DrawHUD1(BloodPlayer pPlayer, TranslationID nPalette)
|
||||||
{
|
{
|
||||||
BeginHUD(1, false, 320, 200);
|
BeginHUD(1, false, 320, 200);
|
||||||
DrawImage("FullHUD", (34, 187 - 200), DI_ITEM_RELCENTER, style:STYLE_Normal, col:0xffc0c0c0, translation:nPalette);
|
DrawImage("FullHUD", (34, 187 - 200), DI_ITEM_RELCENTER, style:STYLE_Normal, col:0xffc0c0c0, translation:nPalette);
|
||||||
|
@ -726,19 +726,20 @@ class BloodStatusBar : RazeStatusBar
|
||||||
|
|
||||||
override void UpdateStatusBar(SummaryInfo summary)
|
override void UpdateStatusBar(SummaryInfo summary)
|
||||||
{
|
{
|
||||||
int nPalette = 0;
|
TranslationID nPalette = 0;
|
||||||
let pPlayer = Blood.GetViewPlayer();
|
let pPlayer = Blood.GetViewPlayer();
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
int nGameType = Blood.getGameType();
|
int nGameType = Blood.getGameType();
|
||||||
if (nGameType == 3)
|
if (nGameType == 3)
|
||||||
{
|
{
|
||||||
|
int pal;
|
||||||
if (pPlayer.teamId & 1)
|
if (pPlayer.teamId & 1)
|
||||||
nPalette = 7;
|
pal = 7;
|
||||||
else
|
else
|
||||||
nPalette = 10;
|
pal = 10;
|
||||||
|
|
||||||
nPalette = Translation.MakeID(Translation_Remap, nPalette);
|
nPalette = Translation.MakeID(Translation_Remap, pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hud_size == Hud_Full)
|
if (hud_size == Hud_Full)
|
||||||
|
|
|
@ -168,7 +168,7 @@ class ListMenuItemDukeTextItem : ListMenuItemTextItem
|
||||||
override void Draw(bool selected, ListMenuDescriptor desc)
|
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||||
{
|
{
|
||||||
let font = Raze.PickBigFont();
|
let font = Raze.PickBigFont();
|
||||||
int trans = mColorSelected? Translation.MakeID(Translation_Remap, 1) : 0;
|
TranslationID trans = mColorSelected? Translation.MakeID(Translation_Remap, 1) : 0;
|
||||||
Color pe;
|
Color pe;
|
||||||
double scale = (gameinfo.gametype & GAMEFLAG_RRALL) ? 0.4 : 1.;
|
double scale = (gameinfo.gametype & GAMEFLAG_RRALL) ? 0.4 : 1.;
|
||||||
let xpos = 160 - font.StringWidth(mText) * scale * 0.5;
|
let xpos = 160 - font.StringWidth(mText) * scale * 0.5;
|
||||||
|
|
|
@ -55,7 +55,7 @@ class DRealmsScreen : SkippableScreenJob
|
||||||
override void Draw(double smoothratio)
|
override void Draw(double smoothratio)
|
||||||
{
|
{
|
||||||
let tex = TexMan.CheckForTexture("DREALMS");
|
let tex = TexMan.CheckForTexture("DREALMS");
|
||||||
int translation = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.DREALMSPAL) : 0;
|
TranslationID translation = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.DREALMSPAL) : 0;
|
||||||
|
|
||||||
screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal);
|
screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||||
}
|
}
|
||||||
|
@ -116,11 +116,11 @@ class DukeTitleScreen : SkippableScreenJob
|
||||||
override void Draw(double smoothratio)
|
override void Draw(double smoothratio)
|
||||||
{
|
{
|
||||||
int clock = (ticks + smoothratio) * 120 / GameTicRate;
|
int clock = (ticks + smoothratio) * 120 / GameTicRate;
|
||||||
int etrans = Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL);
|
TranslationID etrans = Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL);
|
||||||
|
|
||||||
// Only translate if the image depends on the global palette.
|
// Only translate if the image depends on the global palette.
|
||||||
let tex = TexMan.CheckForTexture("BETASCREEN");
|
let tex = TexMan.CheckForTexture("BETASCREEN");
|
||||||
int trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
TranslationID trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
||||||
screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal);
|
screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||||
|
|
||||||
double scale = clamp(clock - 120, 0, 60) / 64.;
|
double scale = clamp(clock - 120, 0, 60) / 64.;
|
||||||
|
@ -251,10 +251,10 @@ class Episode1End1 : SkippableScreenJob
|
||||||
|
|
||||||
override void Draw(double sr)
|
override void Draw(double sr)
|
||||||
{
|
{
|
||||||
int etrans = Translation.MakeID(Translation_BasePalette, Duke.ENDINGPAL);
|
TranslationID etrans = Translation.MakeID(Translation_BasePalette, Duke.ENDINGPAL);
|
||||||
|
|
||||||
let tex = TexMan.CheckForTexture("VICTORY1");
|
let tex = TexMan.CheckForTexture("VICTORY1");
|
||||||
int trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
TranslationID trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
||||||
screen.DrawTexture(tex, false, 0, 50, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TopLeft, true);
|
screen.DrawTexture(tex, false, 0, 50, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TopLeft, true);
|
||||||
|
|
||||||
if (bossani.isValid())
|
if (bossani.isValid())
|
||||||
|
|
|
@ -462,7 +462,7 @@ class Cinema : SkippableScreenJob
|
||||||
TextureID cinematile;
|
TextureID cinematile;
|
||||||
int currentCinemaPalette;
|
int currentCinemaPalette;
|
||||||
int cdtrack;
|
int cdtrack;
|
||||||
int palette;
|
TranslationID palette;
|
||||||
bool done;
|
bool done;
|
||||||
|
|
||||||
ScreenJob Init(String bgTexture, String text, int pal, int cdtrk)
|
ScreenJob Init(String bgTexture, String text, int pal, int cdtrk)
|
||||||
|
|
|
@ -55,7 +55,7 @@ class SWDRealmsScreen : SkippableScreenJob
|
||||||
override void Draw(double sm)
|
override void Draw(double sm)
|
||||||
{
|
{
|
||||||
let tex = TexMan.CheckForTexture("THREED_REALMS_PIC", TexMan.Type_Any);
|
let tex = TexMan.CheckForTexture("THREED_REALMS_PIC", TexMan.Type_Any);
|
||||||
int translation = TexMan.UseGamePalette(tex) ? Translation.MakeID(Translation_BasePalette, DREALMSPAL) : 0;
|
TranslationID translation = TexMan.UseGamePalette(tex) ? Translation.MakeID(Translation_BasePalette, DREALMSPAL) : 0;
|
||||||
Screen.DrawTexture(tex, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal);
|
Screen.DrawTexture(tex, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue