mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
2da18bfa56
25 changed files with 465 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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" )
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -330,7 +330,11 @@ DObject::~DObject ()
|
|||
}
|
||||
}
|
||||
}
|
||||
type->DestroySpecials(this);
|
||||
|
||||
if (nullptr != type)
|
||||
{
|
||||
type->DestroySpecials(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -288,7 +288,7 @@ static void FinishThingdef()
|
|||
|
||||
if (func == nullptr)
|
||||
{
|
||||
VMFunctionBuilder buildit;
|
||||
VMFunctionBuilder buildit(true);
|
||||
|
||||
assert(tcall->Proto != nullptr);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue