diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 23372b7ed..8270fadaf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1406,6 +1406,7 @@ static UINT8 Skin_FindValidDub(consvar_t *cvar, UINT16 skin_id, kartvoice_t *voi int i; const char *value = cvar->string; kartvoice_t *myvoice = voice; + char cvarname[VOICENAMESIZE+1]; if (!Playing()) { @@ -1424,66 +1425,43 @@ static UINT8 Skin_FindValidDub(consvar_t *cvar, UINT16 skin_id, kartvoice_t *voi } } - // First, check for freeslotted voices, should they exist at all. - if (numfreeslotvoices) + // Scan through our allocated skin voices for the wanted voice. + strncpy(cvarname, value, VOICENAMESIZE); + strupr(cvarname); + + i = DEH_FindVoice(cvarname); + + if (i != MAXSKINVOICES) { - for (i = 0; i < numfreeslotvoices; i++) + // Make sure this voice belongs to the skin we're about to assign it to. + if (skinvoices[i].parent == skin_id || forceme) { - if (strncmp(value, skinvoices[i + KSKVC_FIRSTFREESLOT].name, sizeof skinvoices[i + KSKVC_FIRSTFREESLOT].name) == 0) - { - // Make sure this voice belongs to the skin we're about to assign it to. - if (skinvoices[i + KSKVC_FIRSTFREESLOT].parent == skin_id || forceme) - { - // Change the cvar to be the value of the name. - CV_StealthSet(cvar, skinvoices[i + KSKVC_FIRSTFREESLOT].name); - cvar->value = skinvoices[i + KSKVC_FIRSTFREESLOT].id; - } - else - { - // This isn't a valid voice for this skin, so don't assign shit. - if (!silent) - CONS_Alert(CONS_NOTICE, M_GetText("Voice \"%s\" doesn't belong to this skin (%s).\n"), skinvoices[i + KSKVC_FIRSTFREESLOT].name, skins[skin_id].name); + // Change the cvar to be the value of the name. + strncpy(cvarname, DEH_VoiceName(i), VOICENAMESIZE); + strlwr(cvarname); - // *Reassign* the voice to whatever the current voice is, at least. - CV_StealthSet(cvar, myvoice->name); - cvar->value = myvoice->id; - return 1; - } - - // Return regardless, as we've found the voice we were looking for. - return 0; - } + CV_StealthSet(cvar, cvarname); + cvar->value = skinvoices[i].id; } - } - - // Freeslotted voices don't exist or found nothing; check skin voices. - for (i = 0; i < numskinvoices; i++) - { - // Whatever. Go, my code duplication! - if (strncmp(value, skinvoices[i].name, sizeof skinvoices[i].name) == 0) + else { - // Make sure this voice belongs to the skin we're about to assign it to. - if (skinvoices[i].parent == skin_id || forceme) - { - // Change the cvar to be the value of the name. - CV_StealthSet(cvar, skinvoices[i].name); - cvar->value = skinvoices[i].id; - } - else - { - // This isn't a valid voice for this skin, so don't assign shit. - if (!silent) - CONS_Alert(CONS_NOTICE, M_GetText("Voice \"%s\" doesn't belong to this skin (%s).\n"), skinvoices[i].name, skins[skin_id].name); + // This isn't a valid voice for this skin, so don't assign shit. + if (!silent) + CONS_Alert(CONS_NOTICE, M_GetText("Voice \"%s\" doesn't belong to this skin (%s).\n"), DEH_VoiceName(i), skins[skin_id].name); - // *Reassign* the voice cvar to whatever the current voice is, at least. - CV_StealthSet(cvar, myvoice->name); - cvar->value = myvoice->id; - return 1; - } + // *Reassign* the voice cvar to whatever the current voice is, at least. + strncpy(cvarname, DEH_VoiceName(myvoice->id), VOICENAMESIZE); + strlwr(cvarname); - // Return regardless, as we've found the voice we were looking for. - return 0; + CV_StealthSet(cvar, cvarname); + cvar->value = myvoice->id; + + // Signal to networking that we failed to set a voice. + return 1; } + + // We've found the voice we were looking for! + return 0; } // Found diddly-squat, say as much. @@ -1491,8 +1469,13 @@ static UINT8 Skin_FindValidDub(consvar_t *cvar, UINT16 skin_id, kartvoice_t *voi CONS_Alert(CONS_NOTICE, M_GetText("Voice \"%s\" does not exist.\n"), value); // Reassign the voice cvar to our current voice. - CV_StealthSet(cvar, myvoice->name); + strncpy(cvarname, DEH_VoiceName(myvoice->id), VOICENAMESIZE); + strlwr(cvarname); + + CV_StealthSet(cvar, cvarname); cvar->value = myvoice->id; + + // Signal to networking that we failed to set a voice. return 1; } @@ -1859,6 +1842,7 @@ static void SendNameAndColor(UINT8 n) boolean permamute = false; char buf[MAXPLAYERNAME+12]; + char voicebuf[VOICENAMESIZE+1]; char *p; if (splitscreen < n) @@ -1912,7 +1896,7 @@ static void SendNameAndColor(UINT8 n) && !strcmp(cv_skin[n].string, skins[player->skin].name) && cv_follower[n].value == player->followerskin && cv_followercolor[n].value == player->followercolor - && (!permamute && !strcmp(cv_voice[n].string, voice->name))) + && (!permamute && !stricmp(cv_voice[n].string, DEH_VoiceName(voice->id)))) return; player->availabilities = R_GetSkinAvailabilities(); @@ -1955,7 +1939,10 @@ static void SendNameAndColor(UINT8 n) // Reset the voice to that of the skin's. if (prevskin != player->skin && skins[player->skin].voice) { - CV_StealthSet(&cv_voice[n], skins[player->skin].voice->name); + strncpy(voicebuf, DEH_VoiceName(skins[player->skin].voice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)skins[player->skin].voice->id; } } @@ -1971,14 +1958,22 @@ static void SendNameAndColor(UINT8 n) // Reset the voice to that of the skin's. if (prevskin != player->skin && skins[player->skin].voice) { - CV_StealthSet(&cv_voice[n], skins[player->skin].voice->name); + strncpy(voicebuf, DEH_VoiceName(skins[player->skin].voice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)skins[player->skin].voice->id; } } // Need to update voices after the fact. if (!cv_voice[n].string) - CV_StealthSet(&cv_voice[n], skins[player->skin].voice->name); + { + strncpy(voicebuf, DEH_VoiceName(skins[player->skin].voice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); + } SetPlayerVoice(playernum, cv_voice[n].string); @@ -1986,7 +1981,10 @@ static void SendNameAndColor(UINT8 n) if (valuevoice) { - CV_StealthSet(&cv_voice[n], valuevoice->name); + strncpy(voicebuf, DEH_VoiceName(valuevoice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)valuevoice->id; } else @@ -1996,13 +1994,19 @@ static void SendNameAndColor(UINT8 n) if (valuevoice) { - CV_StealthSet(&cv_voice[n], valuevoice->name); + strncpy(voicebuf, DEH_VoiceName(valuevoice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)valuevoice->id; } else { // ...still nothing? - CV_StealthSet(&cv_voice[n], "sonic_voice"); + strncpy(voicebuf, DEH_VoiceName(0), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = 0; } } @@ -2031,7 +2035,10 @@ static void SendNameAndColor(UINT8 n) if (Skin_FindValidDub(&cv_voice[n], cv_skin[n].value, voice, false, true)) { // Our voice is no longer valid, set it to that of our skin's. - CV_StealthSet(&cv_voice[n], skins[player->skin].voice->name); + strncpy(voicebuf, DEH_VoiceName(skins[player->skin].voice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = skins[player->skin].voice->id; } } @@ -2050,7 +2057,12 @@ static void SendNameAndColor(UINT8 n) // Need to update voices after the fact. if (!cv_voice[n].string) - CV_StealthSet(&cv_voice[n], skins[player->skin].voice->name); + { + strncpy(voicebuf, DEH_VoiceName(skins[player->skin].voice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); + } if (!permamute) { @@ -2062,7 +2074,10 @@ static void SendNameAndColor(UINT8 n) if (valuevoice && valuevoice->parent == cv_skin[n].value) { - CV_StealthSet(&cv_voice[n], valuevoice->name); + strncpy(voicebuf, DEH_VoiceName(valuevoice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)valuevoice->id; } else @@ -2072,13 +2087,19 @@ static void SendNameAndColor(UINT8 n) if (valuevoice) { - CV_StealthSet(&cv_voice[n], valuevoice->name); + strncpy(voicebuf, DEH_VoiceName(valuevoice->id), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = (UINT16)valuevoice->id; } else { // ...still nothing? - CV_StealthSet(&cv_voice[n], "sonic_voice"); + strncpy(voicebuf, DEH_VoiceName(0), VOICENAMESIZE); + strlwr(voicebuf); + + CV_StealthSet(&cv_voice[n], voicebuf); cv_voice[n].value = 0; } } @@ -2101,6 +2122,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { player_t *p = &players[playernum]; char name[MAXPLAYERNAME+1]; + char voicename[VOICENAMESIZE+1]; UINT16 color, followercolor; UINT16 skin, voice; SINT8 follower; @@ -2212,7 +2234,10 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { CV_StealthSet(&cv_skin[localplayer], skins[forcedskin].name); - CV_StealthSet(&cv_voice[localplayer], skins[forcedskin].voice->name); + strncpy(voicename, DEH_VoiceName(skins[forcedskin].voice->id), VOICENAMESIZE); + strlwr(voicename); + + CV_StealthSet(&cv_voice[localplayer], voicename); cv_voice[localplayer].value = skins[forcedskin].voice->id; } @@ -2228,7 +2253,10 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) if (localplayer != -1) { - CV_StealthSet(&cv_voice[localplayer], skinvoices[voice].name); + strncpy(voicename, DEH_VoiceName(voice), VOICENAMESIZE); + strlwr(voicename); + + CV_StealthSet(&cv_voice[localplayer], voicename); cv_voice[localplayer].value = skinvoices[voice].id; } } @@ -7472,6 +7500,8 @@ static void Color4_OnChange(void) static void __voice_cvar_func(INT32 pid, UINT8 pnum) { + char cvarname[VOICENAMESIZE+1]; + kartvoice_t *myvoice = P_GetMobjVoice(players[pid].mo); if (!myvoice) @@ -7498,7 +7528,11 @@ static void __voice_cvar_func(INT32 pid, UINT8 pnum) if (!(cht_debug || devparm) && !(multiplayer || netgame) // In single player. && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y { - CV_StealthSet(&cv_voice[pnum], myvoice->name); + strncpy(cvarname, DEH_VoiceName(myvoice->id), VOICENAMESIZE); + strlwr(cvarname); + CV_StealthSet(&cv_voice[pnum], cvarname); + + cv_voice[pnum].value = myvoice->id; return; } } @@ -7508,7 +7542,12 @@ static void __voice_cvar_func(INT32 pid, UINT8 pnum) else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your voice at the moment.\n")); - CV_StealthSet(&cv_voice[pnum], myvoice->name); + + strncpy(cvarname, DEH_VoiceName(myvoice->id), VOICENAMESIZE); + strlwr(cvarname); + CV_StealthSet(&cv_voice[pnum], cvarname); + + cv_voice[pnum].value = myvoice->id; } } diff --git a/src/deh_soc.c b/src/deh_soc.c index dfbf19e01..fcba24275 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -4316,23 +4316,7 @@ void readkartvoice(MYFILE *f, kartvoice_t *voice) word2 = (tmp += 2); strupr(word2); - if (fastcmp(word, "NAME")) - { - strlwr(word2); - // Catch any voices with similar names. - for (i = KSKVC_FIRSTFREESLOT; i < MAXSKINVOICES; i++) - { - if (strnicmp(word2, skinvoices[i].name, sizeof skinvoices[i].name) == 0) - { - // Name collision! - // Append the ID to differentiate... poorly. - snprintf(word2, sizeof voice->name, "%u_%s", voice->id, skinvoices[i].name); - } - } - strncpy(voice->name, word2, sizeof voice->name); - CONS_Printf("KartVoice %s: renamed to \"%s\"\n", strbuf_get(voicenames, voice->info.nameofs), voice->name); - } - else if (fastcmp(word, "SKIN")) + if (fastcmp(word, "SKIN")) { i = R_SkinAvailable(word2); @@ -4395,6 +4379,9 @@ void readkartvoice(MYFILE *f, kartvoice_t *voice) } while (!myfeof(f)); // finish when the line is empty + // Set our ID afterwards. + voice->id = (UINT32)(voice - skinvoices); + Z_Free(s); } @@ -4587,7 +4574,7 @@ kartvoicetype_e get_kartvoice(const char *word) if (fastncmp("KVOICE_",word,7)) word += 7; // take off the KVOICE_ i = DEH_FindVoice(word); - if (i == MAXVOICEFREESLOTS) + if (i == MAXSKINVOICES) deh_warning("Couldn't find voice named 'KVOICE_%s'", word); return i; } diff --git a/src/deh_tables.c b/src/deh_tables.c index cb90f9467..c05fe3036 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -71,7 +71,7 @@ const char *DEH_KartItemName(kartitemtype_e i) const char *DEH_VoiceName(kartvoicetype_e i) { - return strbuf_get(voicenames, skinvoices[i + KSKVC_FIRSTFREESLOT].info.nameofs); + return strbuf_get(voicenames, skinvoices[i].info.nameofs); } mobjtype_t DEH_FindMobjtype(const char *word) @@ -143,13 +143,13 @@ kartvoicetype_e DEH_FindVoice(const char *word) { INT32 i; UINT32 hash = HASH32(word, strlen(word)); - for (i = 0; i < numfreeslotvoices; i++) { - if (hash != skinvoices[i + KSKVC_FIRSTFREESLOT].info.namehash) + for (i = 0; i < numskinvoices; i++) { + if (hash != skinvoices[i].info.namehash) continue; if (fastcmp(word, DEH_VoiceName(i))) return (kartvoicetype_e)i; } - return MAXVOICEFREESLOTS; + return MAXSKINVOICES; } struct flickytypes_s FLICKYTYPES[] = { diff --git a/src/dehacked.c b/src/dehacked.c index 029813a96..6cdb8db65 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -393,19 +393,7 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out) } else if (fastcmp(type, "KVOICE")) { - *out = DEH_FindVoice(word); - if (*out != MAXVOICEFREESLOTS) - return 0; // already allocated - - if (numfreeslotvoices == MAXVOICEFREESLOTS) { - CONS_Alert(CONS_WARNING, "Ran out of free voice slots!\n"); - return -1; - } - CONS_Printf("Voice KVOICE_%s allocated.\n",word); - DEH_Link(word, &skinvoices[numfreeslotvoices + KSKVC_FIRSTFREESLOT].info, &voicenames); - skinvoices[numfreeslotvoices + KSKVC_FIRSTFREESLOT].id = numfreeslotvoices + KSKVC_FIRSTFREESLOT; - *out = numfreeslotvoices++; - return 0; + return R_AllocVoice(false, word, out); } return -2; @@ -806,12 +794,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_kartvoice(word2); // find a voice by name - if ((i + 1) >= 1 && i < numfreeslotvoices) - readkartvoice(f, &skinvoices[i + KSKVC_FIRSTFREESLOT]); + if ((i + 1) >= 1 && i < numskinvoices) + readkartvoice(f, &skinvoices[i]); else { // zero-based, but let's start at 1 - deh_warning("KartVoice number %d out of range (1 - %d)", i, numfreeslotvoices); + deh_warning("KartVoice number %d out of range (1 - %d)", i, numskinvoices); ignorelines(f); } } diff --git a/src/g_demo.c b/src/g_demo.c index ba791ebb1..9fba3164a 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -41,6 +41,7 @@ #include "lua_hook.h" #include "p_saveg.h" // savebuffer_t #include "g_party.h" +#include "deh_tables.h" // SRB2Kart #include "d_netfil.h" // nameonly @@ -54,7 +55,7 @@ #include "k_color.h" #include "k_follower.h" #include "k_grandprix.h" -#include "strbuf.h" +//#include "strbuf.h" static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}}; consvar_t cv_recordmultiplayerdemos = CVAR_INIT ("netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL); @@ -1395,7 +1396,7 @@ void G_WriteDemoExtraData(void) WRITESTRINGL(demobuf.p, skins[players[i].skin].name, 16+1); // Voice - WRITESTRINGL(demobuf.p, skinvoices[players[i].voice_id].name, 32+1); + WRITESTRINGL(demobuf.p, DEH_VoiceName(players[i].voice_id), 32+1); // Stats WRITEUINT8(demobuf.p, skins[players[i].skin].kartspeed); @@ -2982,7 +2983,7 @@ void G_BeginRecording(void) WRITESTRINGL(demobuf.p, skincolors[player->skincolor].name, 16+1); // Voice - WRITESTRINGL(demobuf.p, skinvoices[player->voice_id].name, 32+1); + WRITESTRINGL(demobuf.p, DEH_VoiceName(player->voice_id), 32+1); // Save follower's skin name // PS: We must check for 'follower' to determine if the followerskin is valid. It's going to be 0 if we don't have a follower, but 0 is also absolutely a valid follower! diff --git a/src/info.c b/src/info.c index 827fb8eb9..438a56d3c 100644 --- a/src/info.c +++ b/src/info.c @@ -262,12 +262,12 @@ void P_ResetData(INT32 flags) // voices if (init) { - for (i = KSKVC_FIRSTFREESLOT; i < MAXSKINVOICES; i++) + for (i = 0; i < MAXSKINVOICES; i++) { R_ClearVoice(i); } - numfreeslotvoices = 0; + numskinvoices = 0; if (voicenames) Z_Free(voicenames); diff --git a/src/lua_voicelib.c b/src/lua_voicelib.c index dae6edf1b..2b9a7d5a1 100644 --- a/src/lua_voicelib.c +++ b/src/lua_voicelib.c @@ -16,6 +16,7 @@ #include "fastcmp.h" #include "r_skins.h" #include "sounds.h" +#include "deh_tables.h" #include "lua_script.h" #include "lua_libs.h" @@ -23,7 +24,7 @@ enum voicevars { voicevars_id = 0, - voicevars_name, + voicevars_name, // Not actually in kartvoice_t; returns the name of the voice voicevars_parent, voicevars_parentname, // Not actually in kartvoice_t; returns the name of the parent skin voicevars_win, @@ -70,7 +71,7 @@ static int voice_get(lua_State* L) lua_pushinteger(L, voice->id); break; case voicevars_name: - lua_pushstring(L, voice->name); + lua_pushstring(L, DEH_VoiceName((kartvoicetype_e)(voice - skinvoices))); break; case voicevars_parent: lua_pushinteger(L, voice->parent); @@ -170,16 +171,7 @@ static int lib_iterateVoices(lua_State* L) i = 0; // voices are always valid, only added, never removed - if (i >= KSKVC_MAXVANILLA) - { - // Check freeslotted voices. - if ((i - KSKVC_MAXVANILLA) < numfreeslotvoices) - { - LUA_PushUserdata(L, &skinvoices[i], META_VOICE); - return 1; - } - } - else if (i < numskinvoices) + if (i < numskinvoices) { LUA_PushUserdata(L, &skinvoices[i], META_VOICE); return 1; @@ -202,14 +194,6 @@ static int lib_getVoice(lua_State* L) return luaL_error( L, "skinvoices[] index %d out of range (0 - %d)", i, MAXSKINVOICES - 1); } - if (i >= KSKVC_MAXVANILLA) - { - // Check freeslotted voices. - if ((i - KSKVC_MAXVANILLA) >= numfreeslotvoices) - { - return 0; - } - } else if (i >= numskinvoices) { return 0; @@ -228,19 +212,6 @@ static int lib_getVoice(lua_State* L) return 1; } - // Special functions for getting voice counts per individual table. - if (fastcmp(field, "basevoices")) - { - lua_pushinteger(L, numskinvoices); - return 1; - } - - if (fastcmp(field, "freeslotvoices")) - { - lua_pushinteger(L, numfreeslotvoices); - return 1; - } - // find voice by name // Glad I made a function for this... i = R_FindIDForVoice(field); @@ -258,7 +229,7 @@ static int lib_getVoice(lua_State* L) // In this case: returns TOTAL voices, and not individual table counts. static int lib_numVoices(lua_State* L) { - lua_pushinteger(L, numskinvoices + numfreeslotvoices); + lua_pushinteger(L, numskinvoices); return 1; } diff --git a/src/r_skins.c b/src/r_skins.c index 4c8443f92..2957c9f5b 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -28,6 +28,7 @@ #include "dehacked.h" // get_number (for thok) #include "m_cond.h" #include "d_main.h" // MAINWAD_CHARS +#include "deh_tables.h" // Voice freeslotting #if 0 #include "k_kart.h" // K_KartResetPlayerColor #endif @@ -40,7 +41,6 @@ INT32 numskins = 0; INT32 numskinvoices = 0; -INT32 numfreeslotvoices = 0; skin_t skins[MAXSKINS]; INT32 skinsorted[MAXSKINS]; kartvoice_t skinvoices[MAXSKINVOICES]; @@ -344,10 +344,6 @@ static void Sk_SetDefaultValue(skin_t *skin, kartvoice_t *skin_voice) } // TODO: Make this hexadecimal - snprintf(skin_voice->name, - sizeof skin_voice->name, "voice %u", (UINT32)(skin_voice-skinvoices)); - skin_voice->name[sizeof skin_voice->name - 1] = '\0'; - skin_voice->parent = (UINT16)(skin - skins); skin_voice->id = skin_voice-skinvoices; @@ -725,27 +721,14 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) kartvoicetype_e R_FindIDForVoice(const char* voicename) { INT32 i; + const char *checkvoicename; - // First, check for freeslotted voices, should they exist at all. - if (numfreeslotvoices) - { - for (i = 0; i < numfreeslotvoices; i++) - { - if (strncmp(voicename, - skinvoices[i + KSKVC_FIRSTFREESLOT].name, - sizeof skinvoices[i + KSKVC_FIRSTFREESLOT].name) == 0) - { - // Found a voice. - return (kartvoicetype_e)(i + KSKVC_FIRSTFREESLOT); - } - } - } - - // Freeslotted voices don't exist, or we've found nothing; check skin voices. + // Scan through our allocated skin voices for the wanted voice. for (i = 0; i < numskinvoices; i++) { // Whatever. Go, my code duplication! - if (strncmp(voicename, skinvoices[i].name, sizeof skinvoices[i].name) == 0) + checkvoicename = DEH_VoiceName(i); + if (strnicmp(voicename, checkvoicename, VOICENAMESIZE) == 0) { // Found a voice. return (kartvoicetype_e)i; @@ -760,20 +743,7 @@ static kartvoicetype_e R_FindIDForVoiceNum(UINT16 voicenum) { INT32 i; - // First, check for freeslotted voices, should they exist at all. - if (numfreeslotvoices) - { - for (i = 0; i < numfreeslotvoices; i++) - { - if (skinvoices[i + KSKVC_FIRSTFREESLOT].id == voicenum) - { - // Found a voice. - return (kartvoicetype_e)(i + KSKVC_FIRSTFREESLOT); - } - } - } - - // Freeslotted voices don't exist, or we've found nothing; check skin voices. + // Scan through our allocated skin voices for the wanted voice. for (i = 0; i < numskinvoices; i++) { // Whatever. Go, my code duplication! @@ -815,7 +785,8 @@ void SetPlayerVoice(INT32 playernum, const char* voicename) const kartvoice_t* myvoice = P_GetMobjVoice(player->mo); - if (!strncmp(voicename, myvoice->name, sizeof myvoice->name)) + const char* myvoicename = DEH_VoiceName(myvoice->id); + if (!strnicmp(voicename, myvoicename, VOICENAMESIZE)) { // Hey... this voice is the same as before! // WAIT! Before we go, reset the player's voice ID! @@ -1109,10 +1080,16 @@ static void R_IHateThatHedgehog(UINT16 wadnum) Sk_SetDefaultValue(skin, skin_voice); skin->wadnum = wadnum; strcpy(skin->name, "sonic"); - - strcpy(skin->voice->name, "sonic_voice"); skin->voice->parent = 0; + // Add voice + INT32 dummy; + if (R_AllocVoice(true, skin->name, &dummy) < 0) + { + // Hey guy, take care! + I_Error("Failed to allocate initial skin voice\n"); + } + #ifdef SKINVALUES skin_cons_t[0].value = 0; skin_cons_t[0].strvalue = skin->name; @@ -1288,6 +1265,33 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) return true; } +// +// Allocates a voice onto the dehacked list, and iterates the provided output pointer +// (should it exist). +// +INT32 R_AllocVoice(boolean skinalloc, const char* name, INT32 *out) +{ + char voxname_upper[VOICENAMESIZE]; + + strncpy(voxname_upper, name, VOICENAMESIZE); + strupr(voxname_upper); + + *out = DEH_FindVoice(voxname_upper); + if (*out != MAXSKINVOICES) + return skinalloc ? -1 : 0; // already allocated + + if (numskinvoices == MAXSKINVOICES - 1) { + CONS_Alert(CONS_WARNING, "Ran out of free voice slots!\n"); + return -1; + } + + CONS_Printf("Voice KVOICE_%s allocated.\n",voxname_upper); + DEH_Link(voxname_upper, &skinvoices[numskinvoices].info, &voicenames); + + *out = numskinvoices++; + return 0; +} + // // Find skin sprites, sounds & optional status bar face, & add them // @@ -1330,7 +1334,7 @@ void R_AddSkins(UINT16 wadnum) // set defaults skin = &skins[numskins]; - skin_voice = &skinvoices[numskins]; + skin_voice = &skinvoices[numskinvoices]; Sk_SetDefaultValue(skin, skin_voice); skin->wadnum = wadnum; realname = false; @@ -1360,7 +1364,6 @@ void R_AddSkins(UINT16 wadnum) if (skinnum == -1) { STRBUFCPY(skin->name, value); - STRBUFCPY(skin->voice->name, va("%s_voice", value)); skin->voice->parent = (UINT16)(skin - skins); } // the skin name must uniquely identify a single skin @@ -1379,7 +1382,6 @@ void R_AddSkins(UINT16 wadnum) // I'm lazy so if NEW name is already used I leave the 'skin x' // default skin name set in Sk_SetDefaultValue STRBUFCPY(skin->name, value2); - STRBUFCPY(skin->voice->name, va("%s_voice", value2)); skin->voice->parent = (UINT16)(skin - skins); } Z_Free(value2); @@ -1405,6 +1407,18 @@ void R_AddSkins(UINT16 wadnum) } free(buf2); + // Add voice + INT32 dummy; + if (R_AllocVoice(true, skin->name, &dummy) < 0) + { + // We couldn't allocate our own skin's voice?! + I_Error("Failed to allocate voice for skin %s\n", skin->name); + } + else + { + CONS_Printf(M_GetText("%d voices allocated.\n"), numskinvoices); + } + // Add sprites R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); //ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere @@ -1431,7 +1445,6 @@ void R_AddSkins(UINT16 wadnum) skinsorted[numskins] = numskins; numskins++; - numskinvoices++; } SortSkins(); return; diff --git a/src/r_skins.h b/src/r_skins.h index f41bf6a6b..eb69d950e 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -52,10 +52,9 @@ struct kartvoice_t { UINT32 id; + // Dehacked info for the voice's name (hash and pointer within the voicenames array). dehinfo_t info; - char name[VOICENAMESIZE+1]; // INT16 descriptive name of the voice. - // UINT16 ID of the parent skin this voice belongs to. // Checked when the voice is assigned to prevent erroneous dubs. UINT16 parent; @@ -131,7 +130,7 @@ enum skinmenusortoption }; /// Externs -extern INT32 numskins, numskinvoices, numfreeslotvoices; +extern INT32 numskins, numskinvoices; extern skin_t skins[MAXSKINS]; extern INT32 skinsorted[MAXSKINS]; extern kartvoice_t skinvoices[MAXSKINVOICES]; @@ -156,6 +155,7 @@ void R_AddSkins(UINT16 wadnum); UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); UINT8 P_KartFrameToSprite2(skin_t *skin, UINT8 inframe, UINT8 *outframe); +INT32 R_AllocVoice(boolean skinalloc, const char* name, INT32 *out); void R_ClearVoice(kartvoicetype_e voicetype); void Sk_SetSkinVoiceValue(kartvoice_t *voice, INT32 skinsound, INT32 writesound);