|
|
1.1 ! root 1: ! 2: //************************************************************************** ! 3: //** ! 4: //** sn_sonix.c : Heretic 2 : Raven Software, Corp. ! 5: //** ! 6: //** $RCSfile: sn_sonix.c,v $ ! 7: //** $Revision: 1.17 $ ! 8: //** $Date: 95/10/05 18:25:44 $ ! 9: //** $Author: paul $ ! 10: //** ! 11: //************************************************************************** ! 12: ! 13: // HEADER FILES ------------------------------------------------------------ ! 14: ! 15: #include <string.h> ! 16: #include "h2def.h" ! 17: #include "soundst.h" ! 18: ! 19: // MACROS ------------------------------------------------------------------ ! 20: ! 21: #define SS_MAX_SCRIPTS 64 ! 22: #define SS_TEMPBUFFER_SIZE 1024 ! 23: #define SS_SEQUENCE_NAME_LENGTH 32 ! 24: ! 25: #define SS_SCRIPT_NAME "SNDSEQ" ! 26: #define SS_STRING_PLAY "play" ! 27: #define SS_STRING_PLAYUNTILDONE "playuntildone" ! 28: #define SS_STRING_PLAYTIME "playtime" ! 29: #define SS_STRING_PLAYREPEAT "playrepeat" ! 30: #define SS_STRING_DELAY "delay" ! 31: #define SS_STRING_DELAYRAND "delayrand" ! 32: #define SS_STRING_VOLUME "volume" ! 33: #define SS_STRING_END "end" ! 34: #define SS_STRING_STOPSOUND "stopsound" ! 35: ! 36: // TYPES ------------------------------------------------------------------- ! 37: ! 38: typedef enum ! 39: { ! 40: SS_CMD_NONE, ! 41: SS_CMD_PLAY, ! 42: SS_CMD_WAITUNTILDONE, // used by PLAYUNTILDONE ! 43: SS_CMD_PLAYTIME, ! 44: SS_CMD_PLAYREPEAT, ! 45: SS_CMD_DELAY, ! 46: SS_CMD_DELAYRAND, ! 47: SS_CMD_VOLUME, ! 48: SS_CMD_STOPSOUND, ! 49: SS_CMD_END ! 50: } sscmds_t; ! 51: ! 52: // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- ! 53: ! 54: // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- ! 55: ! 56: // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- ! 57: ! 58: static void VerifySequencePtr(int *base, int *ptr); ! 59: static int GetSoundOffset(char *name); ! 60: ! 61: // EXTERNAL DATA DECLARATIONS ---------------------------------------------- ! 62: ! 63: extern sfxinfo_t S_sfx[]; ! 64: ! 65: // PUBLIC DATA DEFINITIONS ------------------------------------------------- ! 66: ! 67: // PRIVATE DATA DEFINITIONS ------------------------------------------------ ! 68: ! 69: static struct ! 70: { ! 71: char name[SS_SEQUENCE_NAME_LENGTH]; ! 72: int scriptNum; ! 73: int stopSound; ! 74: } SequenceTranslate[SEQ_NUMSEQ] = ! 75: { ! 76: { "Platform", 0, 0 }, ! 77: { "Platform", 0, 0 }, // a 'heavy' platform is just a platform ! 78: { "PlatformMetal", 0, 0 }, ! 79: { "Platform", 0, 0 }, // same with a 'creak' platform ! 80: { "Silence", 0, 0 }, ! 81: { "Lava", 0, 0 }, ! 82: { "Water", 0, 0 }, ! 83: { "Ice", 0, 0 }, ! 84: { "Earth", 0, 0 }, ! 85: { "PlatformMetal2", 0, 0 }, ! 86: { "DoorNormal", 0, 0 }, ! 87: { "DoorHeavy", 0, 0 }, ! 88: { "DoorMetal", 0, 0 }, ! 89: { "DoorCreak", 0, 0 }, ! 90: { "Silence", 0, 0 }, ! 91: { "Lava", 0, 0 }, ! 92: { "Water", 0, 0}, ! 93: { "Ice", 0, 0 }, ! 94: { "Earth", 0, 0}, ! 95: { "DoorMetal2", 0, 0 }, ! 96: { "Wind", 0, 0 } ! 97: }; ! 98: ! 99: static int *SequenceData[SS_MAX_SCRIPTS]; ! 100: ! 101: int ActiveSequences; ! 102: seqnode_t *SequenceListHead; ! 103: ! 104: // CODE -------------------------------------------------------------------- ! 105: ! 106: //========================================================================== ! 107: // ! 108: // VerifySequencePtr ! 109: // ! 110: // Verifies the integrity of the temporary ptr, and ensures that the ptr ! 111: // isn't exceeding the size of the temporary buffer ! 112: //========================================================================== ! 113: ! 114: static void VerifySequencePtr(int *base, int *ptr) ! 115: { ! 116: if(ptr-base > SS_TEMPBUFFER_SIZE) ! 117: { ! 118: I_Error("VerifySequencePtr: tempPtr >= %d\n", SS_TEMPBUFFER_SIZE); ! 119: } ! 120: } ! 121: ! 122: //========================================================================== ! 123: // ! 124: // GetSoundOffset ! 125: // ! 126: //========================================================================== ! 127: ! 128: static int GetSoundOffset(char *name) ! 129: { ! 130: int i; ! 131: ! 132: for(i = 0; i < NUMSFX; i++) ! 133: { ! 134: if(!strcasecmp(name, S_sfx[i].tagName)) ! 135: { ! 136: return i; ! 137: } ! 138: } ! 139: SC_ScriptError("GetSoundOffset: Unknown sound name\n"); ! 140: return 0; ! 141: } ! 142: ! 143: //========================================================================== ! 144: // ! 145: // SN_InitSequenceScript ! 146: // ! 147: //========================================================================== ! 148: ! 149: void SN_InitSequenceScript(void) ! 150: { ! 151: int i, j; ! 152: int inSequence; ! 153: int *tempDataStart; ! 154: int *tempDataPtr; ! 155: ! 156: inSequence = -1; ! 157: ActiveSequences = 0; ! 158: for(i = 0; i < SS_MAX_SCRIPTS; i++) ! 159: { ! 160: SequenceData[i] = NULL; ! 161: } ! 162: SC_Open(SS_SCRIPT_NAME); ! 163: while(SC_GetString()) ! 164: { ! 165: if(*sc_String == ':') ! 166: { ! 167: if(inSequence != -1) ! 168: { ! 169: SC_ScriptError("SN_InitSequenceScript: Nested Script Error"); ! 170: } ! 171: tempDataStart = (int *)Z_Malloc(SS_TEMPBUFFER_SIZE, ! 172: PU_STATIC, NULL); ! 173: memset(tempDataStart, 0, SS_TEMPBUFFER_SIZE); ! 174: tempDataPtr = tempDataStart; ! 175: for(i = 0; i < SS_MAX_SCRIPTS; i++) ! 176: { ! 177: if(SequenceData[i] == NULL) ! 178: { ! 179: break; ! 180: } ! 181: } ! 182: if(i == SS_MAX_SCRIPTS) ! 183: { ! 184: I_Error("Number of SS Scripts >= SS_MAX_SCRIPTS"); ! 185: } ! 186: for(j = 0; j < SEQ_NUMSEQ; j++) ! 187: { ! 188: if(!strcasecmp(SequenceTranslate[j].name, sc_String+1)) ! 189: { ! 190: SequenceTranslate[j].scriptNum = i; ! 191: inSequence = j; ! 192: break; ! 193: } ! 194: } ! 195: continue; // parse the next command ! 196: } ! 197: if(inSequence == -1) ! 198: { ! 199: continue; ! 200: } ! 201: if(SC_Compare(SS_STRING_PLAYUNTILDONE)) ! 202: { ! 203: VerifySequencePtr(tempDataStart, tempDataPtr); ! 204: SC_MustGetString(); ! 205: *tempDataPtr++ = SS_CMD_PLAY; ! 206: *tempDataPtr++ = GetSoundOffset(sc_String); ! 207: *tempDataPtr++ = SS_CMD_WAITUNTILDONE; ! 208: } ! 209: else if(SC_Compare(SS_STRING_PLAY)) ! 210: { ! 211: VerifySequencePtr(tempDataStart, tempDataPtr); ! 212: SC_MustGetString(); ! 213: *tempDataPtr++ = SS_CMD_PLAY; ! 214: *tempDataPtr++ = GetSoundOffset(sc_String); ! 215: } ! 216: else if(SC_Compare(SS_STRING_PLAYTIME)) ! 217: { ! 218: VerifySequencePtr(tempDataStart, tempDataPtr); ! 219: SC_MustGetString(); ! 220: *tempDataPtr++ = SS_CMD_PLAY; ! 221: *tempDataPtr++ = GetSoundOffset(sc_String); ! 222: SC_MustGetNumber(); ! 223: *tempDataPtr++ = SS_CMD_DELAY; ! 224: *tempDataPtr++ = sc_Number; ! 225: } ! 226: else if(SC_Compare(SS_STRING_PLAYREPEAT)) ! 227: { ! 228: VerifySequencePtr(tempDataStart, tempDataPtr); ! 229: SC_MustGetString(); ! 230: *tempDataPtr++ = SS_CMD_PLAYREPEAT; ! 231: *tempDataPtr++ = GetSoundOffset(sc_String); ! 232: } ! 233: else if(SC_Compare(SS_STRING_DELAY)) ! 234: { ! 235: VerifySequencePtr(tempDataStart, tempDataPtr); ! 236: *tempDataPtr++ = SS_CMD_DELAY; ! 237: SC_MustGetNumber(); ! 238: *tempDataPtr++ = sc_Number; ! 239: } ! 240: else if(SC_Compare(SS_STRING_DELAYRAND)) ! 241: { ! 242: VerifySequencePtr(tempDataStart, tempDataPtr); ! 243: *tempDataPtr++ = SS_CMD_DELAYRAND; ! 244: SC_MustGetNumber(); ! 245: *tempDataPtr++ = sc_Number; ! 246: SC_MustGetNumber(); ! 247: *tempDataPtr++ = sc_Number; ! 248: } ! 249: else if(SC_Compare(SS_STRING_VOLUME)) ! 250: { ! 251: VerifySequencePtr(tempDataStart, tempDataPtr); ! 252: *tempDataPtr++ = SS_CMD_VOLUME; ! 253: SC_MustGetNumber(); ! 254: *tempDataPtr++ = sc_Number; ! 255: } ! 256: else if(SC_Compare(SS_STRING_END)) ! 257: { ! 258: int dataSize; ! 259: ! 260: *tempDataPtr++ = SS_CMD_END; ! 261: dataSize = (tempDataPtr-tempDataStart)*sizeof(int); ! 262: SequenceData[i] = (int *)Z_Malloc(dataSize, PU_STATIC, ! 263: NULL); ! 264: memcpy(SequenceData[i], tempDataStart, dataSize); ! 265: Z_Free(tempDataStart); ! 266: inSequence = -1; ! 267: } ! 268: else if(SC_Compare(SS_STRING_STOPSOUND)) ! 269: { ! 270: SC_MustGetString(); ! 271: SequenceTranslate[inSequence].stopSound = ! 272: GetSoundOffset(sc_String); ! 273: *tempDataPtr++ = SS_CMD_STOPSOUND; ! 274: } ! 275: else ! 276: { ! 277: SC_ScriptError("SN_InitSequenceScript: Unknown commmand.\n"); ! 278: } ! 279: } ! 280: } ! 281: ! 282: //========================================================================== ! 283: // ! 284: // SN_StartSequence ! 285: // ! 286: //========================================================================== ! 287: ! 288: void SN_StartSequence(mobj_t *mobj, int sequence) ! 289: { ! 290: seqnode_t *node; ! 291: ! 292: SN_StopSequence(mobj); // Stop any previous sequence ! 293: node = (seqnode_t *)Z_Malloc(sizeof(seqnode_t), PU_STATIC, NULL); ! 294: node->sequencePtr = SequenceData[SequenceTranslate[sequence].scriptNum]; ! 295: node->sequence = sequence; ! 296: node->mobj = mobj; ! 297: node->delayTics = 0; ! 298: node->stopSound = SequenceTranslate[sequence].stopSound; ! 299: node->volume = 127; // Start at max volume ! 300: ! 301: if(!SequenceListHead) ! 302: { ! 303: SequenceListHead = node; ! 304: node->next = node->prev = NULL; ! 305: } ! 306: else ! 307: { ! 308: SequenceListHead->prev = node; ! 309: node->next = SequenceListHead; ! 310: node->prev = NULL; ! 311: SequenceListHead = node; ! 312: } ! 313: ActiveSequences++; ! 314: return; ! 315: } ! 316: ! 317: //========================================================================== ! 318: // ! 319: // SN_StartSequenceName ! 320: // ! 321: //========================================================================== ! 322: ! 323: void SN_StartSequenceName(mobj_t *mobj, char *name) ! 324: { ! 325: int i; ! 326: ! 327: for(i = 0; i < SEQ_NUMSEQ; i++) ! 328: { ! 329: if(!strcmp(name, SequenceTranslate[i].name)) ! 330: { ! 331: SN_StartSequence(mobj, i); ! 332: return; ! 333: } ! 334: } ! 335: } ! 336: ! 337: //========================================================================== ! 338: // ! 339: // SN_StopSequence ! 340: // ! 341: //========================================================================== ! 342: ! 343: void SN_StopSequence(mobj_t *mobj) ! 344: { ! 345: seqnode_t *node; ! 346: ! 347: for(node = SequenceListHead; node; node = node->next) ! 348: { ! 349: if(node->mobj == mobj) ! 350: { ! 351: S_StopSound(mobj); ! 352: if(node->stopSound) ! 353: { ! 354: S_StartSoundAtVolume(mobj, node->stopSound, node->volume); ! 355: } ! 356: if(SequenceListHead == node) ! 357: { ! 358: SequenceListHead = node->next; ! 359: } ! 360: if(node->prev) ! 361: { ! 362: node->prev->next = node->next; ! 363: } ! 364: if(node->next) ! 365: { ! 366: node->next->prev = node->prev; ! 367: } ! 368: Z_Free(node); ! 369: ActiveSequences--; ! 370: } ! 371: } ! 372: } ! 373: ! 374: //========================================================================== ! 375: // ! 376: // SN_UpdateActiveSequences ! 377: // ! 378: //========================================================================== ! 379: ! 380: void SN_UpdateActiveSequences(void) ! 381: { ! 382: seqnode_t *node; ! 383: boolean sndPlaying; ! 384: ! 385: if(!ActiveSequences || paused) ! 386: { // No sequences currently playing/game is paused ! 387: return; ! 388: } ! 389: for(node = SequenceListHead; node; node = node->next) ! 390: { ! 391: if(node->delayTics) ! 392: { ! 393: node->delayTics--; ! 394: continue; ! 395: } ! 396: sndPlaying = S_GetSoundPlayingInfo(node->mobj, node->currentSoundID); ! 397: switch(*node->sequencePtr) ! 398: { ! 399: case SS_CMD_PLAY: ! 400: if(!sndPlaying) ! 401: { ! 402: node->currentSoundID = *(node->sequencePtr+1); ! 403: S_StartSoundAtVolume(node->mobj, node->currentSoundID, ! 404: node->volume); ! 405: } ! 406: node->sequencePtr += 2; ! 407: break; ! 408: case SS_CMD_WAITUNTILDONE: ! 409: if(!sndPlaying) ! 410: { ! 411: node->sequencePtr++; ! 412: node->currentSoundID = 0; ! 413: } ! 414: break; ! 415: case SS_CMD_PLAYREPEAT: ! 416: if(!sndPlaying) ! 417: { ! 418: node->currentSoundID = *(node->sequencePtr+1); ! 419: S_StartSoundAtVolume(node->mobj, node->currentSoundID, ! 420: node->volume); ! 421: } ! 422: break; ! 423: case SS_CMD_DELAY: ! 424: node->delayTics = *(node->sequencePtr+1); ! 425: node->sequencePtr += 2; ! 426: node->currentSoundID = 0; ! 427: break; ! 428: case SS_CMD_DELAYRAND: ! 429: node->delayTics = *(node->sequencePtr+1)+ ! 430: M_Random()%(*(node->sequencePtr+2)-*(node->sequencePtr+1)); ! 431: node->sequencePtr += 2; ! 432: node->currentSoundID = 0; ! 433: break; ! 434: case SS_CMD_VOLUME: ! 435: node->volume = (127*(*(node->sequencePtr+1)))/100; ! 436: node->sequencePtr += 2; ! 437: break; ! 438: case SS_CMD_STOPSOUND: ! 439: // Wait until something else stops the sequence ! 440: break; ! 441: case SS_CMD_END: ! 442: SN_StopSequence(node->mobj); ! 443: break; ! 444: default: ! 445: break; ! 446: } ! 447: } ! 448: } ! 449: ! 450: //========================================================================== ! 451: // ! 452: // SN_StopAllSequences ! 453: // ! 454: //========================================================================== ! 455: ! 456: void SN_StopAllSequences(void) ! 457: { ! 458: seqnode_t *node; ! 459: ! 460: for(node = SequenceListHead; node; node = node->next) ! 461: { ! 462: node->stopSound = 0; // don't play any stop sounds ! 463: SN_StopSequence(node->mobj); ! 464: } ! 465: } ! 466: ! 467: //========================================================================== ! 468: // ! 469: // SN_GetSequenceOffset ! 470: // ! 471: //========================================================================== ! 472: ! 473: int SN_GetSequenceOffset(int sequence, int *sequencePtr) ! 474: { ! 475: return (sequencePtr-SequenceData[SequenceTranslate[sequence].scriptNum]); ! 476: } ! 477: ! 478: //========================================================================== ! 479: // ! 480: // SN_ChangeNodeData ! 481: // ! 482: // nodeNum zero is the first node ! 483: //========================================================================== ! 484: ! 485: void SN_ChangeNodeData(int nodeNum, int seqOffset, int delayTics, int volume, ! 486: int currentSoundID) ! 487: { ! 488: int i; ! 489: seqnode_t *node; ! 490: ! 491: i = 0; ! 492: node = SequenceListHead; ! 493: while(node && i < nodeNum) ! 494: { ! 495: node = node->next; ! 496: i++; ! 497: } ! 498: if(!node) ! 499: { // reach the end of the list before finding the nodeNum-th node ! 500: return; ! 501: } ! 502: node->delayTics = delayTics; ! 503: node->volume = volume; ! 504: node->sequencePtr += seqOffset; ! 505: node->currentSoundID = currentSoundID; ! 506: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.