diff options
author | James Haley | 2010-09-11 21:12:06 +0000 |
---|---|---|
committer | James Haley | 2010-09-11 21:12:06 +0000 |
commit | 90c196e4eb1d079fa946e764ed72a9ecd2c86dac (patch) | |
tree | eccef190c9caa7ce4d6ff5e585286749c1432bb8 /src/strife | |
parent | b6938d1533d624a5815660c40aeda9125090f55e (diff) | |
download | chocolate-doom-90c196e4eb1d079fa946e764ed72a9ecd2c86dac.tar.gz chocolate-doom-90c196e4eb1d079fa946e764ed72a9ecd2c86dac.tar.bz2 chocolate-doom-90c196e4eb1d079fa946e764ed72a9ecd2c86dac.zip |
Added code (some possibly temporary?) to load voices.wad. Fixed several
problems with playing of voice sounds - especially had to add a dynamic
hashtable of voice sfxinfo_t's because Choco won't tolerate overwriting
them once they've been used (see channel_playing array in i_sdlsound.c)
- PROBLEM: Random Z_Malloc failures when trying to play sounds. Cannot
catch in debugger so far.
Subversion-branch: /branches/strife-branch
Subversion-revision: 2065
Diffstat (limited to 'src/strife')
-rw-r--r-- | src/strife/d_main.c | 137 | ||||
-rw-r--r-- | src/strife/p_dialog.c | 5 | ||||
-rw-r--r-- | src/strife/s_sound.c | 117 | ||||
-rw-r--r-- | src/strife/s_sound.h | 4 |
4 files changed, 199 insertions, 64 deletions
diff --git a/src/strife/d_main.c b/src/strife/d_main.c index e7ed01be..041a4bc8 100644 --- a/src/strife/d_main.c +++ b/src/strife/d_main.c @@ -127,6 +127,10 @@ FILE* debugfile; boolean advancedemo; +// haleyjd 09/11/10: [STRIFE] Game type variables +boolean isregistered; +boolean isdemoversion; + // Store demo, do not accept any inputs // haleyjd [STRIFE] Unused. //boolean storedemo; @@ -696,6 +700,53 @@ static char *GetGameName(char *gamename) return gamename; } +// +// haleyjd: STRIFE-FIXME: Temporary? +// Code borrowed from Eternity, and modified to return separator char +// +char M_GetFilePath(const char *fn, char *dest, size_t len) +{ + boolean found_slash = false; + char *p; + char sepchar = '\0'; + + memset(dest, 0, len); + + p = dest + len - 1; + + strncpy(dest, fn, len); + + while(p >= dest) + { + if(*p == '/' || *p == '\\') + { + sepchar = *p; + found_slash = true; // mark that the path ended with a slash + *p = '\0'; + break; + } + *p = '\0'; + p--; + } + + // haleyjd: in the case that no slash was ever found, yet the + // path string is empty, we are dealing with a file local to the + // working directory. The proper path to return for such a string is + // not "", but ".", since the format strings add a slash now. When + // the string is empty but a slash WAS found, we really do want to + // return the empty string, since the path is relative to the root. + if(!found_slash && *dest == '\0') + *dest = '.'; + + // if a separator is not found, default to forward, because Windows + // supports that too. + if(sepchar == '\0') + sepchar = '/'; + + return sepchar; +} + + // // Find out what version of Doom is playing. // @@ -707,59 +758,59 @@ void D_IdentifyVersion(void) // IdentifyIWADByName. However, if the iwad does not match // any known IWAD name, we may have a dilemma. Try to // identify by its contents. - - if (gamemission == none) - { - unsigned int i; - - for (i=0; i<numlumps; ++i) - { - if (!strncasecmp(lumpinfo[i].name, "MAP01", 8)) - { - gamemission = doom2; - break; - } - else if (!strncasecmp(lumpinfo[i].name, "E1M1", 8)) - { - gamemission = doom; - break; - } - } - - if (gamemission == none) - { - // Still no idea. I don't think this is going to work. - - I_Error("Unknown or invalid IWAD file."); - } - } + + // STRIFE-TODO: some elaborate checks? for now we assume... + // The logic in strife1.exe is simple: + // * if strife1.wad is found, set isregistered = true + // * if strife0.wad is found, set isdemoversion = true // Make sure gamemode is set up correctly + gamemode = commercial; + gamemission = strife; + isregistered = true; - if (gamemission == doom) + // Load voices.wad + if(isregistered) { - // Doom 1. But which version? + char *name = D_FindWADByName("voices.wad"); - if (W_CheckNumForName("E4M1") > 0) + if(!name) // not found? { - // Ultimate Doom + int p; - gamemode = retail; - } - else if (W_CheckNumForName("E3M1") > 0) - { - gamemode = registered; + // haleyjd STRIFE-FIXME: Temporary? + // If -iwad was used, check and see if voices.wad exists on the + // same filepath. + if((p = M_CheckParm("-iwad")) && p < myargc - 1) + { + char *iwad = myargv[p + 1]; + size_t len = strlen(iwad) + 24; + char *filename = malloc(len); + char sepchar; + + // how the heck is Choco surviving without this routine? + sepchar = M_GetFilePath(iwad, filename, len); + filename[strlen(filename)] = sepchar; + strcat(filename, "voices.wad"); + + if(!M_FileExists(filename)) + disable_voices = 1; + else + name = filename; // STRIFE-FIXME: memory leak!! + } + else + disable_voices = 1; } - else + + if(disable_voices) // voices disabled? { - gamemode = shareware; + // STRIFE-FIXME: + // if(debugmode) + printf("Voices disabled\n"); + return; } - } - else - { - // Doom 2 of some kind. - gamemode = commercial; + D_AddFile(name); } } @@ -1625,7 +1676,7 @@ void D_DoomMain (void) #endif DEH_printf("S_Init: Setting up sound.\n"); - S_Init (sfxVolume * 8, musicVolume * 8); + S_Init (sfxVolume * 8, musicVolume * 8, voiceVolume * 8); // [STRIFE]: voice DEH_printf("D_CheckNetGame: Checking network game status.\n"); D_CheckNetGame (); diff --git a/src/strife/p_dialog.c b/src/strife/p_dialog.c index 8e4b1bc1..bd32ee33 100644 --- a/src/strife/p_dialog.c +++ b/src/strife/p_dialog.c @@ -1151,7 +1151,8 @@ void P_DialogDoChoice(int choice) currentchoice = &(currentdialog->choices[choice]);
- // I_StartVoice(0); -- verify (should stop previous voice I believe)
+ I_StartVoice(NULL); // STRIFE-TODO: verify (should stop previous voice I believe)
+
// villsa 09/08/10: converted into for loop
for(i = 0; i < MDLG_MAXITEMS; i++)
{
@@ -1364,7 +1365,7 @@ void P_DialogStart(player_t *player) V_DrawPatchDirect(0, 0, W_CacheLumpNum(pic, PU_CACHE));
// get voice
- //I_StartVoice(currentdialog->voice);
+ I_StartVoice(currentdialog->voice);
// get bye text
switch(rnd)
diff --git a/src/strife/s_sound.c b/src/strife/s_sound.c index 52751e10..6a6ddd15 100644 --- a/src/strife/s_sound.c +++ b/src/strife/s_sound.c @@ -137,8 +137,9 @@ int disable_voices = 0; // Sets channels, SFX and music volume, // allocates channel buffer, sets S_sfx lookup. // - -void S_Init(int sfxVolume, int musicVolume) +// haleyjd 09/11/10: Added voice volume +// +void S_Init(int sfxVolume, int musicVolume, int voiceVolume) { int i; @@ -149,6 +150,7 @@ void S_Init(int sfxVolume, int musicVolume) S_SetSfxVolume(sfxVolume); S_SetMusicVolume(musicVolume); + S_SetVoiceVolume(voiceVolume); // Allocating the internal channels for mixing // (the maximum numer of sounds rendered @@ -257,6 +259,10 @@ void S_StopSound(mobj_t *origin) for (cnum=0 ; cnum<snd_channels ; cnum++) { + // haleyjd: do not stop voice here. + if(cnum == i_voicehandle) + continue; + if (channels[cnum].sfxinfo && channels[cnum].origin == origin) { S_StopChannel(cnum); @@ -280,7 +286,7 @@ static int S_GetChannel(mobj_t *origin, sfxinfo_t *sfxinfo, boolean isvoice) channel_t* c; // Find an open channel - for (cnum=0 ; cnum<snd_channels ; cnum++) + for (cnum=0 ; cnum<snd_channels ; cnum++) { if (!channels[cnum].sfxinfo) { @@ -495,7 +501,81 @@ void S_StartSound(void *origin_p, int sfx_id) } channels[cnum].handle = I_StartSound(sfx, cnum, volume, sep); -} +} + + +// haleyjd 09/11/10: [STRIFE] +// None of this was necessary in the vanilla EXE but Choco's low-level code +// won't play nice with a temporary sfxinfo because it insists that the +// "driver_data" member remain valid from the last time the sound was used, +// even if it has already stopped playing. Thanks to this cuteness I get +// to maintain a dynamic cache of sfxinfo objects! + +typedef struct voiceinfo_s +{ + sfxinfo_t sfx; + struct voiceinfo_s *next; // next on hash chain +} voiceinfo_t; + +#define NUMVOICECHAINS 257 + +// +// Ripped from Eternity. +// +static unsigned int S_voiceHash(const char *str) +{ + const char *c = str; + unsigned int h = 0; + + if(!str) + I_Error("S_voiceHash: cannot hash NULL string!\n"); + + // note: this needs to be case insensitive for lump names + while(*c) + { + h = 5 * h + toupper(*c); + ++c; + } + + return h;} + +static voiceinfo_t *voices[NUMVOICECHAINS]; + +// +// S_getVoice +// +// Gets an entry from the voice table, if it exists. If it does not, one will be +// created. +// +static voiceinfo_t *S_getVoice(const char *name, int lumpnum) +{ + voiceinfo_t *voice; + int hashkey = S_voiceHash(name) % NUMVOICECHAINS; + + voice = voices[hashkey]; + + while(voice && strcasecmp(voice->sfx.name, name)) + voice = voice->next; + + if(!voice) + { + voice = calloc(1, sizeof(voiceinfo_t)); + + strncpy(voice->sfx.name, name, 8); + voice->sfx.priority = INT_MIN; // make highest possible priority + voice->sfx.pitch = -1; + voice->sfx.volume = -1; + voice->sfx.numchannels = -1; + voice->sfx.usefulness = -1; + voice->sfx.lumpnum = lumpnum; + + // throw it onto the table. + voice->next = voices[hashkey]; + voices[hashkey] = voice; + } + + return voice; +} // // I_StartVoice @@ -508,14 +588,14 @@ void S_StartSound(void *origin_p, int sfx_id) // void I_StartVoice(const char *lumpname) { - static sfxinfo_t voicesfx; // a static "fake" sfxinfo for voices. int lumpnum; + voiceinfo_t *voice; // choco-specific // no voices in deathmatch mode. if(netgame) return; - // TODO: checks if sfx_SndDevice == 83 + // STRIFE-TODO: checks if snd_SfxDevice == 83 // This is probably turning off voice if using PC speaker... // user has disabled voices? @@ -523,25 +603,26 @@ void I_StartVoice(const char *lumpname) return; // have a voice playing already? stop it. - if (i_voicehandle > 0) + if (i_voicehandle >= 0) S_StopChannel(i_voicehandle); - // haleyjd: Choco-specific: initialize the voicesfx structure - memset(&voicesfx, 0, sizeof(sfxinfo_t)); - strncpy(voicesfx.name, lumpname, 8); - voicesfx.priority = INT_MIN; // make highest possible priority - voicesfx.pitch = -1; - voicesfx.volume = -1; - voicesfx.numchannels = -1; - voicesfx.usefulness = -1; + // Vanilla STRIFE appears to have stopped any current voice without + // starting a new one if NULL was passed in here, though I cannot + // find an explicit check for NULL in the assembly. Either way, it + // didn't crash, so do a check now: + if(lumpname == NULL) + return; if((lumpnum = W_CheckNumForName(lumpname)) != -1) { + // haleyjd: Choco-specific: get a voice structure + voice = S_getVoice(lumpname, lumpnum); + // get a channel for the voice - i_voicehandle = S_GetChannel(NULL, &voicesfx, true); - voicesfx.lumpnum = lumpnum; + i_voicehandle = S_GetChannel(NULL, &voice->sfx, true); + channels[i_voicehandle].handle - = I_StartSound(&voicesfx, i_voicehandle, snd_VoiceVolume, NORM_SEP); + = I_StartSound(&voice->sfx, i_voicehandle, snd_VoiceVolume, NORM_SEP); } } diff --git a/src/strife/s_sound.h b/src/strife/s_sound.h index 1cb70fa0..5e763014 100644 --- a/src/strife/s_sound.h +++ b/src/strife/s_sound.h @@ -37,7 +37,7 @@ // allocates channel buffer, sets S_sfx lookup. // -void S_Init(int sfxVolume, int musicVolume); +void S_Init(int sfxVolume, int musicVolume, int voiceVolume); // Shut down sound @@ -97,5 +97,7 @@ void S_SetVoiceVolume(int volume); // haleyjd 09/11/10: [STRIFE] extern int snd_channels; +extern int disable_voices; + #endif |