diff --git a/common.h b/common.h index bc41786..786d3f7 100644 --- a/common.h +++ b/common.h @@ -68,6 +68,7 @@ enum STRLIST_PICS, STRLIST_FUNCTIONS, STRLIST_MAPVARS, + STRLIST_NAMEDSCRIPTS, NUM_STRLISTS }; diff --git a/error.c b/error.c index 6d90053..7178403 100644 --- a/error.c +++ b/error.c @@ -128,7 +128,7 @@ static struct { ERR_OUT_OF_MEMORY, "Out of memory." }, { ERR_TOO_MANY_STRINGS, "Too many strings. Current max is %d" }, { ERR_UNKNOWN_PRTYPE, "Unknown cast type in print statement." }, - { ERR_SCRIPT_OUT_OF_RANGE, "Script number must be between 1 and 999." }, + { ERR_SCRIPT_OUT_OF_RANGE, "Script number must be between 1 and 32767." }, { ERR_MISSING_PARAM, "Missing required argument." }, { ERR_SCRIPT_ALREADY_DEFINED, "Script already has a body." }, { ERR_FUNCTION_ALREADY_DEFINED, "Function already has a body." }, diff --git a/parse.c b/parse.c index 463d324..491f41e 100644 --- a/parse.c +++ b/parse.c @@ -523,7 +523,7 @@ static void OuterScript(void) { int scriptNumber; symbolNode_t *sym; - int scriptType; + int scriptType, scriptFlags; MS_Message(MSG_DEBUG, "---- OuterScript ----\n"); BreakIndex = 0; @@ -558,10 +558,15 @@ static void OuterScript(void) TK_NextToken(); scriptNumber = 0; } + else if(tk_Token == TK_STRING) + { // Named scripts start counting at -1 and go down from there. + scriptNumber = -1 - STR_FindInList(STRLIST_NAMEDSCRIPTS, tk_String); + TK_NextToken(); + } else { scriptNumber = EvalConstExpression(); - if(scriptNumber < 1 || scriptNumber > 999) + if(scriptNumber < 1 || scriptNumber > 32767) { TK_Undo(); ERR_Error(ERR_SCRIPT_OUT_OF_RANGE, YES, NULL); @@ -570,8 +575,18 @@ static void OuterScript(void) return; } } - MS_Message(MSG_DEBUG, "Script number: %d\n", scriptNumber); + if (scriptNumber >= 0) + { + MS_Message(MSG_DEBUG, "Script number: %d\n", scriptNumber); + } + else + { + MS_Message(MSG_DEBUG, "Script name: %s (%d)\n", + STR_GetString(STRLIST_NAMEDSCRIPTS, -scriptNumber - 1), + scriptNumber); + } scriptType = 0; + scriptFlags = 0; if(tk_Token == TK_LPAREN) { if(TK_NextToken() == TK_VOID) @@ -695,18 +710,18 @@ static void OuterScript(void) TK_NextToken(); if(tk_Token == TK_NET) { - scriptNumber += NET_SCRIPT_FLAG; + scriptFlags |= NET_SCRIPT_FLAG; TK_NextToken(); } // [BB] If NET and CLIENTSIDE are specified, this construction can only parse // "NET CLIENTSIDE" but not "CLIENTSIDE NET". if(tk_Token == TK_CLIENTSIDE) { - scriptNumber += CLIENTSIDE_SCRIPT_FLAG; + scriptFlags |= CLIENTSIDE_SCRIPT_FLAG; TK_NextToken(); } CountScript(scriptType); - PC_AddScript(scriptNumber + scriptType, ScriptVarCount); + PC_AddScript(scriptNumber, scriptType, scriptFlags, ScriptVarCount); pc_LastAppendedCommand = PCD_NOP; if(ProcessStatement(STMT_SCRIPT) == NO) { @@ -716,7 +731,7 @@ static void OuterScript(void) { PC_AppendCmd(PCD_TERMINATE); } - PC_SetScriptVarCount(scriptNumber + scriptType, ScriptVarCount); + PC_SetScriptVarCount(scriptNumber, scriptType, ScriptVarCount); pa_ScriptCount++; } diff --git a/pcode.c b/pcode.c index 5f37e8b..10882eb 100644 --- a/pcode.c +++ b/pcode.c @@ -24,7 +24,7 @@ typedef struct scriptInfo_s { - U_WORD number; + S_WORD number; U_BYTE type; U_BYTE argCount; U_WORD varCount; @@ -99,7 +99,7 @@ static int ObjectFlags; static int PushByteAddr; static char Imports[MAX_IMPORTS][9]; static int NumImports; -static boolean HaveScriptFlags; +static boolean HaveExtendedScripts; static char *PCDNames[PCODE_COMMAND_COUNT] = { @@ -510,7 +510,7 @@ void PC_CloseObject(void) } if(!pc_NoShrink || (NumLanguages > 1) || (NumStringLists > 0) || (pc_FunctionCount > 0) || MapVariablesInit || NumArrays != 0 || - pc_EncryptStrings || NumImports != 0 || HaveScriptFlags) + pc_EncryptStrings || NumImports != 0 || HaveExtendedScripts) { CloseNew(); } @@ -650,6 +650,9 @@ static void CloseNew(void) } } + // Write the string table for named scripts. + STR_WriteListChunk(STRLIST_NAMEDSCRIPTS, MAKE4CC('S','N','A','M'), NO); + if(pc_FunctionCount > 0) { PC_Append("FUNC", 4); @@ -936,7 +939,8 @@ static void CreateDummyScripts(void) pc_DummyAddress = pc_Address; for(i = 0; i < pc_ScriptCount; ++i) { - if(!ScriptInfo[i].imported) + // Only create dummies for scripts WadAuthor could care about. + if(!ScriptInfo[i].imported && ScriptInfo[i].number >= 0 && ScriptInfo[i].number <= 255) { PC_AppendCmd(PCD_TERMINATE); if(!pc_NoShrink) @@ -957,26 +961,27 @@ static void CreateDummyScripts(void) static void RecordDummyScripts(void) { - int i, count; + int i, j, count; for(i = count = 0; i < pc_ScriptCount; ++i) { - if(!ScriptInfo[i].imported) + if(!ScriptInfo[i].imported && ScriptInfo[i].number >= 0 && ScriptInfo[i].number <= 255) { ++count; } } PC_AppendInt((U_INT)count); - for(i = 0; i < pc_ScriptCount; ++i) + for(i = j = 0; i < pc_ScriptCount; ++i) { scriptInfo_t *info = &ScriptInfo[i]; - if(!info->imported) + if(!info->imported && info->number >= 0 && ScriptInfo[i].number <= 255) { MS_Message(MSG_DEBUG, "Dummy script %d, address = %d, arg count = %d\n", info->number, info->address, info->argCount); PC_AppendInt((U_INT)info->number); - PC_AppendInt((U_INT)pc_DummyAddress + i*4); + PC_AppendInt((U_INT)pc_DummyAddress + j*4); PC_AppendInt((U_INT)info->argCount); + j++; } } } @@ -1348,21 +1353,14 @@ void PC_NameMapVariable(int index, symbolNode_t *sym) // //========================================================================== -void PC_AddScript(int inNumber, int argCount) +void PC_AddScript(int number, int type, int flags, int argCount) { scriptInfo_t *script; int i; - U_BYTE type; - U_WORD flags; - U_WORD number; - type = (inNumber & 65535) / 1000; - number = (inNumber & 65535) % 1000; - flags = (inNumber >> 16) & 65535; - - if (flags != 0) + if (flags != 0 || number < 0 || number >= 1000) { - HaveScriptFlags = YES; + HaveExtendedScripts = YES; } for (i = 0; i < pc_ScriptCount; i++) @@ -1399,18 +1397,13 @@ void PC_AddScript(int inNumber, int argCount) // //========================================================================== -void PC_SetScriptVarCount(int inNumber, int varCount) +void PC_SetScriptVarCount(int number, int type, int varCount) { int i; - U_BYTE type; - U_WORD number; - - type = (inNumber & 65535) / 1000; - number = (inNumber & 65535) % 1000; for(i = 0; i < pc_ScriptCount; i++) { - if(ScriptInfo[i].number == number) + if(ScriptInfo[i].number == number && ScriptInfo[i].type == type) { ScriptInfo[i].varCount = varCount; break; diff --git a/pcode.h b/pcode.h index 82df1c6..2a28de4 100644 --- a/pcode.h +++ b/pcode.h @@ -15,28 +15,28 @@ // MACROS ------------------------------------------------------------------ -// Values added to script number to indicate its type +// Values to indicate a script's type enum { - OPEN_SCRIPTS_BASE = 1000, - RESPAWN_SCRIPTS_BASE = 2000, // [BC] - DEATH_SCRIPTS_BASE = 3000, // [BC] - ENTER_SCRIPTS_BASE = 4000, // [BC] - PICKUP_SCRIPTS_BASE = 5000, // [BC] - BLUE_RETURN_SCRIPTS_BASE = 6000, // [BC] - RED_RETURN_SCRIPTS_BASE = 7000, // [BC] - WHITE_RETURN_SCRIPTS_BASE = 8000, // [BC] - LIGHTNING_SCRIPTS_BASE = 12000, - UNLOADING_SCRIPTS_BASE = 13000, - DISCONNECT_SCRIPTS_BASE = 14000, - RETURN_SCRIPTS_BASE = 15000, + OPEN_SCRIPTS_BASE = 1, + RESPAWN_SCRIPTS_BASE = 2, // [BC] + DEATH_SCRIPTS_BASE = 3, // [BC] + ENTER_SCRIPTS_BASE = 4, // [BC] + PICKUP_SCRIPTS_BASE = 5, // [BC] + BLUE_RETURN_SCRIPTS_BASE = 6, // [BC] + RED_RETURN_SCRIPTS_BASE = 7, // [BC] + WHITE_RETURN_SCRIPTS_BASE = 8, // [BC] + LIGHTNING_SCRIPTS_BASE = 12, + UNLOADING_SCRIPTS_BASE = 13, + DISCONNECT_SCRIPTS_BASE = 14, + RETURN_SCRIPTS_BASE = 15, }; -// Values added to script number to indicate flags (requires new-style .o) +// Values to indicate script flags (requires new-style .o) enum { - NET_SCRIPT_FLAG = 0x00010000, - CLIENTSIDE_SCRIPT_FLAG = 0x00020000, // [BB] + NET_SCRIPT_FLAG = 0x0001, + CLIENTSIDE_SCRIPT_FLAG = 0x0002, // [BB] }; // Or'ed with variable index when passing variables of type "out" @@ -447,8 +447,8 @@ void PC_Skip(size_t size); //void PC_SkipByte(void); //void PC_SkipWord(void); void PC_SkipInt(void); -void PC_AddScript(int number, int argCount); -void PC_SetScriptVarCount(int number, int varCount); +void PC_AddScript(int number, int type, int flags, int argCount); +void PC_SetScriptVarCount(int number, int type, int varCount); void PC_AddFunction(struct symbolNode_s *sym); void PC_PutMapVariable(int index, int value); void PC_NameMapVariable(int index, struct symbolNode_s *sym); diff --git a/zspecial.acs b/zspecial.acs index 615245d..e3f6a9b 100644 --- a/zspecial.acs +++ b/zspecial.acs @@ -280,6 +280,13 @@ special -36:SpawnForced(6), -37:AnnouncerSound(2), -38:SetPointer(2,4), + -39:ACS_NamedExecute(2,5), + -40:ACS_NamedSuspend(2), + -41:ACS_NamedTerminate(2), + -42:ACS_NamedLockedExecute(5), + -43:ACS_NamedLockedExecuteDoor(5), + -44:ACS_NamedExecuteWithResult(1,4), + -45:ACS_NamedExecuteAlways(2,5), -1000:__EndOfList__(10);