From 0df2cb80cf03d7259746834220d209b306a8c503 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 4 Sep 2008 23:15:36 +0000 Subject: Add GPLed Heretic/Hexen source. Subversion-branch: /branches/raven-branch Subversion-revision: 1195 --- src/hexen/sn_sonix.c | 506 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 src/hexen/sn_sonix.c (limited to 'src/hexen/sn_sonix.c') diff --git a/src/hexen/sn_sonix.c b/src/hexen/sn_sonix.c new file mode 100644 index 00000000..78ab6e0d --- /dev/null +++ b/src/hexen/sn_sonix.c @@ -0,0 +1,506 @@ + +//************************************************************************** +//** +//** sn_sonix.c : Heretic 2 : Raven Software, Corp. +//** +//** $RCSfile: sn_sonix.c,v $ +//** $Revision: 1.17 $ +//** $Date: 95/10/05 18:25:44 $ +//** $Author: paul $ +//** +//************************************************************************** + +// HEADER FILES ------------------------------------------------------------ + +#include +#include "h2def.h" +#include "soundst.h" + +// MACROS ------------------------------------------------------------------ + +#define SS_MAX_SCRIPTS 64 +#define SS_TEMPBUFFER_SIZE 1024 +#define SS_SEQUENCE_NAME_LENGTH 32 + +#define SS_SCRIPT_NAME "SNDSEQ" +#define SS_STRING_PLAY "play" +#define SS_STRING_PLAYUNTILDONE "playuntildone" +#define SS_STRING_PLAYTIME "playtime" +#define SS_STRING_PLAYREPEAT "playrepeat" +#define SS_STRING_DELAY "delay" +#define SS_STRING_DELAYRAND "delayrand" +#define SS_STRING_VOLUME "volume" +#define SS_STRING_END "end" +#define SS_STRING_STOPSOUND "stopsound" + +// TYPES ------------------------------------------------------------------- + +typedef enum +{ + SS_CMD_NONE, + SS_CMD_PLAY, + SS_CMD_WAITUNTILDONE, // used by PLAYUNTILDONE + SS_CMD_PLAYTIME, + SS_CMD_PLAYREPEAT, + SS_CMD_DELAY, + SS_CMD_DELAYRAND, + SS_CMD_VOLUME, + SS_CMD_STOPSOUND, + SS_CMD_END +} sscmds_t; + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +static void VerifySequencePtr(int *base, int *ptr); +static int GetSoundOffset(char *name); + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +extern sfxinfo_t S_sfx[]; + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static struct +{ + char name[SS_SEQUENCE_NAME_LENGTH]; + int scriptNum; + int stopSound; +} SequenceTranslate[SEQ_NUMSEQ] = +{ + { "Platform", 0, 0 }, + { "Platform", 0, 0 }, // a 'heavy' platform is just a platform + { "PlatformMetal", 0, 0 }, + { "Platform", 0, 0 }, // same with a 'creak' platform + { "Silence", 0, 0 }, + { "Lava", 0, 0 }, + { "Water", 0, 0 }, + { "Ice", 0, 0 }, + { "Earth", 0, 0 }, + { "PlatformMetal2", 0, 0 }, + { "DoorNormal", 0, 0 }, + { "DoorHeavy", 0, 0 }, + { "DoorMetal", 0, 0 }, + { "DoorCreak", 0, 0 }, + { "Silence", 0, 0 }, + { "Lava", 0, 0 }, + { "Water", 0, 0}, + { "Ice", 0, 0 }, + { "Earth", 0, 0}, + { "DoorMetal2", 0, 0 }, + { "Wind", 0, 0 } +}; + +static int *SequenceData[SS_MAX_SCRIPTS]; + +int ActiveSequences; +seqnode_t *SequenceListHead; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// VerifySequencePtr +// +// Verifies the integrity of the temporary ptr, and ensures that the ptr +// isn't exceeding the size of the temporary buffer +//========================================================================== + +static void VerifySequencePtr(int *base, int *ptr) +{ + if(ptr-base > SS_TEMPBUFFER_SIZE) + { + I_Error("VerifySequencePtr: tempPtr >= %d\n", SS_TEMPBUFFER_SIZE); + } +} + +//========================================================================== +// +// GetSoundOffset +// +//========================================================================== + +static int GetSoundOffset(char *name) +{ + int i; + + for(i = 0; i < NUMSFX; i++) + { + if(!strcasecmp(name, S_sfx[i].tagName)) + { + return i; + } + } + SC_ScriptError("GetSoundOffset: Unknown sound name\n"); + return 0; +} + +//========================================================================== +// +// SN_InitSequenceScript +// +//========================================================================== + +void SN_InitSequenceScript(void) +{ + int i, j; + int inSequence; + int *tempDataStart; + int *tempDataPtr; + + inSequence = -1; + ActiveSequences = 0; + for(i = 0; i < SS_MAX_SCRIPTS; i++) + { + SequenceData[i] = NULL; + } + SC_Open(SS_SCRIPT_NAME); + while(SC_GetString()) + { + if(*sc_String == ':') + { + if(inSequence != -1) + { + SC_ScriptError("SN_InitSequenceScript: Nested Script Error"); + } + tempDataStart = (int *)Z_Malloc(SS_TEMPBUFFER_SIZE, + PU_STATIC, NULL); + memset(tempDataStart, 0, SS_TEMPBUFFER_SIZE); + tempDataPtr = tempDataStart; + for(i = 0; i < SS_MAX_SCRIPTS; i++) + { + if(SequenceData[i] == NULL) + { + break; + } + } + if(i == SS_MAX_SCRIPTS) + { + I_Error("Number of SS Scripts >= SS_MAX_SCRIPTS"); + } + for(j = 0; j < SEQ_NUMSEQ; j++) + { + if(!strcasecmp(SequenceTranslate[j].name, sc_String+1)) + { + SequenceTranslate[j].scriptNum = i; + inSequence = j; + break; + } + } + continue; // parse the next command + } + if(inSequence == -1) + { + continue; + } + if(SC_Compare(SS_STRING_PLAYUNTILDONE)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + SC_MustGetString(); + *tempDataPtr++ = SS_CMD_PLAY; + *tempDataPtr++ = GetSoundOffset(sc_String); + *tempDataPtr++ = SS_CMD_WAITUNTILDONE; + } + else if(SC_Compare(SS_STRING_PLAY)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + SC_MustGetString(); + *tempDataPtr++ = SS_CMD_PLAY; + *tempDataPtr++ = GetSoundOffset(sc_String); + } + else if(SC_Compare(SS_STRING_PLAYTIME)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + SC_MustGetString(); + *tempDataPtr++ = SS_CMD_PLAY; + *tempDataPtr++ = GetSoundOffset(sc_String); + SC_MustGetNumber(); + *tempDataPtr++ = SS_CMD_DELAY; + *tempDataPtr++ = sc_Number; + } + else if(SC_Compare(SS_STRING_PLAYREPEAT)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + SC_MustGetString(); + *tempDataPtr++ = SS_CMD_PLAYREPEAT; + *tempDataPtr++ = GetSoundOffset(sc_String); + } + else if(SC_Compare(SS_STRING_DELAY)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + *tempDataPtr++ = SS_CMD_DELAY; + SC_MustGetNumber(); + *tempDataPtr++ = sc_Number; + } + else if(SC_Compare(SS_STRING_DELAYRAND)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + *tempDataPtr++ = SS_CMD_DELAYRAND; + SC_MustGetNumber(); + *tempDataPtr++ = sc_Number; + SC_MustGetNumber(); + *tempDataPtr++ = sc_Number; + } + else if(SC_Compare(SS_STRING_VOLUME)) + { + VerifySequencePtr(tempDataStart, tempDataPtr); + *tempDataPtr++ = SS_CMD_VOLUME; + SC_MustGetNumber(); + *tempDataPtr++ = sc_Number; + } + else if(SC_Compare(SS_STRING_END)) + { + int dataSize; + + *tempDataPtr++ = SS_CMD_END; + dataSize = (tempDataPtr-tempDataStart)*sizeof(int); + SequenceData[i] = (int *)Z_Malloc(dataSize, PU_STATIC, + NULL); + memcpy(SequenceData[i], tempDataStart, dataSize); + Z_Free(tempDataStart); + inSequence = -1; + } + else if(SC_Compare(SS_STRING_STOPSOUND)) + { + SC_MustGetString(); + SequenceTranslate[inSequence].stopSound = + GetSoundOffset(sc_String); + *tempDataPtr++ = SS_CMD_STOPSOUND; + } + else + { + SC_ScriptError("SN_InitSequenceScript: Unknown commmand.\n"); + } + } +} + +//========================================================================== +// +// SN_StartSequence +// +//========================================================================== + +void SN_StartSequence(mobj_t *mobj, int sequence) +{ + seqnode_t *node; + + SN_StopSequence(mobj); // Stop any previous sequence + node = (seqnode_t *)Z_Malloc(sizeof(seqnode_t), PU_STATIC, NULL); + node->sequencePtr = SequenceData[SequenceTranslate[sequence].scriptNum]; + node->sequence = sequence; + node->mobj = mobj; + node->delayTics = 0; + node->stopSound = SequenceTranslate[sequence].stopSound; + node->volume = 127; // Start at max volume + + if(!SequenceListHead) + { + SequenceListHead = node; + node->next = node->prev = NULL; + } + else + { + SequenceListHead->prev = node; + node->next = SequenceListHead; + node->prev = NULL; + SequenceListHead = node; + } + ActiveSequences++; + return; +} + +//========================================================================== +// +// SN_StartSequenceName +// +//========================================================================== + +void SN_StartSequenceName(mobj_t *mobj, char *name) +{ + int i; + + for(i = 0; i < SEQ_NUMSEQ; i++) + { + if(!strcmp(name, SequenceTranslate[i].name)) + { + SN_StartSequence(mobj, i); + return; + } + } +} + +//========================================================================== +// +// SN_StopSequence +// +//========================================================================== + +void SN_StopSequence(mobj_t *mobj) +{ + seqnode_t *node; + + for(node = SequenceListHead; node; node = node->next) + { + if(node->mobj == mobj) + { + S_StopSound(mobj); + if(node->stopSound) + { + S_StartSoundAtVolume(mobj, node->stopSound, node->volume); + } + if(SequenceListHead == node) + { + SequenceListHead = node->next; + } + if(node->prev) + { + node->prev->next = node->next; + } + if(node->next) + { + node->next->prev = node->prev; + } + Z_Free(node); + ActiveSequences--; + } + } +} + +//========================================================================== +// +// SN_UpdateActiveSequences +// +//========================================================================== + +void SN_UpdateActiveSequences(void) +{ + seqnode_t *node; + boolean sndPlaying; + + if(!ActiveSequences || paused) + { // No sequences currently playing/game is paused + return; + } + for(node = SequenceListHead; node; node = node->next) + { + if(node->delayTics) + { + node->delayTics--; + continue; + } + sndPlaying = S_GetSoundPlayingInfo(node->mobj, node->currentSoundID); + switch(*node->sequencePtr) + { + case SS_CMD_PLAY: + if(!sndPlaying) + { + node->currentSoundID = *(node->sequencePtr+1); + S_StartSoundAtVolume(node->mobj, node->currentSoundID, + node->volume); + } + node->sequencePtr += 2; + break; + case SS_CMD_WAITUNTILDONE: + if(!sndPlaying) + { + node->sequencePtr++; + node->currentSoundID = 0; + } + break; + case SS_CMD_PLAYREPEAT: + if(!sndPlaying) + { + node->currentSoundID = *(node->sequencePtr+1); + S_StartSoundAtVolume(node->mobj, node->currentSoundID, + node->volume); + } + break; + case SS_CMD_DELAY: + node->delayTics = *(node->sequencePtr+1); + node->sequencePtr += 2; + node->currentSoundID = 0; + break; + case SS_CMD_DELAYRAND: + node->delayTics = *(node->sequencePtr+1)+ + M_Random()%(*(node->sequencePtr+2)-*(node->sequencePtr+1)); + node->sequencePtr += 2; + node->currentSoundID = 0; + break; + case SS_CMD_VOLUME: + node->volume = (127*(*(node->sequencePtr+1)))/100; + node->sequencePtr += 2; + break; + case SS_CMD_STOPSOUND: + // Wait until something else stops the sequence + break; + case SS_CMD_END: + SN_StopSequence(node->mobj); + break; + default: + break; + } + } +} + +//========================================================================== +// +// SN_StopAllSequences +// +//========================================================================== + +void SN_StopAllSequences(void) +{ + seqnode_t *node; + + for(node = SequenceListHead; node; node = node->next) + { + node->stopSound = 0; // don't play any stop sounds + SN_StopSequence(node->mobj); + } +} + +//========================================================================== +// +// SN_GetSequenceOffset +// +//========================================================================== + +int SN_GetSequenceOffset(int sequence, int *sequencePtr) +{ + return (sequencePtr-SequenceData[SequenceTranslate[sequence].scriptNum]); +} + +//========================================================================== +// +// SN_ChangeNodeData +// +// nodeNum zero is the first node +//========================================================================== + +void SN_ChangeNodeData(int nodeNum, int seqOffset, int delayTics, int volume, + int currentSoundID) +{ + int i; + seqnode_t *node; + + i = 0; + node = SequenceListHead; + while(node && i < nodeNum) + { + node = node->next; + i++; + } + if(!node) + { // reach the end of the list before finding the nodeNum-th node + return; + } + node->delayTics = delayTics; + node->volume = volume; + node->sequencePtr += seqOffset; + node->currentSoundID = currentSoundID; +} -- cgit v1.2.3