mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-30 16:00:55 +00:00
- Started adding action function declarations to objects.
- Added integer constant declarations to objects. - Added some new token-based functions to sc_man.cpp that know about keywords and record proper type information, so parsers don't need to treat everything as strings. - Added a simple symbol table to PClass. SVN r394 (trunk)
This commit is contained in:
parent
30885e6d86
commit
4467cd6563
18 changed files with 5605 additions and 808 deletions
|
@ -1,3 +1,8 @@
|
|||
November 28, 2006
|
||||
- Started adding action function declarations to objects.
|
||||
- Added integer constant declarations to objects.
|
||||
- Added a simple symbol table to PClass.
|
||||
|
||||
November 27, 2006 (Changes by Graf Zahl)
|
||||
- Changed: When playing a shareware game no external WADs are loaded at all,
|
||||
not even zvox.wad or the skins directory.
|
||||
|
|
|
@ -380,3 +380,92 @@ void CreatePath(const char * fn)
|
|||
}
|
||||
else DoCreatePath(fn);
|
||||
}
|
||||
|
||||
// [RH] Replaces the escape sequences in a string with actual escaped characters.
|
||||
// This operation is done in-place.
|
||||
|
||||
void strbin (char *str)
|
||||
{
|
||||
char *p = str, c;
|
||||
int i;
|
||||
|
||||
while ( (c = *p++) ) {
|
||||
if (c != '\\') {
|
||||
*str++ = c;
|
||||
} else {
|
||||
switch (*p) {
|
||||
case 'a':
|
||||
*str++ = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
*str++ = '\b';
|
||||
break;
|
||||
case 'c':
|
||||
*str++ = '\034'; // TEXTCOLOR_ESCAPE
|
||||
break;
|
||||
case 'f':
|
||||
*str++ = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
*str++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
*str++ = '\t';
|
||||
break;
|
||||
case 'r':
|
||||
*str++ = '\r';
|
||||
break;
|
||||
case 'v':
|
||||
*str++ = '\v';
|
||||
break;
|
||||
case '?':
|
||||
*str++ = '\?';
|
||||
break;
|
||||
case '\n':
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
c = 0;
|
||||
p++;
|
||||
for (i = 0; i < 2; i++) {
|
||||
c <<= 4;
|
||||
if (*p >= '0' && *p <= '9')
|
||||
c += *p-'0';
|
||||
else if (*p >= 'a' && *p <= 'f')
|
||||
c += 10 + *p-'a';
|
||||
else if (*p >= 'A' && *p <= 'F')
|
||||
c += 10 + *p-'A';
|
||||
else
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
*str++ = c;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
c = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
c <<= 3;
|
||||
if (*p >= '0' && *p <= '7')
|
||||
c += *p-'0';
|
||||
else
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
*str++ = c;
|
||||
break;
|
||||
default:
|
||||
*str++ = *p;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
*str = 0;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ void FormatGUID (char *text, const GUID &guid);
|
|||
|
||||
char *myasctime ();
|
||||
|
||||
void strbin (char *str);
|
||||
|
||||
void CreatePath(const char * fn);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1394,5 +1394,5 @@ DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) con
|
|||
static fixed_t ReadScale ()
|
||||
{
|
||||
SC_MustGetFloat ();
|
||||
return fixed_t(clamp (sc_Float * FRACUNIT, 256.f, 256.f*FRACUNIT));
|
||||
return fixed_t(clamp (sc_Float * FRACUNIT, 256.0, 256.0*FRACUNIT));
|
||||
}
|
||||
|
|
|
@ -664,7 +664,7 @@ static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
|
|||
else if (SC_Compare ("Alpha"))
|
||||
{
|
||||
SC_MustGetFloat ();
|
||||
defaults->alpha = int(clamp (sc_Float, 0.f, 1.f) * OPAQUE);
|
||||
defaults->alpha = int(clamp (sc_Float, 0.0, 1.0) * OPAQUE);
|
||||
}
|
||||
else if (SC_Compare ("Scale"))
|
||||
{
|
||||
|
|
|
@ -221,6 +221,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
|
|||
type->FlatPointers = NULL;
|
||||
type->bRuntimeClass = true;
|
||||
type->ActorInfo = NULL;
|
||||
type->Symbols.SetParentTable (&this->Symbols);
|
||||
type->InsertIntoHash();
|
||||
|
||||
// If this class has an actor info, then any classes derived from it
|
||||
|
@ -302,3 +303,86 @@ void PClass::FreeStateList ()
|
|||
}
|
||||
}
|
||||
|
||||
// Symbol tables ------------------------------------------------------------
|
||||
|
||||
PSymbolTable::PSymbolTable ()
|
||||
: ParentSymbolTable(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
PSymbolTable::~PSymbolTable ()
|
||||
{
|
||||
for (unsigned int i = 0; i < Symbols.Size(); ++i)
|
||||
{
|
||||
delete Symbols[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PSymbolTable::SetParentTable (PSymbolTable *parent)
|
||||
{
|
||||
ParentSymbolTable = parent;
|
||||
}
|
||||
|
||||
PSymbol *PSymbolTable::FindSymbol (FName symname, bool searchparents) const
|
||||
{
|
||||
int min, max;
|
||||
|
||||
min = 0;
|
||||
max = (int)Symbols.Size() - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
unsigned int mid = (min + max) / 2;
|
||||
PSymbol *sym = Symbols[mid];
|
||||
|
||||
if (sym->SymbolName == symname)
|
||||
{
|
||||
return sym;
|
||||
}
|
||||
else if (sym->SymbolName < symname)
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
}
|
||||
if (searchparents && ParentSymbolTable != NULL)
|
||||
{
|
||||
return ParentSymbolTable->FindSymbol (symname, true);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PSymbol *PSymbolTable::AddSymbol (PSymbol *sym)
|
||||
{
|
||||
// Insert it in sorted order.
|
||||
int min, max, mid;
|
||||
|
||||
min = 0;
|
||||
max = (int)Symbols.Size() - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
PSymbol *tsym = Symbols[mid];
|
||||
|
||||
if (tsym->SymbolName == sym->SymbolName)
|
||||
{ // A symbol with this name already exists in the table
|
||||
return NULL;
|
||||
}
|
||||
else if (tsym->SymbolName < sym->SymbolName)
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Good. The symbol is not in the table yet.
|
||||
Symbols.Insert (MAX(min, max), sym);
|
||||
return sym;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,80 @@
|
|||
#error You must #include "dobject.h" to get dobjtype.h
|
||||
#endif
|
||||
|
||||
// Symbol information -------------------------------------------------------
|
||||
|
||||
enum ESymbolType
|
||||
{
|
||||
SYM_Const,
|
||||
SYM_ActionFunction
|
||||
};
|
||||
|
||||
struct PSymbol
|
||||
{
|
||||
ESymbolType SymbolType;
|
||||
FName SymbolName;
|
||||
};
|
||||
|
||||
// A constant value ---------------------------------------------------------
|
||||
|
||||
struct PSymbolConst : public PSymbol
|
||||
{
|
||||
int Value;
|
||||
};
|
||||
|
||||
// An action function -------------------------------------------------------
|
||||
//
|
||||
// The Arguments string is a string of characters as understood by
|
||||
// the DECORATE parser:
|
||||
//
|
||||
// If the letter is uppercase, it is required. Lowercase letters are optional.
|
||||
// i = integer
|
||||
// f = fixed point
|
||||
// s = sound name
|
||||
// m = actor name
|
||||
// t = string
|
||||
// l = jump label
|
||||
// c = color
|
||||
// x = expression
|
||||
// y = expression
|
||||
// If the final character is a +, the previous parameter is repeated indefinitely,
|
||||
// and an "imaginary" first parameter is inserted containing the total number of
|
||||
// parameters passed.
|
||||
|
||||
struct PSymbolActionFunction : public PSymbol
|
||||
{
|
||||
FString Arguments;
|
||||
void (*Function)(AActor*);
|
||||
};
|
||||
|
||||
// A symbol table -----------------------------------------------------------
|
||||
|
||||
class PSymbolTable
|
||||
{
|
||||
public:
|
||||
PSymbolTable();
|
||||
~PSymbolTable();
|
||||
|
||||
// Sets the table to use for searches if this one doesn't contain the
|
||||
// requested symbol.
|
||||
void SetParentTable (PSymbolTable *parent);
|
||||
|
||||
// Finds a symbol in the table, optionally searching parent tables
|
||||
// as well.
|
||||
PSymbol *FindSymbol (FName symname, bool searchparents) const;
|
||||
|
||||
// Places the symbol in the table and returns a pointer to it or NULL if
|
||||
// a symbol with the same name is already in the table. This symbol is
|
||||
// not copied and will be freed when the symbol table is destroyed.
|
||||
PSymbol *AddSymbol (PSymbol *sym);
|
||||
|
||||
private:
|
||||
PSymbolTable *ParentSymbolTable;
|
||||
TArray<PSymbol *> Symbols;
|
||||
};
|
||||
|
||||
// Meta-info for every class derived from DObject ---------------------------
|
||||
|
||||
struct PClass
|
||||
{
|
||||
static void StaticInit ();
|
||||
|
@ -23,6 +97,7 @@ struct PClass
|
|||
BYTE *Defaults;
|
||||
bool bRuntimeClass; // class was defined at run-time, not compile-time
|
||||
unsigned short ClassIndex;
|
||||
PSymbolTable Symbols;
|
||||
|
||||
void (*ConstructNative)(void *);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ xx(None)
|
|||
|
||||
xx(Super)
|
||||
xx(Object)
|
||||
xx(Actor)
|
||||
|
||||
xx(Untranslated)
|
||||
|
||||
|
@ -178,4 +179,22 @@ xx(Massacre) // For death by a cheater!
|
|||
// a damage type if you wanted to force an extreme death.
|
||||
xx(Extreme)
|
||||
|
||||
|
||||
// Special names for thingdef_exp.cpp
|
||||
xx(Random)
|
||||
xx(Random2)
|
||||
xx(Cos)
|
||||
xx(Sin)
|
||||
xx(Alpha)
|
||||
xx(Angle)
|
||||
xx(Args)
|
||||
xx(CeilingZ)
|
||||
xx(FloorZ)
|
||||
xx(Health)
|
||||
xx(Pitch)
|
||||
xx(Special)
|
||||
xx(TID)
|
||||
xx(TIDtoHate)
|
||||
xx(WaterLevel)
|
||||
xx(X)
|
||||
xx(Y)
|
||||
xx(Z)
|
||||
|
|
|
@ -1479,8 +1479,6 @@ void FBehavior::StaticStopMyScripts (AActor *actor)
|
|||
|
||||
//---- The ACS Interpreter ----//
|
||||
|
||||
void strbin (char *str);
|
||||
|
||||
IMPLEMENT_CLASS (DACSThinker)
|
||||
|
||||
DACSThinker *DACSThinker::ActiveThinker = NULL;
|
||||
|
@ -5288,77 +5286,6 @@ void P_TerminateScript (int script, char *map)
|
|||
SetScriptState (script, DLevelScript::SCRIPT_PleaseRemove);
|
||||
}
|
||||
|
||||
void strbin (char *str)
|
||||
{
|
||||
char *p = str, c;
|
||||
int i;
|
||||
|
||||
while ( (c = *p++) ) {
|
||||
if (c != '\\') {
|
||||
*str++ = c;
|
||||
} else {
|
||||
switch (*p) {
|
||||
case 'c':
|
||||
*str++ = TEXTCOLOR_ESCAPE;
|
||||
break;
|
||||
case 'n':
|
||||
*str++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
*str++ = '\t';
|
||||
break;
|
||||
case 'r':
|
||||
*str++ = '\r';
|
||||
break;
|
||||
case '\n':
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
c = 0;
|
||||
p++;
|
||||
for (i = 0; i < 2; i++) {
|
||||
c <<= 4;
|
||||
if (*p >= '0' && *p <= '9')
|
||||
c += *p-'0';
|
||||
else if (*p >= 'a' && *p <= 'f')
|
||||
c += 10 + *p-'a';
|
||||
else if (*p >= 'A' && *p <= 'F')
|
||||
c += 10 + *p-'A';
|
||||
else
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
*str++ = c;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
c = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
c <<= 3;
|
||||
if (*p >= '0' && *p <= '7')
|
||||
c += *p-'0';
|
||||
else
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
*str++ = c;
|
||||
break;
|
||||
default:
|
||||
*str++ = *p;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
*str = 0;
|
||||
}
|
||||
|
||||
FArchive &operator<< (FArchive &arc, acsdefered_s *&defertop)
|
||||
{
|
||||
BYTE more;
|
||||
|
|
|
@ -491,8 +491,8 @@ static void ReadEAX ()
|
|||
{
|
||||
SC_MustGetFloat ();
|
||||
props.*EAXFields[i].Float = clamp (sc_Float,
|
||||
float(EAXFields[i].Min)/1000.f,
|
||||
float(EAXFields[i].Max)/1000.f);
|
||||
double(EAXFields[i].Min)/1000,
|
||||
double(EAXFields[i].Max)/1000);
|
||||
}
|
||||
else if (EAXFields[i].Int)
|
||||
{
|
||||
|
|
285
src/sc_man.cpp
285
src/sc_man.cpp
|
@ -45,16 +45,19 @@
|
|||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void SC_PrepareScript (void);
|
||||
static bool SC_ScanString (bool tokens);
|
||||
static void CheckOpen (void);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
int sc_TokenType;
|
||||
char *sc_String;
|
||||
int sc_StringLen;
|
||||
unsigned int sc_StringLen;
|
||||
int sc_Number;
|
||||
float sc_Float;
|
||||
double sc_Float;
|
||||
FName sc_Name;
|
||||
int sc_Line;
|
||||
bool sc_End;
|
||||
bool sc_Crossed;
|
||||
|
@ -71,6 +74,8 @@ static char StringBuffer[MAX_STRING_SIZE];
|
|||
static bool ScriptOpen = false;
|
||||
static int ScriptSize;
|
||||
static bool AlreadyGot = false;
|
||||
static bool LastGotToken = false;
|
||||
static char *LastGotPtr;
|
||||
static bool FreeScript = false;
|
||||
static char *SavedScriptPtr;
|
||||
static int SavedScriptLine;
|
||||
|
@ -108,7 +113,10 @@ void SC_OpenFile (const char *name)
|
|||
|
||||
SC_Close ();
|
||||
ScriptSize = M_ReadFile (name, &filebuf);
|
||||
ScriptBuffer = (char *)filebuf;
|
||||
ScriptBuffer = new char[ScriptSize + 1];
|
||||
memcpy (ScriptBuffer, filebuf, ScriptSize);
|
||||
ScriptBuffer[ScriptSize++] = '\n';
|
||||
delete[] filebuf;
|
||||
ScriptName = name; // This is used for error messages so the full file name is preferable
|
||||
FreeScript = true;
|
||||
SC_PrepareScript ();
|
||||
|
@ -119,7 +127,8 @@ void SC_OpenFile (const char *name)
|
|||
// SC_OpenMem
|
||||
//
|
||||
// Prepares a script that is already in memory for parsing. The caller is
|
||||
// responsible for freeing it, if needed.
|
||||
// responsible for freeing it, if needed. You MUST ensure that the script
|
||||
// ends with the newline character '\n'.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -145,8 +154,9 @@ void SC_OpenLumpNum (int lump, const char *name)
|
|||
{
|
||||
SC_Close ();
|
||||
ScriptSize = Wads.LumpLength (lump);
|
||||
ScriptBuffer = new char[ScriptSize];
|
||||
ScriptBuffer = new char[ScriptSize + 1];
|
||||
Wads.ReadLump (lump, ScriptBuffer);
|
||||
ScriptBuffer[ScriptSize++] = '\n';
|
||||
ScriptName = name;
|
||||
FreeScript = true;
|
||||
SC_PrepareScript ();
|
||||
|
@ -169,6 +179,8 @@ static void SC_PrepareScript (void)
|
|||
ScriptOpen = true;
|
||||
sc_String = StringBuffer;
|
||||
AlreadyGot = false;
|
||||
LastGotToken = false;
|
||||
LastGotPtr = NULL;
|
||||
SavedScriptPtr = NULL;
|
||||
CMode = false;
|
||||
Escape = true;
|
||||
|
@ -234,6 +246,7 @@ void SC_RestorePos (void)
|
|||
sc_Line = SavedScriptLine;
|
||||
sc_End = false;
|
||||
AlreadyGot = false;
|
||||
LastGotToken = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,20 +280,28 @@ void SC_SetEscape (bool esc)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetString
|
||||
// SC_ScanString
|
||||
//
|
||||
// Set tokens true if you want sc_TokenType to be set.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SC_GetString ()
|
||||
static bool SC_ScanString (bool tokens)
|
||||
{
|
||||
char *marker, *tok;
|
||||
bool return_val;
|
||||
|
||||
CheckOpen();
|
||||
if (AlreadyGot)
|
||||
{
|
||||
AlreadyGot = false;
|
||||
if (!tokens || LastGotToken)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
ScriptPtr = LastGotPtr;
|
||||
}
|
||||
|
||||
sc_Crossed = false;
|
||||
if (ScriptPtr >= ScriptEndPtr)
|
||||
{
|
||||
|
@ -288,9 +309,24 @@ bool SC_GetString ()
|
|||
return false;
|
||||
}
|
||||
|
||||
LastGotPtr = ScriptPtr;
|
||||
|
||||
// In case the generated scanner does not use marker, avoid compiler warnings.
|
||||
marker;
|
||||
#include "sc_man_scanner.h"
|
||||
LastGotToken = tokens;
|
||||
return return_val;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetString
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SC_GetString ()
|
||||
{
|
||||
return SC_ScanString (false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -343,6 +379,93 @@ bool SC_CheckString (const char *name)
|
|||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetToken
|
||||
//
|
||||
// Sets sc_Float, sc_Number, and sc_Name based on sc_TokenType.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool SC_GetToken ()
|
||||
{
|
||||
if (SC_ScanString (true))
|
||||
{
|
||||
if (sc_TokenType == TK_Identifier || sc_TokenType == TK_NameConst)
|
||||
{
|
||||
sc_Name = FName(sc_String);
|
||||
}
|
||||
else if (sc_TokenType == TK_IntConst)
|
||||
{
|
||||
char *stopper;
|
||||
sc_Number = strtol(sc_String, &stopper, 0);
|
||||
sc_Float = sc_Number;
|
||||
}
|
||||
else if (sc_TokenType == TK_FloatConst)
|
||||
{
|
||||
char *stopper;
|
||||
sc_Float = strtod(sc_String, &stopper);
|
||||
}
|
||||
else if (sc_TokenType == TK_StringConst)
|
||||
{
|
||||
strbin (sc_String);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustGetAnyToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_MustGetAnyToken (void)
|
||||
{
|
||||
if (SC_GetToken () == false)
|
||||
{
|
||||
SC_ScriptError ("Missing token (unexpected end of file).");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustGetToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_MustGetToken (int token)
|
||||
{
|
||||
SC_MustGetAnyToken ();
|
||||
if (sc_TokenType != token)
|
||||
{
|
||||
SC_ScriptError ("Expected %s but got %s instead.",
|
||||
SC_TokenName(token), SC_TokenName(sc_TokenType, sc_String));
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_CheckToken
|
||||
//
|
||||
// Checks if the next token matches the specified token. Returns true if
|
||||
// it does. If it doesn't, it ungets it and returns false.
|
||||
//==========================================================================
|
||||
|
||||
bool SC_CheckToken (int token)
|
||||
{
|
||||
if (SC_GetToken ())
|
||||
{
|
||||
if (sc_TokenType == token)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
SC_UnGet ();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetNumber
|
||||
|
@ -603,6 +726,153 @@ bool SC_Compare (const char *text)
|
|||
return (stricmp (text, sc_String) == 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_TokenName
|
||||
//
|
||||
// Returns the name of a token.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString SC_TokenName (int token, const char *string)
|
||||
{
|
||||
static const char *const names[] =
|
||||
{
|
||||
"an identifier",
|
||||
"a string constant",
|
||||
"a name constant",
|
||||
"an integer constant",
|
||||
"a float constant",
|
||||
"'...'",
|
||||
"'>>='",
|
||||
"'<<='",
|
||||
"'+='",
|
||||
"'-='",
|
||||
"'*='",
|
||||
"'/='",
|
||||
"'%='",
|
||||
"'&='",
|
||||
"'^='",
|
||||
"'|='",
|
||||
"'>>'",
|
||||
"'<<'",
|
||||
"'++'",
|
||||
"'--'",
|
||||
"'&&'",
|
||||
"'||'",
|
||||
"'<='",
|
||||
"'>='",
|
||||
"'=='",
|
||||
"'!="
|
||||
"'break'",
|
||||
"'case'",
|
||||
"'const'",
|
||||
"'continue'",
|
||||
"'default'",
|
||||
"'do'",
|
||||
"'else'",
|
||||
"'for'",
|
||||
"'if'",
|
||||
"'return'",
|
||||
"'states'",
|
||||
"'switch'",
|
||||
"'until'",
|
||||
"'while'",
|
||||
"'bool'",
|
||||
"'float'",
|
||||
"'double'",
|
||||
"'char'",
|
||||
"'byte'",
|
||||
"'sbyte'",
|
||||
"'short'",
|
||||
"'ushort'",
|
||||
"'int'",
|
||||
"'uint'",
|
||||
"'long'",
|
||||
"'ulong'",
|
||||
"'void'",
|
||||
"'struct'",
|
||||
"'class'",
|
||||
"'mode'",
|
||||
"'enum'",
|
||||
"'name'",
|
||||
"'string'",
|
||||
"'sound'",
|
||||
"'state'",
|
||||
"'color'",
|
||||
"'goto'",
|
||||
"'abstract'",
|
||||
"'foreach'",
|
||||
"'true'",
|
||||
"'false'",
|
||||
"'none'",
|
||||
"'new'",
|
||||
"'instanceof'",
|
||||
"'auto'",
|
||||
"'exec'",
|
||||
"'defaultproperties'",
|
||||
"'native'",
|
||||
"'out'",
|
||||
"'ref'",
|
||||
"'event'",
|
||||
"'static'",
|
||||
"'transient'",
|
||||
"'volatile'",
|
||||
"'final'",
|
||||
"'throws'",
|
||||
"'extends'",
|
||||
"'public'",
|
||||
"'protected'",
|
||||
"'private'",
|
||||
"'dot'",
|
||||
"'cross'",
|
||||
"'ignores'",
|
||||
"'localized'",
|
||||
"'latent'",
|
||||
"'singular'",
|
||||
"'config'",
|
||||
"'coerce'",
|
||||
"'iterator'",
|
||||
"'optional'",
|
||||
"'export'",
|
||||
"'virtual'",
|
||||
"'super'",
|
||||
"'global'",
|
||||
"'self'",
|
||||
"'stop'",
|
||||
"'eval'",
|
||||
"'evalnot'",
|
||||
};
|
||||
|
||||
FString work;
|
||||
|
||||
if (token > ' ' && token < 256)
|
||||
{
|
||||
work = '\'';
|
||||
work += token;
|
||||
work += '\'';
|
||||
}
|
||||
else if (token >= TK_Identifier && token < TK_LastToken)
|
||||
{
|
||||
work = names[token - TK_Identifier];
|
||||
if (string != NULL && token >= TK_Identifier && token <= TK_FloatConst)
|
||||
{
|
||||
work += ' ';
|
||||
char quote = (token == TK_StringConst) ? '"' : '\'';
|
||||
work += quote;
|
||||
work += string;
|
||||
work += quote;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FString work;
|
||||
work.Format ("Unknown(%d)", token);
|
||||
return work;
|
||||
}
|
||||
return work;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_ScriptError
|
||||
|
@ -723,5 +993,6 @@ void SC_RestoreScriptState()
|
|||
Escape = ss.Escape;
|
||||
SavedScripts.ShrinkToFit();
|
||||
AlreadyGot = false;
|
||||
LastGotToken = false;
|
||||
}
|
||||
}
|
||||
|
|
122
src/sc_man.h
122
src/sc_man.h
|
@ -10,10 +10,16 @@ void SC_SetCMode (bool cmode);
|
|||
void SC_SetEscape (bool esc);
|
||||
void SC_SavePos (void);
|
||||
void SC_RestorePos (void);
|
||||
FString SC_TokenName (int token, const char *string=NULL);
|
||||
bool SC_GetString (void);
|
||||
void SC_MustGetString (void);
|
||||
void SC_MustGetStringName (const char *name);
|
||||
bool SC_CheckString (const char *name);
|
||||
bool SC_GetToken (void);
|
||||
void SC_MustGetAnyToken (void);
|
||||
void SC_MustGetToken (int token);
|
||||
bool SC_CheckToken (int token);
|
||||
bool SC_CheckTokenId (ENamedName id);
|
||||
bool SC_GetNumber (void);
|
||||
void SC_MustGetNumber (void);
|
||||
bool SC_CheckNumber (void);
|
||||
|
@ -29,10 +35,122 @@ void STACK_ARGS SC_ScriptError (const char *message, ...);
|
|||
void SC_SaveScriptState();
|
||||
void SC_RestoreScriptState();
|
||||
|
||||
enum
|
||||
{
|
||||
TK_Identifier = 257,
|
||||
TK_StringConst,
|
||||
TK_NameConst,
|
||||
TK_IntConst,
|
||||
TK_FloatConst,
|
||||
TK_Ellipsis, // ...
|
||||
TK_RShiftEq, // >>=
|
||||
TK_LShiftEq, // <<=
|
||||
TK_AddEq, // +=
|
||||
TK_SubEq, // -=
|
||||
TK_MulEq, // *=
|
||||
TK_DivEq, // /=
|
||||
TK_ModEq, // %=
|
||||
TK_AndEq, // &=
|
||||
TK_XorEq, // ^=
|
||||
TK_OrEq, // |=
|
||||
TK_RShift, // >>
|
||||
TK_LShift, // <<
|
||||
TK_Incr, // ++
|
||||
TK_Decr, // --
|
||||
TK_AndAnd, // &&
|
||||
TK_OrOr, // ||
|
||||
TK_Leq, // <=
|
||||
TK_Geq, // >=
|
||||
TK_Eq, // ==
|
||||
TK_Neq, // !=
|
||||
TK_Break,
|
||||
TK_Case,
|
||||
TK_Const,
|
||||
TK_Continue,
|
||||
TK_Default,
|
||||
TK_Do,
|
||||
TK_Else,
|
||||
TK_For,
|
||||
TK_If,
|
||||
TK_Return,
|
||||
TK_States,
|
||||
TK_Switch,
|
||||
TK_Until,
|
||||
TK_While,
|
||||
TK_Bool,
|
||||
TK_Float,
|
||||
TK_Double,
|
||||
TK_Char,
|
||||
TK_Byte,
|
||||
TK_SByte,
|
||||
TK_Short,
|
||||
TK_UShort,
|
||||
TK_Int,
|
||||
TK_UInt,
|
||||
TK_Long,
|
||||
TK_ULong,
|
||||
TK_Void,
|
||||
TK_Struct,
|
||||
TK_Class,
|
||||
TK_Mode,
|
||||
TK_Enum,
|
||||
TK_Name,
|
||||
TK_String,
|
||||
TK_Sound,
|
||||
TK_State,
|
||||
TK_Color,
|
||||
TK_Goto,
|
||||
TK_Abstract,
|
||||
TK_ForEach,
|
||||
TK_True,
|
||||
TK_False,
|
||||
TK_None,
|
||||
TK_New,
|
||||
TK_InstanceOf,
|
||||
TK_Auto,
|
||||
TK_Exec,
|
||||
TK_DefaultProperties,
|
||||
TK_Native,
|
||||
TK_Out,
|
||||
TK_Ref,
|
||||
TK_Event,
|
||||
TK_Static,
|
||||
TK_Transient,
|
||||
TK_Volatile,
|
||||
TK_Final,
|
||||
TK_Throws,
|
||||
TK_Extends,
|
||||
TK_Public,
|
||||
TK_Protected,
|
||||
TK_Private,
|
||||
TK_Dot,
|
||||
TK_Cross,
|
||||
TK_Ignores,
|
||||
TK_Localized,
|
||||
TK_Latent,
|
||||
TK_Singular,
|
||||
TK_Config,
|
||||
TK_Coerce,
|
||||
TK_Iterator,
|
||||
TK_Optional,
|
||||
TK_Export,
|
||||
TK_Virtual,
|
||||
TK_Super,
|
||||
TK_Global,
|
||||
TK_Self,
|
||||
TK_Stop,
|
||||
TK_Eval,
|
||||
TK_EvalNot,
|
||||
|
||||
TK_LastToken
|
||||
};
|
||||
|
||||
extern int sc_TokenType;
|
||||
extern char *sc_String;
|
||||
extern int sc_StringLen;
|
||||
extern unsigned int sc_StringLen;
|
||||
extern int sc_Number;
|
||||
extern float sc_Float;
|
||||
extern double sc_Float;
|
||||
extern FName sc_Name;
|
||||
extern int sc_Line;
|
||||
extern bool sc_End;
|
||||
extern bool sc_Crossed;
|
||||
|
|
4381
src/sc_man_scanner.h
4381
src/sc_man_scanner.h
File diff suppressed because it is too large
Load diff
|
@ -2,19 +2,21 @@
|
|||
#define YYCURSOR cursor
|
||||
#define YYLIMIT limit
|
||||
#define YYMARKER marker
|
||||
|
||||
#define YYFILL(n) {}
|
||||
#if 0 // As long as the buffer ends with '\n', we need do nothing special for YYFILL.
|
||||
// This buffer must be as large as the largest YYFILL call
|
||||
YYCTYPE eofbuf[3];
|
||||
YYCTYPE eofbuf[9];
|
||||
#define YYFILL(n) \
|
||||
{ if(!sc_End) { \
|
||||
if(n == 2) { eofbuf[0] = *cursor; } \
|
||||
else if(n == 3) { eofbuf[0] = *cursor; eofbuf[1] = *(cursor + 1); } \
|
||||
else if(n >= 3 && n <= 9) { memcpy(eofbuf, cursor, n-1); } \
|
||||
eofbuf[n-1] = '\n'; \
|
||||
cursor = eofbuf; \
|
||||
limit = eofbuf + n - 1; \
|
||||
sc_End = true; } \
|
||||
} \
|
||||
assert(n <= 3) // Semicolon intentionally omitted
|
||||
assert(n <= sizeof eofbuf) // Semicolon intentionally omitted
|
||||
#endif
|
||||
|
||||
//#define YYDEBUG(s,c) { Printf ("%d: %02x\n", s, c); }
|
||||
#define YYDEBUG(s,c)
|
||||
|
@ -29,8 +31,14 @@ std2:
|
|||
any = [\000-\377];
|
||||
WSP = ([\000- ]\[\n]);
|
||||
NWS = (any\[\000- ]);
|
||||
O = [0-7];
|
||||
D = [0-9];
|
||||
X = [0-9A-Fa-f];
|
||||
L = [a-zA-Z_];
|
||||
H = [a-fA-F0-9];
|
||||
E = [Ee] [+-]? D+;
|
||||
FS = [fFlL];
|
||||
IS = [uUlL];
|
||||
ESC = [\\] ([abcfnrtv?'"\\] | "x" H+ | O+);
|
||||
|
||||
TOK1 = [{}|=];
|
||||
TOKC = [{}|=/`~!@#$%^&*()\[\]\\?\-=+;:<>,.];
|
||||
|
@ -41,7 +49,169 @@ std2:
|
|||
TOK2 = (NWS\STOP1);
|
||||
TOKC2 = (NWS\STOPC);
|
||||
*/
|
||||
if (!CMode)
|
||||
if (tokens) // A well-defined scanner, based on the c.re example.
|
||||
{
|
||||
#define RET(x) sc_TokenType = x; goto normal_token;
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
"//" (any\"\n")* "\n" { goto newline; } /* C++ comment */
|
||||
|
||||
/* C Keywords */
|
||||
'break' { RET(TK_Break); }
|
||||
'case' { RET(TK_Case); }
|
||||
'const' { RET(TK_Const); }
|
||||
'continue' { RET(TK_Continue); }
|
||||
'default' { RET(TK_Default); }
|
||||
'do' { RET(TK_Do); }
|
||||
'else' { RET(TK_Else); }
|
||||
'for' { RET(TK_For); }
|
||||
'goto' { RET(TK_Goto); }
|
||||
'if' { RET(TK_If); }
|
||||
'return' { RET(TK_Return); }
|
||||
'states' { RET(TK_States); }
|
||||
'switch' { RET(TK_Switch); }
|
||||
'until' { RET(TK_Until); }
|
||||
'volatile' { RET(TK_Volatile); }
|
||||
'while' { RET(TK_While); }
|
||||
|
||||
/* Type names */
|
||||
'bool' { RET(TK_Bool); }
|
||||
'float' { RET(TK_Float); }
|
||||
'double' { RET(TK_Double); }
|
||||
'char' { RET(TK_Char); }
|
||||
'byte' { RET(TK_Byte); }
|
||||
'sbyte' { RET(TK_SByte); }
|
||||
'short' { RET(TK_Short); }
|
||||
'ushort' { RET(TK_UShort); }
|
||||
'int' { RET(TK_Int); }
|
||||
'uint' { RET(TK_UInt); }
|
||||
'long' { RET(TK_Long); }
|
||||
'ulong' { RET(TK_ULong); }
|
||||
'void' { RET(TK_Void); }
|
||||
'struct' { RET(TK_Struct); }
|
||||
'class' { RET(TK_Class); }
|
||||
'mode' { RET(TK_Mode); }
|
||||
'enum' { RET(TK_Enum); }
|
||||
'name' { RET(TK_Name); }
|
||||
'string' { RET(TK_String); }
|
||||
'sound' { RET(TK_Sound); }
|
||||
'state' { RET(TK_State); }
|
||||
'color' { RET(TK_Color); }
|
||||
|
||||
/* Other keywords from UnrealScript */
|
||||
'abstract' { RET(TK_Abstract); }
|
||||
'foreach' { RET(TK_ForEach); }
|
||||
'true' { RET(TK_True); }
|
||||
'false' { RET(TK_False); }
|
||||
'none' { RET(TK_None); }
|
||||
'new' { RET(TK_New); }
|
||||
'instanceof' { RET(TK_InstanceOf); }
|
||||
'auto' { RET(TK_Auto); }
|
||||
'exec' { RET(TK_Exec); }
|
||||
'defaultproperties' { RET(TK_DefaultProperties); }
|
||||
'native' { RET(TK_Native); }
|
||||
'out' { RET(TK_Out); }
|
||||
'ref' { RET(TK_Ref); }
|
||||
'event' { RET(TK_Event); }
|
||||
'static' { RET(TK_Static); }
|
||||
'transient' { RET(TK_Transient); }
|
||||
'final' { RET(TK_Final); }
|
||||
'throws' { RET(TK_Throws); }
|
||||
'extends' { RET(TK_Extends); }
|
||||
'public' { RET(TK_Public); }
|
||||
'protected' { RET(TK_Protected); }
|
||||
'private' { RET(TK_Private); }
|
||||
'dot' { RET(TK_Dot); }
|
||||
'cross' { RET(TK_Cross); }
|
||||
'ignores' { RET(TK_Ignores); }
|
||||
'localized' { RET(TK_Localized); }
|
||||
'latent' { RET(TK_Latent); }
|
||||
'singular' { RET(TK_Singular); }
|
||||
'config' { RET(TK_Config); }
|
||||
'coerce' { RET(TK_Coerce); }
|
||||
'iterator' { RET(TK_Iterator); }
|
||||
'optional' { RET(TK_Optional); }
|
||||
'export' { RET(TK_Export); }
|
||||
'virtual' { RET(TK_Virtual); }
|
||||
'super' { RET(TK_Super); }
|
||||
'global' { RET(TK_Global); }
|
||||
'self' { RET(TK_Self); }
|
||||
'stop' { RET(TK_Stop); }
|
||||
|
||||
/* Needed for decorate action functions */
|
||||
"eval" { RET(TK_Eval); }
|
||||
"evalnot" { RET(TK_EvalNot); }
|
||||
|
||||
L (L|D)* { RET(TK_Identifier); }
|
||||
|
||||
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?)
|
||||
{ RET(TK_IntConst); }
|
||||
|
||||
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
|
||||
{ RET(TK_FloatConst); }
|
||||
|
||||
(["] (ESC|any\[\n\\"])* ["])
|
||||
{ RET(TK_StringConst); }
|
||||
|
||||
(['] (any\[\n'])* ['])
|
||||
{ RET(TK_NameConst); }
|
||||
|
||||
"..." { RET(TK_Ellipsis); }
|
||||
">>=" { RET(TK_RShiftEq); }
|
||||
"<<=" { RET(TK_LShiftEq); }
|
||||
"+=" { RET(TK_AddEq); }
|
||||
"-=" { RET(TK_SubEq); }
|
||||
"*=" { RET(TK_MulEq); }
|
||||
"/=" { RET(TK_DivEq); }
|
||||
"%=" { RET(TK_ModEq); }
|
||||
"&=" { RET(TK_AndEq); }
|
||||
"^=" { RET(TK_XorEq); }
|
||||
"|=" { RET(TK_OrEq); }
|
||||
">>" { RET(TK_RShift); }
|
||||
"<<" { RET(TK_LShift); }
|
||||
"++" { RET(TK_Incr); }
|
||||
"--" { RET(TK_Decr); }
|
||||
"&&" { RET(TK_AndAnd); }
|
||||
"||" { RET(TK_OrOr); }
|
||||
"<=" { RET(TK_Leq); }
|
||||
">=" { RET(TK_Geq); }
|
||||
"==" { RET(TK_Eq); }
|
||||
"!=" { RET(TK_Neq); }
|
||||
";" { RET(';'); }
|
||||
"{" { RET('{'); }
|
||||
"}" { RET('}'); }
|
||||
"," { RET(','); }
|
||||
":" { RET(':'); }
|
||||
"=" { RET('='); }
|
||||
"(" { RET('('); }
|
||||
")" { RET(')'); }
|
||||
"[" { RET('['); }
|
||||
"]" { RET(']'); }
|
||||
"." { RET('.'); }
|
||||
"&" { RET('&'); }
|
||||
"!" { RET('!'); }
|
||||
"~" { RET('~'); }
|
||||
"-" { RET('-'); }
|
||||
"+" { RET('+'); }
|
||||
"*" { RET('*'); }
|
||||
"/" { RET('/'); }
|
||||
"%" { RET('%'); }
|
||||
"<" { RET('<'); }
|
||||
">" { RET('>'); }
|
||||
"^" { RET('^'); }
|
||||
"|" { RET('|'); }
|
||||
"?" { RET('?'); }
|
||||
|
||||
[ \t\v\f\r]+ { goto std1; }
|
||||
"\n" { goto newline; }
|
||||
any
|
||||
{
|
||||
SC_ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
|
||||
goto std1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (!CMode) // The classic Hexen scanner.
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
|
@ -59,7 +229,7 @@ std2:
|
|||
any { goto normal_token; } /* unknown character */
|
||||
*/
|
||||
}
|
||||
else
|
||||
else // A modified Hexen scanner for DECORATE.
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
|
@ -87,6 +257,7 @@ std2:
|
|||
negative_check:
|
||||
// re2c doesn't have enough state to handle '-' as the start of a negative number
|
||||
// and as its own token, so help it out a little.
|
||||
sc_TokenType = '-';
|
||||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
goto normal_token;
|
||||
|
@ -112,7 +283,8 @@ comment:
|
|||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return false;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
goto std1;
|
||||
}
|
||||
|
@ -121,7 +293,8 @@ comment:
|
|||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return false;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
sc_Line++;
|
||||
sc_Crossed = true;
|
||||
|
@ -134,7 +307,8 @@ newline:
|
|||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return false;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
sc_Line++;
|
||||
sc_Crossed = true;
|
||||
|
@ -143,15 +317,25 @@ newline:
|
|||
normal_token:
|
||||
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
|
||||
sc_StringLen = MIN (ScriptPtr - tok, MAX_STRING_SIZE-1);
|
||||
if (tokens && (sc_TokenType == TK_StringConst || sc_TokenType == TK_NameConst))
|
||||
{
|
||||
sc_StringLen -= 2;
|
||||
memcpy (sc_String, tok+1, sc_StringLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (sc_String, tok, sc_StringLen);
|
||||
}
|
||||
sc_String[sc_StringLen] = '\0';
|
||||
return true;
|
||||
return_val = true;
|
||||
goto end;
|
||||
|
||||
string:
|
||||
if (YYLIMIT != ScriptEndPtr)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return false;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
ScriptPtr = cursor;
|
||||
for (sc_StringLen = 0; cursor < YYLIMIT; ++cursor)
|
||||
|
@ -191,4 +375,5 @@ string:
|
|||
}
|
||||
ScriptPtr = cursor + 1;
|
||||
sc_String[sc_StringLen] = '\0';
|
||||
return true;
|
||||
return_val = true;
|
||||
end:
|
||||
|
|
196
src/thingdef.cpp
196
src/thingdef.cpp
|
@ -361,7 +361,6 @@ static flagdef *FindFlag (const PClass *type, const char *part1, const char *par
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int EvalExpressionI (int id, AActor *self);
|
||||
//===========================================================================
|
||||
//
|
||||
// A_ChangeFlag
|
||||
|
@ -1589,7 +1588,7 @@ bool DoSpecialFunctions(FState & state, bool multistate, int * statecount, Bagga
|
|||
{
|
||||
for (i = 0; i < 5;)
|
||||
{
|
||||
StateParameters[paramindex+i+1]=ParseExpression (false);
|
||||
StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class);
|
||||
i++;
|
||||
if (!SC_CheckString (",")) break;
|
||||
}
|
||||
|
@ -1851,6 +1850,16 @@ do_stop:
|
|||
goto endofstate;
|
||||
}
|
||||
|
||||
//AFuncDesc * afd = FindFunction(sc_String);
|
||||
//PSymbolActionFunction *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
|
||||
//if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
|
||||
//{
|
||||
// PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
|
||||
// state.Action = afd->Function;
|
||||
// if (!afd->Arguments.IsEmpty())
|
||||
// {
|
||||
// const char *params = afd->Arguments.GetChars();
|
||||
// int numparams = afd->Arguments.Len();
|
||||
AFuncDesc * afd = FindFunction(sc_String);
|
||||
if (afd != NULL)
|
||||
{
|
||||
|
@ -1859,6 +1868,7 @@ do_stop:
|
|||
{
|
||||
const char * params = afd->parameters;
|
||||
int numparams = (int)strlen(params);
|
||||
|
||||
int v;
|
||||
|
||||
if (!islower(*params))
|
||||
|
@ -1883,31 +1893,6 @@ do_stop:
|
|||
{
|
||||
switch(*params)
|
||||
{
|
||||
/*
|
||||
case 'A':
|
||||
case 'a': // Angle
|
||||
SC_MustGetFloat();
|
||||
v=(int)angle_t(sc_Float*ANGLE_1);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b': // Byte
|
||||
SC_MustGetNumber();
|
||||
v=clamp<int>(sc_Number, 0, 255);
|
||||
break;
|
||||
|
||||
case '9': // 90 degree angle as integer
|
||||
SC_MustGetNumber();
|
||||
v=clamp<int>(sc_Number, 0, 90);
|
||||
break;
|
||||
|
||||
case '!': // not boolean (to simulate parameters which default to 1)
|
||||
SC_MustGetNumber();
|
||||
v=!sc_Number;
|
||||
break;
|
||||
|
||||
*/
|
||||
|
||||
case 'I':
|
||||
case 'i': // Integer
|
||||
SC_MustGetNumber();
|
||||
|
@ -2038,12 +2023,12 @@ do_stop:
|
|||
|
||||
case 'X':
|
||||
case 'x':
|
||||
v = ParseExpression (false);
|
||||
v = ParseExpression (false, bag.Info->Class);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
case 'y':
|
||||
v = ParseExpression (true);
|
||||
v = ParseExpression (true, bag.Info->Class);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2543,6 +2528,153 @@ static void StatePropertyIsDeprecated (const char *actorname, const char *prop)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ActorConstDef
|
||||
//
|
||||
// Parses a constant definition.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ActorConstDef (AActor *defaults, Baggage &bag)
|
||||
{
|
||||
// Read the type and make sure it's int.
|
||||
// (Maybe there will be other types later.)
|
||||
SC_MustGetToken(TK_Int);
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
FName symname = sc_Name;
|
||||
SC_MustGetToken('=');
|
||||
int expr = ParseExpression (false, bag.Info->Class);
|
||||
SC_MustGetToken(';');
|
||||
|
||||
int val = EvalExpressionI (expr, NULL, bag.Info->Class);
|
||||
PSymbolConst *sym = new PSymbolConst;
|
||||
sym->SymbolName = symname;
|
||||
sym->SymbolType = SYM_Const;
|
||||
sym->Value = val;
|
||||
if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
SC_ScriptError ("'%s' is already defined in class '%s'.",
|
||||
symname.GetChars(), bag.Info->Class->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ActorActionDef
|
||||
//
|
||||
// Parses an action function definition.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ActorActionDef (AActor *defaults, Baggage &bag)
|
||||
{
|
||||
#define OPTIONAL 1
|
||||
#define EVAL 2
|
||||
#define EVALNOT 4
|
||||
|
||||
FName funcname;
|
||||
FString args;
|
||||
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
funcname = sc_Name;
|
||||
SC_MustGetToken('(');
|
||||
while (sc_TokenType != ')')
|
||||
{
|
||||
int flags = 0;
|
||||
char type = '@';
|
||||
|
||||
// Retrieve flags before type name
|
||||
for (;;)
|
||||
{
|
||||
if (SC_CheckToken(TK_Optional))
|
||||
{
|
||||
flags |= OPTIONAL;
|
||||
}
|
||||
else if (SC_CheckToken(TK_Eval))
|
||||
{
|
||||
flags |= EVAL;
|
||||
}
|
||||
else if (SC_CheckToken(TK_EvalNot))
|
||||
{
|
||||
flags |= EVALNOT;
|
||||
}
|
||||
else if (SC_CheckToken(TK_Coerce) || SC_CheckToken(TK_Native))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flags != 0)
|
||||
{
|
||||
SC_MustGetAnyToken();
|
||||
}
|
||||
switch (sc_TokenType)
|
||||
{
|
||||
case TK_Int: type = 'i'; break;
|
||||
case TK_Float: type = 'f'; break;
|
||||
case TK_Sound: type = 's'; break;
|
||||
case TK_String: type = 't'; break;
|
||||
case TK_State: type = 'l'; break;
|
||||
case TK_Color: type = 'c'; break;
|
||||
case TK_Class:
|
||||
SC_MustGetToken('<');
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
if (sc_Name != NAME_Actor)
|
||||
{
|
||||
SC_ScriptError ("Sorry, you can only use class<actor>");
|
||||
}
|
||||
SC_MustGetToken('>');
|
||||
type = 'm';
|
||||
break;
|
||||
case TK_Ellipsis:
|
||||
type = '+';
|
||||
SC_MustGetToken(')');
|
||||
SC_UnGet();
|
||||
break;
|
||||
default:
|
||||
SC_ScriptError ("Unknown variable type %s", SC_TokenName(sc_TokenType, sc_String).GetChars());
|
||||
break;
|
||||
}
|
||||
if (flags & EVALNOT)
|
||||
{
|
||||
type = 'y';
|
||||
}
|
||||
else if (flags & EVAL)
|
||||
{
|
||||
type = 'x';
|
||||
}
|
||||
if (!(flags & OPTIONAL))
|
||||
{
|
||||
type -= 'a' - 'A';
|
||||
break;
|
||||
}
|
||||
#undef OPTIONAL
|
||||
#undef EVAL
|
||||
#undef EVALNOT
|
||||
args += type;
|
||||
SC_MustGetAnyToken();
|
||||
if (sc_TokenType != ',' && sc_TokenType != ')')
|
||||
{
|
||||
SC_ScriptError ("Expected ',' or ')' but got %s instead", SC_TokenName(sc_TokenType, sc_String).GetChars());
|
||||
}
|
||||
}
|
||||
PSymbolActionFunction *sym = new PSymbolActionFunction;
|
||||
sym->SymbolName = funcname;
|
||||
sym->SymbolType = SYM_ActionFunction;
|
||||
sym->Arguments = args;
|
||||
sym->Function = NULL;
|
||||
if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
SC_ScriptError ("'%s' is already defined in class '%s'.",
|
||||
funcname.GetChars(), bag.Info->Class->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -2699,7 +2831,7 @@ static void ActorDamage (AActor *defaults, Baggage &bag)
|
|||
|
||||
if (SC_CheckString ("("))
|
||||
{
|
||||
defaults->Damage = 0x40000000 | ParseExpression (false);
|
||||
defaults->Damage = 0x40000000 | ParseExpression (false, bag.Info->Class);
|
||||
SC_MustGetStringName(")");
|
||||
}
|
||||
else
|
||||
|
@ -3997,7 +4129,7 @@ static void PlayerScoreIcon (APlayerPawn *defaults, Baggage &bag)
|
|||
static void PlayerCrouchSprite (APlayerPawn *defaults, Baggage &bag)
|
||||
{
|
||||
SC_MustGetString ();
|
||||
for (int i = 0; i < sc_StringLen; i++) sc_String[i] = toupper (sc_String[i]);
|
||||
for (unsigned int i = 0; i < sc_StringLen; i++) sc_String[i] = toupper (sc_String[i]);
|
||||
defaults->crouchsprite = GetSpriteIndex (sc_String);
|
||||
}
|
||||
|
||||
|
@ -4115,6 +4247,7 @@ static const ActorProps props[] =
|
|||
{
|
||||
{ "+", ActorFlagSetOrReset, RUNTIME_CLASS(AActor) },
|
||||
{ "-", ActorFlagSetOrReset, RUNTIME_CLASS(AActor) },
|
||||
{ "action", ActorActionDef, RUNTIME_CLASS(AActor) },
|
||||
{ "activesound", ActorActiveSound, RUNTIME_CLASS(AActor) },
|
||||
{ "alpha", ActorAlpha, RUNTIME_CLASS(AActor) },
|
||||
{ "ammo.backpackamount", (apf)AmmoBackpackAmount, RUNTIME_CLASS(AAmmo) },
|
||||
|
@ -4131,6 +4264,7 @@ static const ActorProps props[] =
|
|||
{ "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) },
|
||||
{ "cameraheight", ActorCameraheight, RUNTIME_CLASS(AActor) },
|
||||
{ "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) },
|
||||
{ "const", ActorConstDef, RUNTIME_CLASS(AActor) },
|
||||
{ "conversationid", ActorConversationID, RUNTIME_CLASS(AActor) },
|
||||
{ "crash", ActorCrashState, RUNTIME_CLASS(AActor) },
|
||||
{ "crush", ActorCrushState, RUNTIME_CLASS(AActor) },
|
||||
|
|
|
@ -26,11 +26,11 @@ extern TArray<int> StateParameters;
|
|||
extern TArray<int> JumpParameters;
|
||||
|
||||
|
||||
int ParseExpression (bool _not);
|
||||
int ParseExpression (bool _not, PClass *cls);
|
||||
|
||||
int EvalExpressionI (int id, AActor *self);
|
||||
float EvalExpressionF (int id, AActor *self);
|
||||
bool EvalExpressionN (int id, AActor *self);
|
||||
int EvalExpressionI (int id, AActor *self, const PClass *cls=NULL);
|
||||
float EvalExpressionF (int id, AActor *self, const PClass *cls=NULL);
|
||||
bool EvalExpressionN (int id, AActor *self, const PClass *cls=NULL);
|
||||
|
||||
void ClearStateLabels();
|
||||
void AddState (const char * statename, FState * state);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="updaterevision"
|
||||
ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}"
|
||||
RootNamespace="updaterevision"
|
||||
|
@ -96,6 +96,82 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
|
@ -173,82 +249,6 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
|
Loading…
Reference in a new issue