This commit is contained in:
raa-eruanna 2016-10-02 23:10:28 -04:00
commit 267b131c03
21 changed files with 346 additions and 61 deletions

View File

@ -9,6 +9,8 @@ endif()
include( CheckCXXSourceCompiles ) include( CheckCXXSourceCompiles )
include( CheckFunctionExists ) include( CheckFunctionExists )
include( CheckCXXCompilerFlag ) include( CheckCXXCompilerFlag )
include( CheckIncludeFile )
include( CheckIncludeFiles )
include( CheckLibraryExists ) include( CheckLibraryExists )
include( FindPkgConfig ) include( FindPkgConfig )
include( FindOpenGL ) include( FindOpenGL )
@ -119,7 +121,13 @@ if( WIN32 )
PATHS ENV DXSDK_DIR PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include ) PATH_SUFFIXES Include )
if( NOT D3D_INCLUDE_DIR ) if( NOT D3D_INCLUDE_DIR )
# Modern versions of the Windows SDK include d3d9.h. Unfortunately,
# CMake cannot find this file via find_path, so we check for it using
# CHECK_INCLUDE_FILE.
CHECK_INCLUDE_FILE( d3d9.h D3D9_H_FOUND )
if ( NOT D3D9_H_FOUND )
message( SEND_ERROR "Could not find DirectX 9 header files" ) message( SEND_ERROR "Could not find DirectX 9 header files" )
endif()
else() else()
include_directories( ${D3D_INCLUDE_DIR} ) include_directories( ${D3D_INCLUDE_DIR} )
endif() endif()
@ -128,35 +136,41 @@ if( WIN32 )
PATHS ENV DXSDK_DIR PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include ) PATH_SUFFIXES Include )
if( NOT XINPUT_INCLUDE_DIR ) if( NOT XINPUT_INCLUDE_DIR )
# Modern versions of the Windows SDK include xinput.h. Unfortunately,
# CMake cannot find this file via find_path, so we check for it using
# CHECK_INCLUDE_FILES. windows.h must be included before xinput.h.
CHECK_INCLUDE_FILES( "windows.h;xinput.h" XINPUT_H_FOUND )
if( NOT XINPUT_H_FOUND )
message( WARNING "Could not find xinput.h. XInput will be disabled." ) message( WARNING "Could not find xinput.h. XInput will be disabled." )
add_definitions( -DNO_XINPUT ) add_definitions( -DNO_XINPUT )
endif()
else() else()
include_directories( ${XINPUT_INCLUDE_DIR} ) include_directories( ${XINPUT_INCLUDE_DIR} )
endif() endif()
find_library( DX_dxguid_LIBRARY dxguid
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Lib Lib/${XBITS} )
find_library( DX_dinput8_LIBRARY dinput8 find_library( DX_dinput8_LIBRARY dinput8
PATHS ENV DXSDK_DIR PATHS ENV DXSDK_DIR
PATH_SUFFIXES Lib Lib/${XBITS} ) PATH_SUFFIXES Lib Lib/${XBITS} )
find_library( DX_dxguid_LIBRARY dxguid
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Lib Lib/${XBITS} )
set( DX_LIBS_FOUND YES ) # Modern versions of the Windows SDK include dinput8.lib. Unfortunately,
if( NOT DX_dxguid_LIBRARY ) # CMake cannot find these libraries via find_library.
set( DX_LIBS_FOUND NO )
endif()
if( NOT DX_dinput8_LIBRARY ) if( NOT DX_dinput8_LIBRARY )
set( DX_LIBS_FOUND NO ) # If we got this far, assume dinput8.lib is in the system library path.
set( DX_dinput8_LIBRARY dinput8 )
endif() endif()
if( NOT DX_LIBS_FOUND ) # Modern versions of the Windows SDK do NOT include dxguid.lib. Its contents
message( FATAL_ERROR "Could not find DirectX 9 libraries" ) # were moved to dinput8.lib.
if( NOT DX_dxguid_LIBRARY )
message( STATUS "Could not find dxguid.lib. Build may fail on old Windows SDKs.")
endif() endif()
set( ZDOOM_LIBS set( ZDOOM_LIBS
wsock32 wsock32
winmm winmm
"${DX_dxguid_LIBRARY}"
"${DX_dinput8_LIBRARY}" "${DX_dinput8_LIBRARY}"
ole32 ole32
user32 user32
@ -167,6 +181,9 @@ if( WIN32 )
setupapi setupapi
oleaut32 oleaut32
DelayImp ) DelayImp )
if( DX_dxguid_LIBRARY )
list( APPEND ZDOOM_LIBS "${DX_dxguid_LIBRARY}" )
endif()
else() else()
if( APPLE ) if( APPLE )
set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" ) set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" )

View File

@ -755,6 +755,9 @@ public:
// What species am I? // What species am I?
virtual FName GetSpecies(); virtual FName GetSpecies();
// set translation
void SetTranslation(const char *trname);
double GetBobOffset(double ticfrac = 0) const double GetBobOffset(double ticfrac = 0) const
{ {
if (!(flags2 & MF2_FLOATBOB)) if (!(flags2 & MF2_FLOATBOB))

View File

@ -2439,6 +2439,7 @@ void D_DoomMain (void)
if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n"); if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n");
TeamLibrary.ParseTeamInfo (); TeamLibrary.ParseTeamInfo ();
R_ParseTrnslate();
PClassActor::StaticInit (); PClassActor::StaticInit ();
// [GRB] Initialize player class list // [GRB] Initialize player class list

View File

@ -330,9 +330,13 @@ DObject::~DObject ()
} }
} }
} }
if (nullptr != type)
{
type->DestroySpecials(this); type->DestroySpecials(this);
} }
} }
}
//========================================================================== //==========================================================================
// //

View File

@ -54,6 +54,12 @@ void AFastProjectile::Tick ()
// Handle movement // Handle movement
if (!Vel.isZero() || (Z() != floorz)) if (!Vel.isZero() || (Z() != floorz))
{ {
// force some lateral movement so that collision detection works as intended.
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage())
{
Vel.X = MinVel;
}
frac = Vel / count; frac = Vel / count;
changexy = frac.X != 0 || frac.Y != 0; changexy = frac.X != 0 || frac.Y != 0;
int ripcount = count / 8; int ripcount = count / 8;
@ -124,7 +130,7 @@ void AFastProjectile::Tick ()
P_ExplodeMissile (this, NULL, NULL); P_ExplodeMissile (this, NULL, NULL);
return; return;
} }
if (changexy && ripcount <= 0) if (!frac.isZero() && ripcount <= 0)
{ {
ripcount = count >> 3; ripcount = count >> 3;
Effect(); Effect();

View File

@ -1021,7 +1021,7 @@ class CommandDrawNumber : public CommandDrawString
usePrefix(false), interpolationSpeed(0), drawValue(0), length(3), usePrefix(false), interpolationSpeed(0), drawValue(0), length(3),
lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1), lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1),
highTranslation(CR_UNTRANSLATED), value(CONSTANT), highTranslation(CR_UNTRANSLATED), value(CONSTANT),
inventoryItem(NULL) inventoryItem(NULL), cvarName(nullptr)
{ {
} }
@ -1164,6 +1164,37 @@ class CommandDrawNumber : public CommandDrawString
inventoryItem = RUNTIME_CLASS(APowerupGiver); inventoryItem = RUNTIME_CLASS(APowerupGiver);
} }
if(parenthesized) sc.MustGetToken(')');
}
else if (sc.Compare("intcvar"))
{
bool parenthesized = sc.CheckToken('(');
value = INTCVAR;
if (!parenthesized || !sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier);
cvarName = sc.String;
// We have a name, but make sure it exists. If not, send notification so modders
// are aware of the situation.
FBaseCVar *CVar = FindCVar(cvarName, nullptr);
if (CVar != nullptr)
{
ECVarType cvartype = CVar->GetRealType();
if (!(cvartype == CVAR_Bool || cvartype == CVAR_Int))
{
sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName);
}
}
else
{
sc.ScriptMessage("CVar '%s' does not exist", cvarName);
}
if (parenthesized) sc.MustGetToken(')'); if (parenthesized) sc.MustGetToken(')');
} }
} }
@ -1444,6 +1475,24 @@ class CommandDrawNumber : public CommandDrawString
num++; num++;
} }
break; break;
case INTCVAR:
{
FBaseCVar *CVar = GetCVar(statusBar->CPlayer->mo, cvarName);
if (CVar != nullptr)
{
ECVarType cvartype = CVar->GetRealType();
if (cvartype == CVAR_Bool || cvartype == CVAR_Int)
{
num = CVar->GetGenericRep(CVAR_Int).Int;
break;
}
}
// Fallback in case of bad cvar/type. Unset can remove a cvar at will.
num = 0;
break;
}
default: break; default: break;
} }
if(interpolationSpeed != 0 && (!hudChanged || level.time == 1)) if(interpolationSpeed != 0 && (!hudChanged || level.time == 1))
@ -1522,6 +1571,7 @@ class CommandDrawNumber : public CommandDrawString
ACCURACY, ACCURACY,
STAMINA, STAMINA,
KEYS, KEYS,
INTCVAR,
CONSTANT CONSTANT
}; };
@ -1544,6 +1594,7 @@ class CommandDrawNumber : public CommandDrawString
PClassActor *inventoryItem; PClassActor *inventoryItem;
FString prefixPadding; FString prefixPadding;
FString cvarName;
friend class CommandDrawInventoryBar; friend class CommandDrawInventoryBar;
}; };

View File

@ -4379,10 +4379,11 @@ enum EACSFunctions
ACSF_CheckClass = 200, ACSF_CheckClass = 200,
ACSF_DamageActor, // [arookas] ACSF_DamageActor, // [arookas]
ACSF_SetActorFlag, ACSF_SetActorFlag,
ACSF_SetTranslation,
// ZDaemon // ZDaemon
ACSF_GetTeamScore = 19620, // (int team) ACSF_GetTeamScore = 19620, // (int team)
ACSF_SetTeamScore, // (int team, int value) ACSF_SetTeamScore, // (int team, int value
}; };
int DLevelScript::SideFromID(int id, int side) int DLevelScript::SideFromID(int id, int side)
@ -6002,6 +6003,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
return count; return count;
} }
case ACSF_SetTranslation:
{
int tid = args[0];
const char *trname = FBehavior::StaticLookupString(args[1]);
if (tid == 0)
{
if (activator != nullptr)
activator->SetTranslation(trname);
}
else
{
FActorIterator it(tid);
while ((actor = it.Next()) != nullptr)
{
actor->SetTranslation(trname);
}
}
return 1;
}
default: default:
break; break;
} }

View File

@ -6525,6 +6525,23 @@ int AActor::ApplyDamageFactor(FName damagetype, int damage) const
} }
void AActor::SetTranslation(const char *trname)
{
if (*trname == 0)
{
// an empty string resets to the default
Translation = GetDefault()->Translation;
return;
}
int tnum = R_FindCustomTranslation(trname);
if (tnum >= 0)
{
Translation = tnum;
}
// silently ignore if the name does not exist, this would create some insane message spam otherwise.
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
// DropItem handling // DropItem handling

View File

@ -1049,6 +1049,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
return 0; return 0;
} }
//---------------------------------------------------------------------------
//
// PROC OverlayID
// Because non-action functions cannot acquire the ID of the overlay...
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, OverlayID)
{
PARAM_ACTION_PROLOGUE;
if (ACTION_CALL_FROM_PSPRITE())
{
ACTION_RETURN_INT(stateinfo->mPSPIndex);
}
ACTION_RETURN_INT(0);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// PROC A_Lower // PROC A_Lower

View File

@ -609,26 +609,26 @@ void FRemapTable::AddToTranslation(const char *range)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int FRemapTable::StoreTranslation() int FRemapTable::StoreTranslation(int slot)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < translationtables[TRANSLATION_Decorate].Size(); i++) for (i = 0; i < translationtables[slot].Size(); i++)
{ {
if (*this == *translationtables[TRANSLATION_Decorate][i]) if (*this == *translationtables[slot][i])
{ {
// A duplicate of this translation already exists // A duplicate of this translation already exists
return TRANSLATION(TRANSLATION_Decorate, i); return TRANSLATION(slot, i);
} }
} }
if (translationtables[TRANSLATION_Decorate].Size() >= MAX_DECORATE_TRANSLATIONS) if (translationtables[slot].Size() >= MAX_DECORATE_TRANSLATIONS)
{ {
I_Error("Too many DECORATE translations"); I_Error("Too many DECORATE translations");
} }
FRemapTable *newtrans = new FRemapTable; FRemapTable *newtrans = new FRemapTable;
*newtrans = *this; *newtrans = *this;
i = translationtables[TRANSLATION_Decorate].Push(newtrans); i = translationtables[slot].Push(newtrans);
return TRANSLATION(TRANSLATION_Decorate, i); return TRANSLATION(slot, i);
} }
@ -1197,3 +1197,90 @@ void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayer
R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL, NULL); R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL, NULL);
} }
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
static TMap<FName, int> customTranslationMap;
int R_FindCustomTranslation(const char *name)
{
if (name == nullptr)
{
return -1;
}
// Ice is a special case which will remain in its original slot.
if (!stricmp(name, "Ice"))
{
return TRANSLATION(TRANSLATION_Standard, 7);
}
int *t = customTranslationMap.CheckKey(FName(name, true));
return (t != nullptr)? *t : -1;
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
void R_ParseTrnslate()
{
customTranslationMap.Clear();
translationtables[TRANSLATION_Custom].Clear();
int lump;
int lastlump = 0;
while (-1 != (lump = Wads.FindLump("TRNSLATE", &lastlump)))
{
FScanner sc(lump);
while (sc.GetToken())
{
sc.TokenMustBe(TK_Identifier);
FName newtrans = sc.String;
FRemapTable *base = nullptr;
if (sc.CheckToken(':'))
{
sc.MustGetAnyToken();
if (sc.TokenType == TK_IntConst)
{
int max = 6;
if (sc.Number < 0 || sc.Number > max)
{
sc.ScriptError("Translation must be in the range [0,%d]", max);
}
base = translationtables[TRANSLATION_Standard][sc.Number];
}
else if (sc.TokenType == TK_Identifier)
{
int tnum = R_FindCustomTranslation(sc.String);
if (tnum == -1)
{
sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars());
}
base = translationtables[GetTranslationType(tnum)][GetTranslationIndex(tnum)];
}
else
{
// error out.
sc.TokenMustBe(TK_Identifier);
}
}
sc.MustGetToken('=');
FRemapTable NewTranslation;
if (base != nullptr) NewTranslation = *base;
else NewTranslation.MakeIdentity();
do
{
sc.MustGetToken(TK_StringConst);
NewTranslation.AddToTranslation(sc.String);
} while (sc.CheckToken(','));
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);
customTranslationMap[newtrans] = trans;
}
}
}

View File

@ -19,6 +19,7 @@ enum
TRANSLATION_Decorate, TRANSLATION_Decorate,
TRANSLATION_Blood, TRANSLATION_Blood,
TRANSLATION_RainPillar, TRANSLATION_RainPillar,
TRANSLATION_Custom,
NUM_TRANSLATION_TABLES NUM_TRANSLATION_TABLES
}; };
@ -42,7 +43,7 @@ struct FRemapTable
void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2); void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
void AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2); void AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
void AddToTranslation(const char * range); void AddToTranslation(const char * range);
int StoreTranslation(); int StoreTranslation(int slot);
BYTE *Remap; // For the software renderer BYTE *Remap; // For the software renderer
PalEntry *Palette; // The ideal palette this maps to PalEntry *Palette; // The ideal palette this maps to
@ -109,6 +110,9 @@ extern TArray<PalEntry> BloodTranslationColors;
int CreateBloodTranslation(PalEntry color); int CreateBloodTranslation(PalEntry color);
int R_FindCustomTranslation(const char *name);
void R_ParseTrnslate();
#endif // __R_TRANSLATE_H #endif // __R_TRANSLATE_H

View File

@ -321,9 +321,16 @@ protected:
} }
bool WriteDouble(double d) { bool WriteDouble(double d) {
bool ret = true;
if (internal::Double(d).IsNanOrInf()) { if (internal::Double(d).IsNanOrInf()) {
if (!(writeFlags & kWriteNanAndInfFlag)) if (!(writeFlags & kWriteNanAndInfFlag))
return false; {
// if we abort here, the writer is left in a broken state, unable to recover, so better write a 0 in addition to returning an error.
ret = false;
d = 0;
}
else
{
if (internal::Double(d).IsNan()) { if (internal::Double(d).IsNan()) {
PutReserve(*os_, 3); PutReserve(*os_, 3);
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
@ -339,13 +346,14 @@ protected:
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
return true; return true;
} }
}
char buffer[25]; char buffer[25];
char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
PutReserve(*os_, static_cast<size_t>(end - buffer)); PutReserve(*os_, static_cast<size_t>(end - buffer));
for (char* p = buffer; p != end; ++p) for (char* p = buffer; p != end; ++p)
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
return true; return ret;
} }
bool WriteString(const Ch* str, SizeType length) { bool WriteString(const Ch* str, SizeType length) {

View File

@ -217,11 +217,11 @@ struct FWriter
{ {
if (mWriter1) if (mWriter1)
{ {
if (!mWriter1->Double(k)) mWriter1->Double(0); mWriter1->Double(k);
} }
else if (mWriter2) else if (mWriter2)
{ {
if (!mWriter2->Double(k)) mWriter2->Double(0); mWriter2->Double(k);
} }
} }

View File

@ -288,7 +288,7 @@ static void FinishThingdef()
if (func == nullptr) if (func == nullptr)
{ {
VMFunctionBuilder buildit; VMFunctionBuilder buildit(true);
assert(tcall->Proto != nullptr); assert(tcall->Proto != nullptr);

View File

@ -7412,3 +7412,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetVisibleRotation)
ACTION_RETURN_BOOL(true); ACTION_RETURN_BOOL(true);
} }
//==========================================================================
//
//
//
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslation)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_STRING(trname);
self->SetTranslation(trname);
return 0;
}

View File

@ -3373,7 +3373,7 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx)
ExpEmit FxClassMember::Emit(VMFunctionBuilder *build) ExpEmit FxClassMember::Emit(VMFunctionBuilder *build)
{ {
if (~membervar->Flags & VARF_Native) if (build->IsActionFunc && ~membervar->Flags & VARF_Native)
{ // Check if this is a user-defined variable. { // Check if this is a user-defined variable.
// As of right now, FxClassMember is only ever used with FxSelf. // As of right now, FxClassMember is only ever used with FxSelf.
// This very user variable was defined in stateowner so if // This very user variable was defined in stateowner so if
@ -3948,15 +3948,16 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
//========================================================================== //==========================================================================
// //
// Assumption: This call is being made to generate code inside an action // Assumption: This call is being generated inside a function whose a0
// method, so the first three address registers are all set up for such a // register is a self pointer. For action functions, a1 maps to stateowner
// function. (self, stateowner, callingstate) // and a2 maps to callingstate. (self, stateowner, callingstate)
// //
//========================================================================== //==========================================================================
ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
{ {
assert(build->Registers[REGT_POINTER].GetMostUsed() >= 3); assert((build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= NAP) ||
(!build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= 1));
int count = (ArgList ? ArgList->Size() : 0); int count = (ArgList ? ArgList->Size() : 0);
if (count == 1) if (count == 1)
@ -3974,9 +3975,19 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
count += 1; count += 1;
} }
if (Function->Flags & VARF_Action) if (Function->Flags & VARF_Action)
{
static_assert(NAP == 3, "This code needs to be updated if NAP changes");
if (build->IsActionFunc)
{ {
build->Emit(OP_PARAM, 0, REGT_POINTER, 1); build->Emit(OP_PARAM, 0, REGT_POINTER, 1);
build->Emit(OP_PARAM, 0, REGT_POINTER, 2); build->Emit(OP_PARAM, 0, REGT_POINTER, 2);
}
else
{
int null = build->GetConstantAddress(nullptr, ATAG_GENERIC);
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, null);
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, null);
}
count += 2; count += 2;
} }
// Emit code to pass explicit parameters // Emit code to pass explicit parameters
@ -4967,7 +4978,8 @@ static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numpa
ExpEmit FxRuntimeStateIndex::Emit(VMFunctionBuilder *build) ExpEmit FxRuntimeStateIndex::Emit(VMFunctionBuilder *build)
{ {
assert(build->Registers[REGT_POINTER].GetMostUsed() >= 3); assert(build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= 3 &&
"FxRuntimeStateIndex is only valid inside action functions");
ExpEmit out(build, REGT_POINTER); ExpEmit out(build, REGT_POINTER);
@ -5139,7 +5151,14 @@ int DecoFindSingleNameState(VMFrameStack *stack, VMValue *param, int numparam, V
ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build) ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
{ {
ExpEmit dest(build, REGT_POINTER); ExpEmit dest(build, REGT_POINTER);
if (build->IsActionFunc)
{
build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner
}
else
{
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
}
for (unsigned i = 0; i < names.Size(); ++i) for (unsigned i = 0; i < names.Size(); ++i)
{ {
build->EmitParamInt(names[i]); build->EmitParamInt(names[i]);

View File

@ -1100,9 +1100,10 @@ DEFINE_PROPERTY(translation, L, Actor)
for(int i = 1; i < PROP_PARM_COUNT; i++) for(int i = 1; i < PROP_PARM_COUNT; i++)
{ {
PROP_STRING_PARM(str, i); PROP_STRING_PARM(str, i);
if (i== 1 && PROP_PARM_COUNT == 2 && !stricmp(str, "Ice")) int tnum;
if (i== 1 && PROP_PARM_COUNT == 2 && (tnum = R_FindCustomTranslation(str)) != -1)
{ {
defaults->Translation = TRANSLATION(TRANSLATION_Standard, 7); defaults->Translation = tnum;
return; return;
} }
else else
@ -1110,7 +1111,7 @@ DEFINE_PROPERTY(translation, L, Actor)
CurrentTranslation.AddToTranslation(str); CurrentTranslation.AddToTranslation(str);
} }
} }
defaults->Translation = CurrentTranslation.StoreTranslation (); defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
} }
} }

View File

@ -27,6 +27,12 @@
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
// This macro is defined by newer versions of xinput.h. In case we are
// compiling with an older version, define it here.
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
#endif
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state); typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state);

View File

@ -6,7 +6,7 @@
// //
//========================================================================== //==========================================================================
VMFunctionBuilder::VMFunctionBuilder() VMFunctionBuilder::VMFunctionBuilder(bool selfcheck)
{ {
NumIntConstants = 0; NumIntConstants = 0;
NumFloatConstants = 0; NumFloatConstants = 0;
@ -14,6 +14,7 @@ VMFunctionBuilder::VMFunctionBuilder()
NumStringConstants = 0; NumStringConstants = 0;
MaxParam = 0; MaxParam = 0;
ActiveParam = 0; ActiveParam = 0;
IsActionFunc = selfcheck;
} }
//========================================================================== //==========================================================================

View File

@ -23,7 +23,7 @@ public:
friend class VMFunctionBuilder; friend class VMFunctionBuilder;
}; };
VMFunctionBuilder(); VMFunctionBuilder(bool checkself = false);
~VMFunctionBuilder(); ~VMFunctionBuilder();
VMScriptFunction *MakeFunction(); VMScriptFunction *MakeFunction();
@ -60,6 +60,9 @@ public:
// Track available registers. // Track available registers.
RegAvailability Registers[4]; RegAvailability Registers[4];
// For use by DECORATE's self/stateowner sanitizer.
bool IsActionFunc;
private: private:
struct AddrKonst struct AddrKonst
{ {

View File

@ -57,6 +57,7 @@ ACTOR Actor native //: Thinker
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT); native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT); native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT); native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
action native int OverlayID();
// Action functions // Action functions
// Meh, MBF redundant functions. Only for DeHackEd support. // Meh, MBF redundant functions. Only for DeHackEd support.
@ -344,6 +345,7 @@ ACTOR Actor native //: Thinker
action native bool A_SetSpriteAngle(float angle = 0, int ptr = AAPTR_DEFAULT); action native bool A_SetSpriteAngle(float angle = 0, int ptr = AAPTR_DEFAULT);
action native bool A_SetSpriteRotation(float angle = 0, int ptr = AAPTR_DEFAULT); action native bool A_SetSpriteRotation(float angle = 0, int ptr = AAPTR_DEFAULT);
action native bool A_SetVisibleRotation(float anglestart = 0, float angleend = 0, float pitchstart = 0, float pitchend = 0, int flags = 0, int ptr = AAPTR_DEFAULT); action native bool A_SetVisibleRotation(float anglestart = 0, float angleend = 0, float pitchstart = 0, float pitchend = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
native void A_SetTranslation(string transname);
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0); native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);