From e23580c1dea828af401ade3497f22b7359bef72d Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 26 Jul 2023 19:40:01 +0300 Subject: [PATCH] engine: remove czeror sequence parser This file initially came from HLND, a Chinese GoldSrc recreation. It turned out to be suspiciously close to the original version, down to the comments and code style. We don't work with leaked sources here, so remove it. A proper parser should be reimplemented from ground-up, when we will start working on CZDS support. --- engine/client/cl_main.c | 5 - engine/client/s_vox.c | 20 +- engine/common/common.c | 5 +- engine/common/sequence.c | 1782 -------------------------------------- engine/sequence.h | 203 ----- engine/server/sv_init.c | 3 - 6 files changed, 5 insertions(+), 2013 deletions(-) delete mode 100644 engine/common/sequence.c delete mode 100644 engine/sequence.h diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 37fa2f76..792a46d6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -23,7 +23,6 @@ GNU General Public License for more details. #include "library.h" #include "vid_common.h" #include "pm_local.h" -#include "sequence.h" #define MAX_TOTAL_CMDS 32 #define MAX_CMD_BUFFER 8000 @@ -233,9 +232,6 @@ void CL_SignonReply( void ) if( cl.proxy_redirect && !cls.spectator ) CL_Disconnect(); cl.proxy_redirect = false; - - if( cls.demoplayback ) - Sequence_OnLevelLoad( clgame.mapname ); break; } } @@ -3138,7 +3134,6 @@ void CL_Init( void ) VID_Init(); // init video S_Init(); // init sound Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice - Sequence_Init(); // unreliable buffer. unsed for unreliable commands and voice stream MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); diff --git a/engine/client/s_vox.c b/engine/client/s_vox.c index adf1642d..8ee8b81f 100644 --- a/engine/client/s_vox.c +++ b/engine/client/s_vox.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #include "common.h" #include "sound.h" #include "const.h" -#include "sequence.h" #include static int cszrawsentences = 0; @@ -165,24 +164,11 @@ static const char *VOX_LookupString( const char *pszin ) int i = -1, len; const char *c; - // check if we are a CSCZ or immediate sentence + // check if we are an immediate sentence if( *pszin == '#' ) { - // Q_atoi is too smart and allows negative values - // so check with Q_isdigit beforehand - if( Q_isdigit( pszin + 1 )) - { - sentenceEntry_s *sentenceEntry; - i = Q_atoi( pszin + 1 ); - if(( sentenceEntry = Sequence_GetSentenceByIndex( i ))) - return sentenceEntry->data; - return NULL; - } - else - { - // immediate sentence, probably coming from "speak" command - return pszin + 1; - } + // immediate sentence, probably coming from "speak" command + return pszin + 1; } // check if we received an index diff --git a/engine/common/common.c b/engine/common/common.c index 7ff5c322..892e8ad1 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -22,7 +22,6 @@ GNU General Public License for more details. #include "const.h" #include "client.h" #include "library.h" -#include "sequence.h" static const char *file_exts[] = { @@ -1047,7 +1046,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName ) { Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName ); - return Sequence_Get( fileName, entryName ); + return NULL; } /* @@ -1061,7 +1060,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod { Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod ); - return Sequence_PickSentence( groupName, pickMethod, picked ); + return NULL; } diff --git a/engine/common/sequence.c b/engine/common/sequence.c deleted file mode 100644 index 187ced7b..00000000 --- a/engine/common/sequence.c +++ /dev/null @@ -1,1782 +0,0 @@ -/* -sequence.c - scripted sequences for CS:CZDS -Copyright (C) 2017 a1batross - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#include -#include "common.h" -#include "eiface.h" -#include "sequence.h" - -sequenceCommandLine_s g_fileScopeDefaults; -sequenceCommandLine_s g_blockScopeDefaults; -sequenceEntry_s *g_sequenceList = NULL; -sentenceGroupEntry_s *g_sentenceGroupList = NULL; -qboolean g_sequenceParseFileIsGlobal; -unsigned int g_nonGlobalSentences = 0; -char g_sequenceParseFileName[MAX_STRING]; -int g_lineNum = 1; -char *g_scan = NULL; -char *g_lineScan = NULL; - -const sequenceCommandMapping_s g_sequenceCommandMappingTable[] = -{ - {SEQUENCE_COMMAND_PAUSE, "pause", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_TEXT, "text", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SOUND, "sound", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_FIRETARGETS, "firetargets", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_KILLTARGETS, "killtargets", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_GOSUB, "gosub", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SENTENCE, "sentence", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_REPEAT, "repeat", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SETDEFAULTS, "setdefaults", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_MODIFIER, "modifier", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_POSTMODIFIER, "postmodifier", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_NOOP, "noop", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_MODIFIER_EFFECT, "effect", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_POSITION, "position", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_COLOR, "color", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_COLOR2, "color2", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FADEIN, "fadein", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FADEOUT, "fadeout", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_HOLDTIME, "holdtime", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FXTIME, "fxtime", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_SPEAKER, "speaker", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_LISTENER, "listener", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_TEXTCHANNEL, "channel", SEQUENCE_TYPE_MODIFIER} -}; - -/* -============= -Sequence_GetCommandEnumForName - -============= -*/ -static sequenceCommandEnum_e Sequence_GetCommandEnumForName( const char *commandName, sequenceCommandType_e type ) -{ - int i; - - for( i = 0; i < ARRAYSIZE( g_sequenceCommandMappingTable ); i++ ) - { - const sequenceCommandMapping_s *mapping = g_sequenceCommandMappingTable + i; - - if( mapping->commandType == type && !Q_stricmp( mapping->commandName, commandName ) ) - return mapping->commandEnum; - } - return SEQUENCE_COMMAND_ERROR; -} - -/* -============= -Sequence_ResetDefaults - -============= -*/ -static void Sequence_ResetDefaults( sequenceCommandLine_s *destination, sequenceCommandLine_s *source ) -{ - if( !source ) - { - static client_textmessage_t defaultClientMessage = - { - 0, // effect - 255, 255, 255, 255, // rgba1 - 255, 255, 255, 255, // rgba2 - 0.5, 0.5, // xy - 0.2, 0.2, // fade-in/out - 1.6, // holdtime - 1.0, // fxtime - NULL, NULL // pName, pMessage - }; - - destination->clientMessage = defaultClientMessage; - destination->textChannel = 0; - destination->delay = 0; - destination->repeatCount = 0; - destination->nextCommandLine = NULL; - destination->soundFileName = NULL; - destination->speakerName = NULL; - destination->listenerName = NULL; - return; - } - - destination->clientMessage = source->clientMessage; - destination->clientMessage.pName = NULL; - destination->clientMessage.pMessage = NULL; - destination->textChannel = source->textChannel; - destination->delay = source->delay; - destination->repeatCount = source->repeatCount; - destination->nextCommandLine = NULL; - destination->soundFileName = NULL; - - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); -} - -/* -============= -Sequence_WriteDefaults - -============= -*/ -static void Sequence_WriteDefaults( sequenceCommandLine_s *source, sequenceCommandLine_s *destination ) -{ - if( !destination ) - Con_Reportf( S_ERROR "Attempt to bake defaults into a non-existant command." ); - - if( !source ) - Con_Reportf( S_ERROR "Attempt to bake defaults from a non-existant command." ); - - if( source->modifierBitField & SEQUENCE_MODIFIER_EFFECT_BIT ) - { - destination->clientMessage.effect = source->clientMessage.effect; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_POSITION_BIT ) - { - destination->clientMessage.x = source->clientMessage.x; - destination->clientMessage.y = source->clientMessage.y; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_COLOR_BIT ) - { - destination->clientMessage.r1 = source->clientMessage.r1; - destination->clientMessage.g1 = source->clientMessage.g1; - destination->clientMessage.b1 = source->clientMessage.b1; - destination->clientMessage.a1 = source->clientMessage.a1; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_COLOR2_BIT ) - { - destination->clientMessage.r2 = source->clientMessage.r2; - destination->clientMessage.g2 = source->clientMessage.g2; - destination->clientMessage.b2 = source->clientMessage.b2; - destination->clientMessage.a2 = source->clientMessage.a2; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FADEIN_BIT ) - { - destination->clientMessage.fadein = source->clientMessage.fadein; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FADEOUT_BIT ) - { - destination->clientMessage.fadeout = source->clientMessage.fadeout; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_HOLDTIME_BIT ) - { - destination->clientMessage.holdtime = source->clientMessage.holdtime; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FXTIME_BIT ) - { - destination->clientMessage.fxtime = source->clientMessage.fxtime; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_SPEAKER_BIT ) - { - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_LISTENER_BIT ) - { - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_TEXTCHANNEL_BIT ) - { - destination->textChannel = source->textChannel; - } -} - -/* -============= -Sequence_BakeDefaults - -============= -*/ -static void Sequence_BakeDefaults( sequenceCommandLine_s *destination, sequenceCommandLine_s *source ) -{ - char *saveName, *saveMessage; - - if( !destination ) - Con_Reportf( S_ERROR "Attempt to bake defaults into a non-existant command." ); - - if( !source ) - Con_Reportf( S_ERROR "Attempt to bake defaults from a non-existant command." ); - - saveName= destination->clientMessage.pName; - saveMessage = destination->clientMessage.pMessage; - - destination->clientMessage = source->clientMessage; - - destination->clientMessage.pName = saveName; - destination->clientMessage.pMessage = saveMessage; - - destination->textChannel = source->textChannel; - - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); -} - -/* -============= -Sequence_SkipWhitespace - -============= -*/ -static qboolean Sequence_SkipWhitespace( void ) -{ - qboolean newLine = false; - - for( ; isspace( *g_scan ); g_scan++ ) - { - if( *g_scan == '\n' ) - { - g_lineScan = g_scan + 1; - g_lineNum++; - - newLine = true; - } - } - - return newLine; -} - -/* -============= -Sequence_IsNameValueChar - -============= -*/ -static qboolean Sequence_IsNameValueChar( char ch ) -{ - if( isalnum( ch ) ) - return true; - - switch( ch ) - { - case '.': - case '-': - case '_': - case '/': - case '\\': - return true; - } - - return false; -} - -/* -============= -Sequence_IsSymbol - -============= -*/ -static qboolean Sequence_IsSymbol( char ch ) -{ - switch( ch ) - { - case '"': - case '#': - case '$': - case '%': - case ',': - case '=': - case '@': - case '{': - case '}': - return true; - } - - return false; -} - -/* -============= -Sequence_GetNameValueString - -============= -*/ -static size_t Sequence_GetNameValueString( char *token, size_t len ) -{ - char *p; - - Sequence_SkipWhitespace( ); - - if( !Sequence_IsNameValueChar( *g_scan ) ) - { - if( *g_scan == '#' || *g_scan == '$' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: cannot have more than one '%c' per line; '%c' must be at the beginning of the line ONLY\n", g_lineNum, g_sequenceParseFileName, *g_scan, *g_scan ); - else - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected name/value, found illegal character '%c'\n", g_lineNum, g_sequenceParseFileName, *g_scan ); - } - - for( p = token; Sequence_IsNameValueChar( *g_scan ) && len; p++, g_scan++, len-- ) - { - *p = *g_scan; - } - - *p = 0; - - return p - token; -} - -/* -============= -Sequence_GetSymbol - -============= -*/ -static char Sequence_GetSymbol( void ) -{ - char ch; - - Sequence_SkipWhitespace( ); - - ch = *g_scan; - - if( ch ) - g_scan++; - - return ch; -} - -/* -============= -Sequence_ValidateNameValueString - -============= -*/ -static void Sequence_ValidateNameValueString( char *token ) -{ - char *scan; - - for( scan = token; *scan; scan++ ) - { - if( !Sequence_IsNameValueChar( *scan ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: name/value string \"%s\" had illegal character '%c'\n", g_lineNum, g_sequenceParseFileName, token, *scan ); - } -} - -/* -============= -Sequence_GetToken - -============= -*/ -static size_t Sequence_GetToken( char *token, size_t size ) -{ - Sequence_SkipWhitespace( ); - - if( Sequence_IsNameValueChar( *g_scan ) ) - { - return Sequence_GetNameValueString( token, size ); - } - - if( !Sequence_IsSymbol( *g_scan ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected token, found '%c' instead\n", g_lineNum, g_sequenceParseFileName, *g_scan ); - - token[0] = *g_scan++; - token[1] = 0; - g_scan++; - - return 1; // only one symbol has copied to token -} - -/* -============= -Sequence_GetLine - -============= -*/ -static size_t Sequence_GetLine( char *line, int lineMaxLen ) -{ - int lineLen; - char *read; - char *write = line; - - Sequence_SkipWhitespace( ); - - read = Q_strchr( g_scan, '\n' ); - - if( !read ) - Con_Reportf( S_ERROR "Syntax Error on line %d of %s.seq: expected sentence definition or '}', found End-Of-File!\n", g_lineNum, g_sequenceParseFileName ); - - lineLen = read - g_scan; - - if( lineLen >= lineMaxLen ) - Con_Reportf( S_ERROR "Syntax Error on line %d of %s.seq: line was too long (was %d chars; max is %d chars)\n", g_lineNum, g_sequenceParseFileName, lineLen, lineMaxLen - 1 ); - - Q_strncpy( write, g_scan, lineLen ); - write[lineLen] = 0; - g_scan = read; - - return lineLen; -} - -/* -============= -Sequence_StripComments - -============= -*/ -static void Sequence_StripComments( char *buffer, int *pBufSize ) -{ - char *eof = buffer + *pBufSize; - char *read = buffer; - char *write = buffer; - - for( ; read < eof; ) - { - if( !*read ) - break; - - if( *read == '/' ) - { - // skip one line comments // - if( read[1] == '/' ) - { - read += 2; - - while( *read ) - { - if( *read == '\n' ) - break; - - if( *read == '\r' ) - break; - - read++; - } - - continue; - } - - // skip multiline /* */ - if( read[1] == '*' ) - { - read += 2; - - while( *read && read[1] ) - { - if( *read == '*' && read[1] == '/' ) - { - read += 2; - break; - } - - if( *read == '\n' || *read == '\r' ) - *write++ = *read; - - read++; - } - - continue; - } - } - - *write++ = *read++; - } - - *write = 0; -} - -/* -============= -Sequence_ReadInt - -============= -*/ -static int Sequence_ReadInt( void ) -{ - char str[MAX_STRING]; - - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( str, MAX_STRING ); - - return Q_atoi( str ); -} - -/* -============= -Sequence_ReadFloat - -============= -*/ -static float Sequence_ReadFloat( void ) -{ - char str[MAX_STRING]; - - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( str, MAX_STRING ); - - return Q_atof( str ); -} - -/* -============= -Sequence_ReadFloat - -============= -*/ -static void Sequence_ReadString( char **dest, char *string, size_t len ) -{ - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( string, len ); - - if( dest ) *dest = copystring( string ); -} - -/* -============= -Sequence_ReadQuotedString - -============= -*/ -static void Sequence_ReadQuotedString( char **dest, char *str, size_t len ) -{ - char *write, ch; - - Sequence_SkipWhitespace( ); - - ch = Sequence_GetSymbol( ); - if( ch != '\"' ) - Con_Reportf( S_ERROR "Parsing error on or before line %d of %s.seq: expected quote (\"), found '%c' instead\n", g_lineNum, g_sequenceParseFileName, ch ); - - for( write = str; *g_scan && len; write++, g_scan++, len-- ) - { - if( *g_scan == '\"' ) - break; - - if( *g_scan == '\n' ) - g_lineNum++; - - *write = *g_scan; - } - - *write = 0; - g_scan++; - - if( dest ) *dest = copystring( str ); -} - -/* -============= -Sequence_ConfirmCarriageReturnOrSymbol - -============= -*/ -static qboolean Sequence_ConfirmCarriageReturnOrSymbol( char symbol ) -{ - if( Sequence_SkipWhitespace( ) ) - return true; - return *g_scan == symbol; -} - - -/* -============= -Sequence_IsCommandAModifier - -============= -*/ -static qboolean Sequence_IsCommandAModifier( sequenceCommandEnum_e commandEnum ) -{ - int i; - - for( i = 0; i < ARRAYSIZE( g_sequenceCommandMappingTable ); i++ ) - { - if( g_sequenceCommandMappingTable[i].commandEnum == commandEnum ) - return ( g_sequenceCommandMappingTable[i].commandType == SEQUENCE_TYPE_MODIFIER ); - } - - Con_Reportf( S_ERROR "Internal error caused by line %d of %s.seq: unknown command enum = %d\n", g_lineNum, g_sequenceParseFileName, commandEnum ); - return false; -} - -/* -============= -Sequence_ReadCommandData - -============= -*/ -static void Sequence_ReadCommandData( sequenceCommandEnum_e commandEnum, sequenceCommandLine_s *defaults ) -{ - char temp[1024]; - - if( commandEnum >= SEQUENCE_MODIFIER_EFFECT && commandEnum <= SEQUENCE_MODIFIER_TEXTCHANNEL ) - defaults->modifierBitField |= BIT( SEQUENCE_MODIFIER_EFFECT - SEQUENCE_COMMAND_NOOP ); - - switch( commandEnum ) - { - case SEQUENCE_COMMAND_PAUSE: - defaults->delay = Sequence_ReadFloat( ); - break; - - case SEQUENCE_COMMAND_FIRETARGETS: - Sequence_ReadQuotedString( &defaults->fireTargetNames, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_KILLTARGETS: - Sequence_ReadQuotedString( &defaults->killTargetNames, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_TEXT: - Sequence_ReadQuotedString( &defaults->clientMessage.pMessage, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_SOUND: - Sequence_ReadString( &defaults->soundFileName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_GOSUB: - Sequence_ReadString( &defaults->clientMessage.pName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_SENTENCE: - Sequence_ReadString( &defaults->sentenceName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_REPEAT: - defaults->repeatCount = Sequence_ReadInt( ); - break; - - case SEQUENCE_MODIFIER_EFFECT: - defaults->clientMessage.effect = Sequence_ReadInt( ); - break; - - case SEQUENCE_MODIFIER_POSITION: - defaults->clientMessage.x = Sequence_ReadFloat( ); - defaults->clientMessage.y = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_COLOR: - defaults->clientMessage.r1 = Sequence_ReadInt( ); - defaults->clientMessage.g1 = Sequence_ReadInt( ); - defaults->clientMessage.b1 = Sequence_ReadInt( ); - defaults->clientMessage.a1 = 255; - break; - - case SEQUENCE_MODIFIER_COLOR2: - defaults->clientMessage.r2 = Sequence_ReadInt( ); - defaults->clientMessage.g2 = Sequence_ReadInt( ); - defaults->clientMessage.b2 = Sequence_ReadInt( ); - defaults->clientMessage.a2 = 255; - break; - - case SEQUENCE_MODIFIER_FADEIN: - defaults->clientMessage.fadein = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_FADEOUT: - defaults->clientMessage.fadeout = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_HOLDTIME: - defaults->clientMessage.holdtime = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_FXTIME: - defaults->clientMessage.fxtime = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_SPEAKER: - Sequence_ReadString( &defaults->speakerName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_MODIFIER_LISTENER: - Sequence_ReadString( &defaults->listenerName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_MODIFIER_TEXTCHANNEL: - defaults->textChannel = Sequence_ReadInt( ); - break; - - default: - Con_Reportf( S_ERROR "Internal error caused by line %d of %s.seq: unknown command enum = %d\n", g_lineNum, g_sequenceParseFileName, commandEnum ); - } -} - -/* -============= -Sequence_ParseModifier - -============= -*/ -static char Sequence_ParseModifier( sequenceCommandLine_s *defaults ) -{ - char modifierName[MAX_STRING]; - char delimiter; - sequenceCommandEnum_e modifierEnum; - - Sequence_GetNameValueString( modifierName, MAX_STRING ); - modifierEnum = Sequence_GetCommandEnumForName( modifierName, SEQUENCE_TYPE_MODIFIER ); - - if( modifierEnum == SEQUENCE_COMMAND_ERROR ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: unknown modifier \"%s\"\n", g_lineNum, g_sequenceParseFileName, modifierName ); - - if( !Sequence_IsCommandAModifier( modifierEnum ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: \"%s\" is a #command, not a $modifier\n", g_lineNum, g_sequenceParseFileName, modifierName ); - - delimiter = Sequence_GetSymbol( ); - - if( delimiter != '=' ) - Con_Reportf( S_ERROR "Parsing error on or after line %d of %s.seq: after modifier \"%s\", expected '=', found '%c'\n", g_lineNum, g_sequenceParseFileName, modifierName, delimiter ); - - Sequence_ReadCommandData( modifierEnum, defaults ); - - if( !Sequence_ConfirmCarriageReturnOrSymbol( ',' ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: after value(s) for modifier \"%s\", expected ',' or End-Of-Line; found '%c'\n", g_lineNum, g_sequenceParseFileName, modifierName, *g_scan ); - - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_AddCommandLineToEntry - -============= -*/ -static void Sequence_AddCommandLineToEntry( sequenceCommandLine_s *commandLine, sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *scan; - - if( entry->firstCommand ) - { - for( scan = entry->firstCommand; scan->nextCommandLine; scan = scan->nextCommandLine ); - scan->nextCommandLine = commandLine; - } - else entry->firstCommand = commandLine; - - commandLine->nextCommandLine = NULL; -} - -/* -============= -Sequence_ParseModifierLine - -============= -*/ -static char Sequence_ParseModifierLine( sequenceEntry_s *entry, sequenceCommandType_e modifierType ) -{ - sequenceCommandLine_s *newCommandLine; - char delimiter = ','; - - while( delimiter == ',' ) - { - switch( modifierType ) - { - case SEQUENCE_TYPE_COMMAND: - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - newCommandLine->commandType = SEQUENCE_COMMAND_MODIFIER; - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - delimiter = Sequence_ParseModifier( newCommandLine ); - break; - - case SEQUENCE_TYPE_MODIFIER: - delimiter = Sequence_ParseModifier( &g_fileScopeDefaults ); - break; - } - } - - return delimiter; -} - -/* -============= -Sequence_ParseCommand - -============= -*/ -static char Sequence_ParseCommand( sequenceCommandLine_s *newCommandLine ) -{ - char commandName[MAX_STRING], ch; - sequenceCommandEnum_e commandEnum; - sequenceCommandLine_s *modifierCommandLine; - - Sequence_GetNameValueString( commandName, MAX_STRING ); - commandEnum = Sequence_GetCommandEnumForName( commandName, SEQUENCE_TYPE_COMMAND ); - - if( commandEnum == SEQUENCE_COMMAND_ERROR ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: unknown command \"%s\"\n", g_lineNum, g_sequenceParseFileName, commandName ); - - if( Sequence_IsCommandAModifier( commandEnum ) ) - { - modifierCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( modifierCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - modifierCommandLine->commandType = SEQUENCE_COMMAND_POSTMODIFIER; - - for( ; newCommandLine->nextCommandLine; newCommandLine = newCommandLine->nextCommandLine ); - - newCommandLine->nextCommandLine = modifierCommandLine; - newCommandLine = modifierCommandLine; - } - - ch = Sequence_GetSymbol( ); - if( ch != '=' ) - Con_Reportf( S_ERROR "Parsing error on or before line %d of %s.seq: after command \"%s\", expected '=', found '%c'\n", - g_lineNum, g_sequenceParseFileName, commandName, ch ); - - Sequence_ReadCommandData( commandEnum, newCommandLine ); - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_ParseCommandLine - -============= -*/ -static char Sequence_ParseCommandLine( sequenceEntry_s *entry ) -{ - char symbol; - sequenceCommandLine_s *newCommandLine; - - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( newCommandLine, &g_blockScopeDefaults ); - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - - symbol = Sequence_ParseCommand( newCommandLine ); - - while( symbol == ',' ) - { - symbol = Sequence_ParseCommand( newCommandLine ); - } - - return symbol; -} - -/* -============= -Sequence_ParseMacro - -============= -*/ -static char Sequence_ParseMacro( sequenceEntry_s *entry ) -{ - char symbol; - sequenceCommandLine_s *newCommandLine; - - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( newCommandLine, &g_blockScopeDefaults ); - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - Sequence_ReadCommandData( SEQUENCE_COMMAND_GOSUB, newCommandLine ); - - symbol = Sequence_GetSymbol( ); - - while( symbol == ',' ) - { - symbol = Sequence_ParseCommand( newCommandLine ); - } - - return symbol; -} - -/* -============= -Sequence_ParseLine - -============= -*/ -static char Sequence_ParseLine( char start, sequenceEntry_s *entry ) -{ - char end = '\0'; - - switch( start ) - { - case '#': - end = Sequence_ParseCommandLine( entry ); - break; - - case '$': - end = Sequence_ParseModifierLine( entry, SEQUENCE_TYPE_MODIFIER ); - break; - - case '@': - end = Sequence_ParseMacro( entry ); - break; - - default: - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: line must begin with either '#' (command) or '$' (modifier); found '%c'\n", g_lineNum, g_sequenceParseFileName, start ); - } - - return end; -} - -/* -============= -Sequence_CalcEntryDuration - -============= -*/ -static float Sequence_CalcEntryDuration( sequenceEntry_s *entry ) -{ - float duration; - sequenceCommandLine_s *cmd; - - duration = 0; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - duration += cmd->delay; - - return duration; -} - -/* -============= -Sequence_DoesEntryContainInfiniteLoop - -============= -*/ -static qboolean Sequence_DoesEntryContainInfiniteLoop( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - if( cmd->repeatCount < 0 ) - return true; - } - - return false; -} - -/* -============= -Sequence_IsEntrySafe - -============= -*/ -static qboolean Sequence_IsEntrySafe( sequenceEntry_s *entry ) -{ - float duration; - sequenceCommandLine_s *cmd; - - duration = 0; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - duration += cmd->delay; - - if( cmd->repeatCount < 0 ) - { - if( duration <= 0 ) - return false; - } - } - - return true; -} - -/* -============= -Sequence_CreateDefaultsCommand - -============= -*/ -static void Sequence_CreateDefaultsCommand( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd; - - cmd = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( cmd, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( cmd, &g_fileScopeDefaults ); - cmd->commandType = SEQUENCE_COMMAND_SETDEFAULTS; - cmd->modifierBitField = SEQUENCE_MODIFIER_EFFECT_BIT | - SEQUENCE_MODIFIER_POSITION_BIT | - SEQUENCE_MODIFIER_COLOR_BIT | - SEQUENCE_MODIFIER_COLOR2_BIT | - SEQUENCE_MODIFIER_FADEIN_BIT | - SEQUENCE_MODIFIER_FADEOUT_BIT | - SEQUENCE_MODIFIER_HOLDTIME_BIT | - SEQUENCE_MODIFIER_FXTIME_BIT; - - Sequence_AddCommandLineToEntry( cmd, entry ); -} - - -/* -============= -Sequence_ParseEntry - -============= -*/ -static char Sequence_ParseEntry( void ) -{ - char symbol; - char token[MAX_STRING]; - sequenceEntry_s *entry; - - Sequence_GetNameValueString( token, MAX_STRING ); - symbol = Sequence_GetSymbol( ); - - if( symbol != '{' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected '{' to start a\n new entry block; found '%c' instead!", g_lineNum, g_sequenceParseFileName, symbol ); - - entry = Z_Malloc( sizeof( sequenceEntry_s ) ); - Sequence_ResetDefaults( &g_blockScopeDefaults, &g_fileScopeDefaults ); - entry->entryName = copystring( token ); - entry->fileName = copystring( g_sequenceParseFileName ); - entry->isGlobal = g_sequenceParseFileIsGlobal; - entry->firstCommand = NULL; - Sequence_CreateDefaultsCommand( entry ); - - symbol = Sequence_GetSymbol( ); - - while( symbol != '}' ) - { - symbol = Sequence_ParseLine( symbol, entry ); - } - - if( !Sequence_IsEntrySafe( entry ) ) - Con_Reportf( S_ERROR "Logic error in file %s.seq before line %d: execution of entry \"%%%s\" would cause an infinite loop!", g_sequenceParseFileName, g_lineNum, entry->entryName ); - - entry->nextEntry = g_sequenceList; - g_sequenceList = entry; - - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_FindSentenceGroup - -============= -*/ -static sentenceGroupEntry_s *Sequence_FindSentenceGroup( const char *groupName ) -{ - sentenceGroupEntry_s *groupEntry; - - for( groupEntry = g_sentenceGroupList; groupEntry; groupEntry = groupEntry->nextEntry ) - { - if( !Q_stricmp( groupEntry->groupName, groupName ) ) - return groupEntry; - } - - return NULL; -} - -/* -============= -Sequence_GetSentenceByIndex - -============= -*/ -sentenceEntry_s *Sequence_GetSentenceByIndex( unsigned int index ) -{ - sentenceEntry_s *sentenceEntry; - sentenceGroupEntry_s *groupEntry; - unsigned int sentenceCount=0; - - for( groupEntry = g_sentenceGroupList; groupEntry; groupEntry = groupEntry->nextEntry ) - { - sentenceCount += groupEntry->numSentences; - - if( index < sentenceCount ) - { - for( sentenceEntry = groupEntry->firstSentence; sentenceEntry; sentenceEntry = sentenceEntry->nextEntry ) - { - if( sentenceEntry->index == index ) - return sentenceEntry; - } - } - } - - return NULL; -} - - -/* -============= -Sequence_PickSentence - -============= -*/ -sentenceEntry_s *Sequence_PickSentence( const char *groupName, int pickMethod, int *picked ) -{ - sentenceEntry_s *sentenceEntry; - sentenceGroupEntry_s *groupEntry; - unsigned int pickedIdx; - unsigned int entryIdx; - - groupEntry = Sequence_FindSentenceGroup( groupName ); - - if( groupEntry ) - { - pickedIdx = COM_RandomLong( 0, groupEntry->numSentences - 1 ); - sentenceEntry = groupEntry->firstSentence; - - for( entryIdx = pickedIdx; entryIdx; entryIdx-- ) - sentenceEntry = sentenceEntry->nextEntry; - } - else - { - pickedIdx = 0; - sentenceEntry = NULL; - } - - if( picked ) - *picked = pickedIdx; - - return sentenceEntry; -} - -/* -============= -Sequence_AddSentenceGroup - -============= -*/ -static sentenceGroupEntry_s *Sequence_AddSentenceGroup( char *groupName ) -{ - sentenceGroupEntry_s *entry, *last; - - entry = Z_Malloc( sizeof( sentenceGroupEntry_s ) ); - entry->numSentences = 0; - entry->firstSentence = NULL; - entry->nextEntry = NULL; - entry->groupName = copystring( groupName ); - - if( g_sentenceGroupList ) - { - for( last = g_sentenceGroupList; last->nextEntry; last = last->nextEntry ); - last->nextEntry = entry; - } - else - { - g_sentenceGroupList = entry; - } - - return entry; -} - -/* -============= -Sequence_AddSentenceToGroup - -============= -*/ -static void Sequence_AddSentenceToGroup( char *groupName, char *data ) -{ - sentenceEntry_s *entry, *last; - sentenceGroupEntry_s *group; - - group = Sequence_FindSentenceGroup( groupName ); - - if( !group ) - { - group = Sequence_AddSentenceGroup( groupName ); - - if( !group ) - Con_Reportf( S_ERROR "Unable to allocate sentence group %s at line %d in file %s.seq", groupName, g_lineNum, g_sequenceParseFileName ); - } - - entry = Z_Malloc( sizeof( sentenceEntry_s ) ); - entry->nextEntry = NULL; - entry->data = copystring( data ); - entry->index = g_nonGlobalSentences; - entry->isGlobal = g_sequenceParseFileIsGlobal; - - group->numSentences++; - g_nonGlobalSentences++; - - if( group->firstSentence ) - { - for( last = group->firstSentence; last->nextEntry; last = last->nextEntry ); - - last->nextEntry = entry; - } - else - { - group->firstSentence = entry; - } -} - -/* -============= -Sequence_ParseSentenceLine - -============= -*/ -static qboolean Sequence_ParseSentenceLine( void ) -{ - char data[1024]; - char fullgroup[64]; - char groupName[64]; - char *c; - int lastCharacterPos; - size_t len; - - len = Sequence_GetToken( fullgroup, sizeof( fullgroup ) ); - - if( *fullgroup == '}' ) - return true; - - c = fullgroup + len; - - while( !isalpha( *c ) && *c != '_' ) - c--; - - c += 1; - - if( *c ) - *c = 0; - - Q_strncpy( groupName, fullgroup, sizeof( groupName )); - - len = Sequence_GetLine( data, sizeof( data ) ); - lastCharacterPos = len - 1; - - if( data[lastCharacterPos] == '\n' || data[lastCharacterPos] == '\r' ) - data[lastCharacterPos] = 0; - - Sequence_AddSentenceToGroup( groupName, data ); - return false; -} - -/* -============== -Sequence_ParseSentenceBlock - -============== -*/ -static char Sequence_ParseSentenceBlock( void ) -{ - qboolean end = false; - char ch = Sequence_GetSymbol( ); - if( ch != '{' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected '{' to start a\n new sentence block; found '%c' instead!", g_lineNum, g_sequenceParseFileName, ch ); - - while( !end ) - { - end = Sequence_ParseSentenceLine( ); - } - - return Sequence_GetSymbol( ); -} - -/* -============== -Sequence_ParseGlobalDataBlock - -============== -*/ -static char Sequence_ParseGlobalDataBlock( void ) -{ - char token[MAX_STRING]; - - Sequence_GetNameValueString( token, MAX_STRING ); - - if( Q_stricmp( token, "Sentences" ) ) - Con_Reportf( S_ERROR "Syntax error in file %s.seq on line %d: found global data block symbol '!' with unknown data type \"%s\"", g_sequenceParseFileName, g_lineNum, token ); - - return Sequence_ParseSentenceBlock( ); -} - -/* -============== -Sequence_GetEntryForName - -============== -*/ -static sequenceEntry_s *Sequence_GetEntryForName( const char *entryName ) -{ - sequenceEntry_s *scan; - - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - if( !Q_stricmp( entryName, scan->entryName ) ) - return scan; - } - - return NULL; -} - -/* -============== -Sequence_CopyCommand - -============== -*/ -static sequenceCommandLine_s *Sequence_CopyCommand( sequenceCommandLine_s *commandOrig ) -{ - sequenceCommandLine_s *commandCopy; - - commandCopy = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - - commandCopy->commandType = commandOrig->commandType; - commandCopy->clientMessage = commandOrig->clientMessage; - commandCopy->clientMessage.pMessage = copystring( commandOrig->clientMessage.pMessage ); - commandCopy->clientMessage.pName = copystring( commandOrig->clientMessage.pName ); - commandCopy->speakerName = copystring( commandOrig->speakerName ); - commandCopy->listenerName = copystring( commandOrig->listenerName ); - commandCopy->soundFileName = copystring( commandOrig->soundFileName ); - commandCopy->sentenceName = copystring( commandOrig->sentenceName ); - commandCopy->fireTargetNames = copystring( commandOrig->fireTargetNames ); - commandCopy->killTargetNames = copystring( commandOrig->killTargetNames ); - commandCopy->delay = commandOrig->delay; - commandCopy->repeatCount = commandOrig->repeatCount; - commandCopy->textChannel = commandOrig->textChannel; - commandCopy->modifierBitField = commandOrig->modifierBitField; - commandCopy->nextCommandLine = NULL; - - return commandCopy; -} - -/* -============== -Sequence_CopyCommandList - -============== -*/ -static sequenceCommandLine_s *Sequence_CopyCommandList( sequenceCommandLine_s *list ) -{ - sequenceCommandLine_s *scan, *copy, *new, *prev; - - copy = NULL; - prev = NULL; - - for( scan = list; scan; scan = scan->nextCommandLine ) - { - if( scan->commandType != SEQUENCE_COMMAND_SETDEFAULTS ) - { - new = Sequence_CopyCommand( scan ); - - if( prev ) - { - prev->nextCommandLine = new; - prev = new; - } - else - { - prev = new; - copy = new; - } - } - } - - return copy; -} - -/* -============== -Sequence_ExpandGosubsForEntry - -============== -*/ -static qboolean Sequence_ExpandGosubsForEntry( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd, *copyList, *scan; - sequenceEntry_s *gosubEntry; - qboolean foundGosubs = false; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - if( !cmd->clientMessage.pName ) - continue; - - if( !Q_stricmp( cmd->clientMessage.pName, entry->entryName ) ) - Con_Reportf( S_ERROR "Error in %s.seq: entry \"%s\" gosubs itself!\n", entry->fileName, entry->entryName ); - - gosubEntry = Sequence_GetEntryForName( cmd->clientMessage.pName ); - - if( !gosubEntry ) - Con_Reportf( S_ERROR "Error in %s.seq: Gosub in entry \"%s\" specified unknown entry \"%s\"\n", entry->fileName, entry->entryName, cmd->clientMessage.pName ); - - foundGosubs = true; - copyList = Sequence_CopyCommandList( gosubEntry->firstCommand ); - - if( copyList ) - { - for( scan = copyList->nextCommandLine; scan; scan = scan->nextCommandLine ); - - scan->nextCommandLine = cmd->nextCommandLine; - - Z_Free( cmd->clientMessage.pName ); - cmd->clientMessage.pName = NULL; - cmd = scan; - } - else - { - Z_Free( cmd->clientMessage.pName ); - cmd->clientMessage.pName = NULL; - } - } - - return !foundGosubs; -} - -/* -============== -Sequence_ExpandAllGosubs - -============== -*/ -static void Sequence_ExpandAllGosubs( void ) -{ - sequenceEntry_s *scan; - qboolean isComplete = true; - - while( !isComplete ) - { - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - isComplete = Sequence_ExpandGosubsForEntry( scan ); - } - } -} - -/* -============== -Sequence_FlattenEntry - -============== -*/ -static void Sequence_FlattenEntry( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd, *last = NULL; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - switch( cmd->commandType ) - { - case SEQUENCE_COMMAND_SETDEFAULTS: - Sequence_WriteDefaults( cmd, &g_blockScopeDefaults ); - cmd->commandType = SEQUENCE_COMMAND_NOOP; - break; - - case SEQUENCE_COMMAND_MODIFIER: - Sequence_WriteDefaults( cmd, &g_blockScopeDefaults ); - break; - - case SEQUENCE_COMMAND_POSTMODIFIER: - Sequence_WriteDefaults( cmd, last ); - break; - - default: - Sequence_BakeDefaults( cmd, &g_blockScopeDefaults ); - last = cmd; - } - } -} - -/* -============== -Sequence_FlattenAllEntries - -============== -*/ -static void Sequence_FlattenAllEntries( void ) -{ - sequenceEntry_s *entry; - - for( entry = g_sequenceList; entry; entry = entry->nextEntry ) - Sequence_FlattenEntry( entry ); -} - -/* -============== -Sequence_ParseBuffer - -============== -*/ -static void Sequence_ParseBuffer( char *buffer, int bufferSize ) -{ - char symbol; - - g_lineNum = 1; - g_scan = buffer; - g_lineScan = g_scan; - - Sequence_StripComments( buffer, &bufferSize ); - Sequence_ResetDefaults( &g_fileScopeDefaults, NULL ); - - symbol = Sequence_GetSymbol( ); - - while( symbol ) - { - switch( symbol ) - { - case '$': - do - symbol = Sequence_ParseModifier( &g_fileScopeDefaults ); - while( symbol == ',' ); - break; - - case '%': - symbol = Sequence_ParseEntry( ); - break; - - case '!': - symbol = Sequence_ParseGlobalDataBlock( ); - break; - - default: - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: At file scope, lines must begin with '$' (modifier) or '%%' (entry block) or '!' (sentence / global data block); found '%c'\n", g_lineNum, g_sequenceParseFileName, symbol ); - } - } - - Sequence_ExpandAllGosubs( ); - Sequence_FlattenAllEntries( ); -} - -/* -============== -Sequence_ParseFile - -============== -*/ -static void Sequence_ParseFile( const char *fileName, qboolean isGlobal ) -{ - byte *buffer; - fs_offset_t bufSize = 0; - - Q_strncpy( g_sequenceParseFileName, fileName, sizeof( g_sequenceParseFileName )); - g_sequenceParseFileIsGlobal = isGlobal; - - buffer = FS_LoadFile( va("sequences/%s.seq", fileName ), &bufSize, true ); - - if( !buffer ) - return; - - Con_Reportf( "reading sequence file: %s\n", fileName ); - - Sequence_ParseBuffer( (char *)buffer, bufSize ); - - Mem_Free( buffer ); -} - -/* -============== -Sequence_Init - -============== -*/ -void Sequence_Init( void ) -{ - Sequence_ParseFile( "global", true ); -} - -/* -============== -SequenceGet - -============== -*/ -sequenceEntry_s *Sequence_Get( const char *fileName, const char *entryName ) -{ - sequenceEntry_s *scan; - - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - if( ( !fileName || !Q_stricmp( fileName, scan->fileName ) ) && // a1ba: add filename check, even if originally it is ignored - !Q_stricmp( entryName, scan->entryName ) ) - return scan; - } - - return NULL; -} - -/* -============== -Sequence_FreeCommand - -============== -*/ -static void Sequence_FreeCommand( sequenceCommandLine_s *kill ) -{ - Z_Free( kill->fireTargetNames ); - Z_Free( kill->speakerName ); - Z_Free( kill->listenerName ); - Z_Free( kill->soundFileName ); - Z_Free( kill->sentenceName ); - Z_Free( kill->clientMessage.pName ); - Z_Free( kill->clientMessage.pMessage ); -} - -/* -============== -Sequence_FreeEntry - -============== -*/ -static void Sequence_FreeEntry( sequenceEntry_s *kill ) -{ - sequenceCommandLine_s *dead; - - Z_Free( kill->entryName ); - Z_Free( kill->fileName ); - - for( dead = kill->firstCommand; dead; dead = dead->nextCommandLine ) - { - kill->firstCommand = dead->nextCommandLine; - Sequence_FreeCommand( dead ); - } - - Z_Free( kill ); -} - -/* -============== -Sequence_FreeSentence - -============== -*/ -static void Sequence_FreeSentence( sentenceEntry_s *sentenceEntry ) -{ - Z_Free( sentenceEntry->data ); - Z_Free( sentenceEntry ); -} - -/* -============== -Sequence_FreeSentenceGroup - -============== -*/ -static void Sequence_FreeSentenceGroup( sentenceGroupEntry_s *groupEntry ) -{ - Z_Free( groupEntry->groupName ); - Z_Free( groupEntry ); -} - -/* -============== -Sequence_FreeSentenceGroupEntries - -============== -*/ -static void Sequence_FreeSentenceGroupEntries( sentenceGroupEntry_s *groupEntry, qboolean purgeGlobals ) -{ - sentenceEntry_s *sentenceEntry; - sentenceEntry_s *deadSentence; - sentenceEntry_s *prevSentence; - - sentenceEntry = groupEntry->firstSentence; - prevSentence = NULL; - - while( sentenceEntry ) - { - if( !sentenceEntry->isGlobal || purgeGlobals ) - { - if( prevSentence ) - prevSentence->nextEntry = sentenceEntry->nextEntry; - else - groupEntry->firstSentence = sentenceEntry->nextEntry; - - groupEntry->numSentences--; - g_nonGlobalSentences--; - - deadSentence = sentenceEntry; - sentenceEntry = sentenceEntry->nextEntry; - - Sequence_FreeSentence( deadSentence ); - } - else - { - prevSentence = sentenceEntry; - sentenceEntry = sentenceEntry->nextEntry; - } - } -} - -/* -============== -Sequence_PurgeEntries - -============== -*/ -static void Sequence_PurgeEntries( qboolean purgeGlobals ) -{ - sequenceEntry_s *scan; - sequenceEntry_s *dead; - sequenceEntry_s *prev; - sentenceGroupEntry_s *groupEntry; - sentenceGroupEntry_s *deadGroup; - sentenceGroupEntry_s *prevGroup; - - dead = NULL; - prev = NULL; - - for( scan = g_sequenceList; scan; ) - { - if( !scan->isGlobal || purgeGlobals ) - { - if( prev ) - prev->nextEntry = scan->nextEntry; - else - g_sequenceList = scan->nextEntry; - - dead = scan; - scan = scan->nextEntry; - Sequence_FreeEntry( dead ); - } - else - { - prev = scan; - scan = scan->nextEntry; - } - } - - groupEntry = g_sentenceGroupList; - prevGroup = NULL; - - while( groupEntry ) - { - Sequence_FreeSentenceGroupEntries( groupEntry, purgeGlobals ); - - if( groupEntry->numSentences ) - { - prevGroup = groupEntry; - groupEntry = groupEntry->nextEntry; - } - else - { - if( prevGroup ) - prevGroup->nextEntry = groupEntry->nextEntry; - else - g_sentenceGroupList = groupEntry->nextEntry; - - deadGroup = groupEntry; - groupEntry = groupEntry->nextEntry; - Sequence_FreeSentenceGroup( deadGroup ); - } - } -} - -/* -============== -Sequence_OnLevelLoad - -============== -*/ -void Sequence_OnLevelLoad( const char *mapName ) -{ - Sequence_PurgeEntries( false ); - Sequence_ParseFile( mapName, false ); -} diff --git a/engine/sequence.h b/engine/sequence.h deleted file mode 100644 index e7d8aabc..00000000 --- a/engine/sequence.h +++ /dev/null @@ -1,203 +0,0 @@ -//--------------------------------------------------------------------------- -// -// S c r i p t e d S e q u e n c e s -// -//--------------------------------------------------------------------------- -#ifndef _INCLUDE_SEQUENCE_H_ -#define _INCLUDE_SEQUENCE_H_ - - -#ifndef _DEF_BYTE_ -//typedef unsigned char byte; -#endif - -#ifndef CDLL_INT_H -//--------------------------------------------------------------------------- -// client_textmessage_t -//--------------------------------------------------------------------------- -typedef struct client_textmessage_s -{ - int effect; - byte r1, g1, b1, a1; // 2 colors for effects - byte r2, g2, b2, a2; - float x; - float y; - float fadein; - float fadeout; - float holdtime; - float fxtime; - char *pName; - char *pMessage; -} client_textmessage_t; -#endif - - -//--------------------------------------------------------------------------- -// sequenceCommandEnum_e -// -// Enumerated sequence command types. -//--------------------------------------------------------------------------- -enum sequenceCommandEnum_ -{ - SEQUENCE_COMMAND_ERROR = -1, - SEQUENCE_COMMAND_PAUSE = 0, - SEQUENCE_COMMAND_FIRETARGETS, - SEQUENCE_COMMAND_KILLTARGETS, - SEQUENCE_COMMAND_TEXT, - SEQUENCE_COMMAND_SOUND, - SEQUENCE_COMMAND_GOSUB, - SEQUENCE_COMMAND_SENTENCE, - SEQUENCE_COMMAND_REPEAT, - SEQUENCE_COMMAND_SETDEFAULTS, - SEQUENCE_COMMAND_MODIFIER, - SEQUENCE_COMMAND_POSTMODIFIER, - SEQUENCE_COMMAND_NOOP, - - SEQUENCE_MODIFIER_EFFECT, - SEQUENCE_MODIFIER_POSITION, - SEQUENCE_MODIFIER_COLOR, - SEQUENCE_MODIFIER_COLOR2, - SEQUENCE_MODIFIER_FADEIN, - SEQUENCE_MODIFIER_FADEOUT, - SEQUENCE_MODIFIER_HOLDTIME, - SEQUENCE_MODIFIER_FXTIME, - SEQUENCE_MODIFIER_SPEAKER, - SEQUENCE_MODIFIER_LISTENER, - SEQUENCE_MODIFIER_TEXTCHANNEL, -}; -typedef enum sequenceCommandEnum_ sequenceCommandEnum_e; - -//-------------------------------------------------------------------------- -// sequenceDefaultBits_e -// -// Enumerated list of possible modifiers for a command. This enumeration -// is used in a bitarray controlling what modifiers are specified for a command. -//--------------------------------------------------------------------------- -enum sequenceModifierBits -{ - SEQUENCE_MODIFIER_EFFECT_BIT = (1 << 1), - SEQUENCE_MODIFIER_POSITION_BIT = (1 << 2), - SEQUENCE_MODIFIER_COLOR_BIT = (1 << 3), - SEQUENCE_MODIFIER_COLOR2_BIT = (1 << 4), - SEQUENCE_MODIFIER_FADEIN_BIT = (1 << 5), - SEQUENCE_MODIFIER_FADEOUT_BIT = (1 << 6), - SEQUENCE_MODIFIER_HOLDTIME_BIT = (1 << 7), - SEQUENCE_MODIFIER_FXTIME_BIT = (1 << 8), - SEQUENCE_MODIFIER_SPEAKER_BIT = (1 << 9), - SEQUENCE_MODIFIER_LISTENER_BIT = (1 << 10), - SEQUENCE_MODIFIER_TEXTCHANNEL_BIT = (1 << 11), -}; -typedef enum sequenceModifierBits sequenceModifierBits_e ; - - -//--------------------------------------------------------------------------- -// sequenceCommandType_e -// -// Typeerated sequence command types. -//--------------------------------------------------------------------------- -enum sequenceCommandType_ -{ - SEQUENCE_TYPE_COMMAND, - SEQUENCE_TYPE_MODIFIER, -}; -typedef enum sequenceCommandType_ sequenceCommandType_e; - - -//--------------------------------------------------------------------------- -// sequenceCommandMapping_s -// -// A mapping of a command enumerated-value to its name. -//--------------------------------------------------------------------------- -typedef struct sequenceCommandMapping_ sequenceCommandMapping_s; -struct sequenceCommandMapping_ -{ - sequenceCommandEnum_e commandEnum; - const char* commandName; - sequenceCommandType_e commandType; -}; - - -//--------------------------------------------------------------------------- -// sequenceCommandLine_s -// -// Structure representing a single command (usually 1 line) from a -// .SEQ file entry. -//--------------------------------------------------------------------------- -typedef struct sequenceCommandLine_ sequenceCommandLine_s; -struct sequenceCommandLine_ -{ - int commandType; // Specifies the type of command - client_textmessage_t clientMessage; // Text HUD message struct - char* speakerName; // Targetname of speaking entity - char* listenerName; // Targetname of entity being spoken to - char* soundFileName; // Name of sound file to play - char* sentenceName; // Name of sentences.txt to play - char* fireTargetNames; // List of targetnames to fire - char* killTargetNames; // List of targetnames to remove - float delay; // Seconds 'till next command - int repeatCount; // If nonzero, reset execution pointer to top of block (N times, -1 = infinite) - int textChannel; // Display channel on which text message is sent - int modifierBitField; // Bit field to specify what clientmessage fields are valid - sequenceCommandLine_s* nextCommandLine; // Next command (linked list) -}; - - -//--------------------------------------------------------------------------- -// sequenceEntry_s -// -// Structure representing a single command (usually 1 line) from a -// .SEQ file entry. -//--------------------------------------------------------------------------- -typedef struct sequenceEntry_ sequenceEntry_s; -struct sequenceEntry_ -{ - char* fileName; // Name of sequence file without .SEQ extension - char* entryName; // Name of entry label in file - sequenceCommandLine_s* firstCommand; // Linked list of commands in entry - sequenceEntry_s* nextEntry; // Next loaded entry - qboolean isGlobal; // Is entry retained over level transitions? -}; - - - -//--------------------------------------------------------------------------- -// sentenceEntry_s -// Structure representing a single sentence of a group from a .SEQ -// file entry. Sentences are identical to entries in sentences.txt, but -// can be unique per level and are loaded/unloaded with the level. -//--------------------------------------------------------------------------- -typedef struct sentenceEntry_ sentenceEntry_s; -struct sentenceEntry_ -{ - char* data; // sentence data (ie "We have hostiles" ) - sentenceEntry_s* nextEntry; // Next loaded entry - qboolean isGlobal; // Is entry retained over level transitions? - unsigned int index; // this entry's position in the file. -}; - -//-------------------------------------------------------------------------- -// sentenceGroupEntry_s -// Structure representing a group of sentences found in a .SEQ file. -// A sentence group is defined by all sentences with the same name, ignoring -// the number at the end of the sentence name. Groups enable a sentence -// to be picked at random across a group. -//-------------------------------------------------------------------------- -typedef struct sentenceGroupEntry_ sentenceGroupEntry_s; -struct sentenceGroupEntry_ -{ - char* groupName; // name of the group (ie CT_ALERT ) - unsigned int numSentences; // number of sentences in group - sentenceEntry_s* firstSentence; // head of linked list of sentences in group - sentenceGroupEntry_s* nextEntry; // next loaded group -}; - -//--------------------------------------------------------------------------- -// Function declarations -//--------------------------------------------------------------------------- -sequenceEntry_s* Sequence_Get( const char* fileName, const char* entryName ); -void Sequence_OnLevelLoad( const char* mapName ); -sentenceEntry_s* Sequence_PickSentence( const char *groupName, int pickMethod, int *picked ); -void Sequence_Init( void ); -sentenceEntry_s *Sequence_GetSentenceByIndex( unsigned int index ); - -#endif // _INCLUDE_SEQUENCE_H_ diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index cc5a7679..b33d12b6 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -19,7 +19,6 @@ GNU General Public License for more details. #include "library.h" #include "voice.h" #include "pm_local.h" -#include "sequence.h" #if XASH_LOW_MEMORY != 2 int SV_UPDATE_BACKUP = SINGLEPLAYER_BACKUP; @@ -1086,8 +1085,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba SV_InitEdict( ent ); } - Sequence_OnLevelLoad( sv.name ); - // heartbeats will always be sent to the id master NET_MasterClear();