This commit is contained in:
Christoph Oelckers 2016-10-03 00:56:55 +02:00
commit 2da18bfa56
25 changed files with 465 additions and 64 deletions

View File

@ -214,6 +214,19 @@ Note: All <bool> fields default to false unless mentioned otherwise.
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
portal_ceil_alpha = <float> // translucency of ceiling portal (default is 0 (not visible))
portal_ceil_blocksound = <bool> // ceiling portal blocks sound.
portal_ceil_disabled = <bool> // ceiling portal disabled.
portal_ceil_nopass = <bool> // ceiling portal blocks movement if true.
portal_ceil_norender = <bool> // ceiling portal not rendered.
portal_ceil_overlaytype = <string> // defines translucency style, can either be "translucent" or "additive". Default is "translucent".
portal_floor_alpha = <float> // translucency of floor portal (default is 0 (not visible))
portal_floor_blocksound = <bool> // floor portal blocks sound.
portal_floor_disabled = <bool> // floor portal disabled.
portal_floor_nopass = <bool> // ceiling portal blocks movement if true.
portal_floor_norender = <bool> // ceiling portal not rendered.
portal_floor_overlaytype = <string> // defines translucency style, can either be "translucent" or "additive". Default is "translucent".
* Note about dropactors

View File

@ -9,6 +9,8 @@ endif()
include( CheckCXXSourceCompiles )
include( CheckFunctionExists )
include( CheckCXXCompilerFlag )
include( CheckIncludeFile )
include( CheckIncludeFiles )
include( CheckLibraryExists )
include( FindPkgConfig )
include( FindOpenGL )
@ -119,7 +121,13 @@ if( WIN32 )
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include )
if( NOT D3D_INCLUDE_DIR )
message( SEND_ERROR "Could not find DirectX 9 header files" )
# 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" )
endif()
else()
include_directories( ${D3D_INCLUDE_DIR} )
endif()
@ -128,35 +136,41 @@ if( WIN32 )
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Include )
if( NOT XINPUT_INCLUDE_DIR )
message( WARNING "Could not find xinput.h. XInput will be disabled." )
add_definitions( -DNO_XINPUT )
# 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." )
add_definitions( -DNO_XINPUT )
endif()
else()
include_directories( ${XINPUT_INCLUDE_DIR} )
endif()
find_library( DX_dxguid_LIBRARY dxguid
PATHS ENV DXSDK_DIR
PATH_SUFFIXES Lib Lib/${XBITS} )
find_library( DX_dinput8_LIBRARY dinput8
PATHS ENV DXSDK_DIR
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 )
if( NOT DX_dxguid_LIBRARY )
set( DX_LIBS_FOUND NO )
endif()
# Modern versions of the Windows SDK include dinput8.lib. Unfortunately,
# CMake cannot find these libraries via find_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()
if( NOT DX_LIBS_FOUND )
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
# Modern versions of the Windows SDK do NOT include dxguid.lib. Its contents
# 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()
set( ZDOOM_LIBS
wsock32
winmm
"${DX_dxguid_LIBRARY}"
"${DX_dinput8_LIBRARY}"
ole32
user32
@ -167,6 +181,9 @@ if( WIN32 )
setupapi
oleaut32
DelayImp )
if( DX_dxguid_LIBRARY )
list( APPEND ZDOOM_LIBS "${DX_dxguid_LIBRARY}" )
endif()
else()
if( APPLE )
set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" )

View File

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

View File

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

View File

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

View File

@ -54,6 +54,12 @@ void AFastProjectile::Tick ()
// Handle movement
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;
changexy = frac.X != 0 || frac.Y != 0;
int ripcount = count / 8;
@ -124,7 +130,7 @@ void AFastProjectile::Tick ()
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy && ripcount <= 0)
if (!frac.isZero() && ripcount <= 0)
{
ripcount = count >> 3;
Effect();

View File

@ -1021,7 +1021,7 @@ class CommandDrawNumber : public CommandDrawString
usePrefix(false), interpolationSpeed(0), drawValue(0), length(3),
lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1),
highTranslation(CR_UNTRANSLATED), value(CONSTANT),
inventoryItem(NULL)
inventoryItem(NULL), cvarName(nullptr)
{
}
@ -1166,6 +1166,37 @@ class CommandDrawNumber : public CommandDrawString
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(value == INVENTORY)
{
@ -1444,6 +1475,24 @@ class CommandDrawNumber : public CommandDrawString
num++;
}
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;
}
if(interpolationSpeed != 0 && (!hudChanged || level.time == 1))
@ -1522,6 +1571,7 @@ class CommandDrawNumber : public CommandDrawString
ACCURACY,
STAMINA,
KEYS,
INTCVAR,
CONSTANT
};
@ -1544,6 +1594,7 @@ class CommandDrawNumber : public CommandDrawString
PClassActor *inventoryItem;
FString prefixPadding;
FString cvarName;
friend class CommandDrawInventoryBar;
};

View File

@ -507,6 +507,21 @@ xx(Alphaceiling)
xx(Renderstylefloor)
xx(Renderstyleceiling)
xx(Waterzone)
xx(portal_ceil_alpha)
xx(portal_ceil_blocksound)
xx(portal_ceil_disabled)
xx(portal_ceil_nopass)
xx(portal_ceil_norender)
xx(portal_ceil_overlaytype)
xx(portal_ceil_useglobaltex)
xx(portal_floor_alpha)
xx(portal_floor_blocksound)
xx(portal_floor_disabled)
xx(portal_floor_nopass)
xx(portal_floor_norender)
xx(portal_floor_overlaytype)
xx(portal_floor_useglobaltex)
xx(offsetx_top)
xx(offsety_top)

View File

@ -4379,10 +4379,11 @@ enum EACSFunctions
ACSF_CheckClass = 200,
ACSF_DamageActor, // [arookas]
ACSF_SetActorFlag,
ACSF_SetTranslation,
// ZDaemon
ACSF_GetTeamScore = 19620, // (int team)
ACSF_SetTeamScore, // (int team, int value)
ACSF_SetTeamScore, // (int team, int value
};
int DLevelScript::SideFromID(int id, int side)
@ -6002,6 +6003,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
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:
break;
}

View File

@ -3526,7 +3526,7 @@ void AActor::Tick ()
sector_t *sec = node->m_sector;
DVector2 scrollv;
if (level.Scrolls.Size() > (sec-sectors))
if (level.Scrolls.Size() > unsigned(sec-sectors))
{
scrollv = level.Scrolls[sec - sectors];
}
@ -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

View File

@ -1049,6 +1049,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
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

View File

@ -1568,6 +1568,60 @@ public:
tagstring = CheckString(key);
break;
case NAME_portal_ceil_alpha:
sec->planes[sector_t::ceiling].alpha = CheckFloat(key);
break;
case NAME_portal_ceil_blocksound:
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_BLOCKSOUND, key);
break;
case NAME_portal_ceil_disabled:
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_DISABLED, key);
break;
case NAME_portal_ceil_nopass:
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_NOPASS, key);
break;
case NAME_portal_ceil_norender:
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_NORENDER, key);
break;
case NAME_portal_ceil_overlaytype:
if (!stricmp(CheckString(key), "translucent")) sec->planes[sector_t::ceiling].Flags &= ~PLANEF_ADDITIVE;
else if (!stricmp(CheckString(key), "additive")) sec->planes[sector_t::ceiling].Flags |= PLANEF_ADDITIVE;
break;
case NAME_portal_floor_alpha:
sec->planes[sector_t::floor].alpha = CheckFloat(key);
break;
case NAME_portal_floor_blocksound:
Flag(sec->planes[sector_t::floor].Flags, PLANEF_BLOCKSOUND, key);
break;
case NAME_portal_floor_disabled:
Flag(sec->planes[sector_t::floor].Flags, PLANEF_DISABLED, key);
break;
case NAME_portal_floor_nopass:
Flag(sec->planes[sector_t::floor].Flags, PLANEF_NOPASS, key);
break;
case NAME_portal_floor_norender:
Flag(sec->planes[sector_t::floor].Flags, PLANEF_NORENDER, key);
break;
case NAME_portal_floor_overlaytype:
if (!stricmp(CheckString(key), "translucent")) sec->planes[sector_t::floor].Flags &= ~PLANEF_ADDITIVE;
else if (!stricmp(CheckString(key), "additive")) sec->planes[sector_t::floor].Flags |= PLANEF_ADDITIVE;
break;
// These two are used by Eternity for something I do not understand.
//case NAME_portal_ceil_useglobaltex:
//case NAME_portal_floor_useglobaltex:
default:
break;
}

View File

@ -609,26 +609,26 @@ void FRemapTable::AddToTranslation(const char *range)
//
//----------------------------------------------------------------------------
int FRemapTable::StoreTranslation()
int FRemapTable::StoreTranslation(int slot)
{
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
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");
}
FRemapTable *newtrans = new FRemapTable;
*newtrans = *this;
i = translationtables[TRANSLATION_Decorate].Push(newtrans);
return TRANSLATION(TRANSLATION_Decorate, i);
i = translationtables[slot].Push(newtrans);
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);
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
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_Blood,
TRANSLATION_RainPillar,
TRANSLATION_Custom,
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 AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
void AddToTranslation(const char * range);
int StoreTranslation();
int StoreTranslation(int slot);
BYTE *Remap; // For the software renderer
PalEntry *Palette; // The ideal palette this maps to
@ -109,6 +110,9 @@ extern TArray<PalEntry> BloodTranslationColors;
int CreateBloodTranslation(PalEntry color);
int R_FindCustomTranslation(const char *name);
void R_ParseTrnslate();
#endif // __R_TRANSLATE_H

View File

@ -321,23 +321,31 @@ protected:
}
bool WriteDouble(double d) {
if (internal::Double(d).IsNanOrInf()) {
if (!(writeFlags & kWriteNanAndInfFlag))
return false;
if (internal::Double(d).IsNan()) {
PutReserve(*os_, 3);
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
return true;
}
if (internal::Double(d).Sign()) {
PutReserve(*os_, 9);
PutUnsafe(*os_, '-');
}
else
PutReserve(*os_, 8);
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
return true;
bool ret = true;
if (internal::Double(d).IsNanOrInf()) {
if (!(writeFlags & kWriteNanAndInfFlag))
{
// 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()) {
PutReserve(*os_, 3);
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
return true;
}
if (internal::Double(d).Sign()) {
PutReserve(*os_, 9);
PutUnsafe(*os_, '-');
}
else
PutReserve(*os_, 8);
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
return true;
}
}
char buffer[25];
@ -345,7 +353,7 @@ protected:
PutReserve(*os_, static_cast<size_t>(end - buffer));
for (char* p = buffer; p != end; ++p)
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
return true;
return ret;
}
bool WriteString(const Ch* str, SizeType length) {

View File

@ -217,11 +217,11 @@ struct FWriter
{
if (mWriter1)
{
if (!mWriter1->Double(k)) mWriter1->Double(0);
mWriter1->Double(k);
}
else if (mWriter2)
{
if (!mWriter2->Double(k)) mWriter2->Double(0);
mWriter2->Double(k);
}
}
@ -821,7 +821,6 @@ void FSerializer::WriteObjects()
for (unsigned i = 0; i < w->mDObjects.Size(); i++)
{
auto obj = w->mDObjects[i];
player_t *player;
BeginObject(nullptr);
w->Key("classtype");

View File

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

View File

@ -3322,6 +3322,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslucent)
return 0;
}
//===========================================================================
//
// A_SetRenderStyle
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRenderStyle)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(alpha);
PARAM_INT_OPT(mode) { mode = 0; }
self->Alpha = clamp(alpha, 0., 1.);
self->RenderStyle = ERenderStyle(mode);
return 0;
}
//===========================================================================
//
// A_FadeIn
@ -7396,3 +7412,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetVisibleRotation)
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)
{
if (~membervar->Flags & VARF_Native)
if (build->IsActionFunc && ~membervar->Flags & VARF_Native)
{ // Check if this is a user-defined variable.
// As of right now, FxClassMember is only ever used with FxSelf.
// 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
// method, so the first three address registers are all set up for such a
// function. (self, stateowner, callingstate)
// Assumption: This call is being generated inside a function whose a0
// register is a self pointer. For action functions, a1 maps to stateowner
// and a2 maps to callingstate. (self, stateowner, callingstate)
//
//==========================================================================
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);
if (count == 1)
@ -3975,8 +3976,18 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
}
if (Function->Flags & VARF_Action)
{
build->Emit(OP_PARAM, 0, REGT_POINTER, 1);
build->Emit(OP_PARAM, 0, REGT_POINTER, 2);
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, 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;
}
// Emit code to pass explicit parameters
@ -4967,7 +4978,8 @@ static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numpa
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);
@ -5139,7 +5151,14 @@ int DecoFindSingleNameState(VMFrameStack *stack, VMValue *param, int numparam, V
ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
{
ExpEmit dest(build, REGT_POINTER);
build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner
if (build->IsActionFunc)
{
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)
{
build->EmitParamInt(names[i]);

View File

@ -1100,9 +1100,10 @@ DEFINE_PROPERTY(translation, L, Actor)
for(int i = 1; i < PROP_PARM_COUNT; 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;
}
else
@ -1110,7 +1111,7 @@ DEFINE_PROPERTY(translation, L, Actor)
CurrentTranslation.AddToTranslation(str);
}
}
defaults->Translation = CurrentTranslation.StoreTranslation ();
defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
}
}

View File

@ -27,6 +27,12 @@
// 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 -------------------------------------------------------------------
typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state);

View File

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

View File

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

View File

@ -57,6 +57,7 @@ ACTOR Actor native //: Thinker
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
action native int OverlayID();
// Action functions
// Meh, MBF redundant functions. Only for DeHackEd support.
@ -218,6 +219,7 @@ ACTOR Actor native //: Thinker
native void A_LogInt(int whattoprint);
native void A_LogFloat(float whattoprint);
native void A_SetTranslucent(float alpha, int style = 0);
native void A_SetRenderStyle(float alpha, int style);
action native A_FadeIn(float reduce = 0.1, int flags = 0);
action native A_FadeOut(float reduce = 0.1, int flags = 1); //bool remove == true
native void A_FadeTo(float target, float amount = 0.1, int flags = 0);
@ -343,6 +345,7 @@ ACTOR Actor native //: Thinker
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_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_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);

View File

@ -689,4 +689,22 @@ enum
VRF_NOANGLE = VRF_NOANGLESTART|VRF_NOANGLEEND,
VRF_NOPITCH = VRF_NOPITCHSTART|VRF_NOPITCHEND,
};
};
enum
{
STYLE_None,
STYLE_Normal,
STYLE_Fuzzy,
STYLE_SoulTrans,
STYLE_OptFuzzy,
STYLE_Stencil,
STYLE_Translucent,
STYLE_Add,
STYLE_Shaded,
STYLE_TranslucentStencil,
STYLE_Shadow,
STYLE_Subtract,
STYLE_AddStencil,
STYLE_AddShaded,
};