diff --git a/ci/ubuntu-buildgen.sh b/ci/ubuntu-buildgen.sh index f4f03a89f..c487261c3 100644 --- a/ci/ubuntu-buildgen.sh +++ b/ci/ubuntu-buildgen.sh @@ -11,10 +11,10 @@ set -x sudo apt update if [[ -z ${USE_SDL12:-} ]]; then sudo apt install ninja-build libsdl2-dev libsdl2-mixer-dev \ - libcurl4-openssl-dev libwxgtk3.2-dev deutex + libcurl4-openssl-dev libpng-dev libwxgtk3.2-dev deutex else sudo apt install ninja-build libsdl1.2-dev libsdl-mixer1.2-dev \ - libcurl4-openssl-dev libwxgtk3.2-dev deutex + libcurl4-openssl-dev libpng-dev libwxgtk3.2-dev deutex fi # Generate build diff --git a/client/src/d_main.cpp b/client/src/d_main.cpp index 6be17b25e..a54681bd0 100644 --- a/client/src/d_main.cpp +++ b/client/src/d_main.cpp @@ -777,6 +777,7 @@ void D_DoomMain() D_Initialize_States(boomstates, ::NUMSTATES); D_Initialize_Mobjinfo(doom_mobjinfo, ::NUMMOBJTYPES); D_Initialize_sprnames(doom_sprnames, ::NUMSPRITES, SPR_TROO); + D_Initialize_SoundMap(doom_SoundMap, ARRAY_LENGTH(doom_SoundMap)); // Initialize all extra frames D_Init_Nightmare_Flags(); // Initialize the odamex specific objects diff --git a/common/d_dehacked.cpp b/common/d_dehacked.cpp index c6e36f9ad..aa9d9f729 100644 --- a/common/d_dehacked.cpp +++ b/common/d_dehacked.cpp @@ -405,6 +405,7 @@ struct Key static int PatchThing(int); static int PatchSound(int); +static int PatchSounds(int); static int PatchFrame(int); static int PatchSprite(int); static int PatchSprites(int); @@ -443,12 +444,31 @@ static const struct {"[STRINGS]", PatchStrings}, {"[PARS]", PatchPars}, {"[CODEPTR]", PatchCodePtrs}, - {"[SPRITES]", PatchSprites}, // Eternity engine added a few more features to BEX {"[MUSIC]", PatchMusic}, + // DSDHacked BEX additions + {"[SPRITES]", PatchSprites}, + {"[SOUNDS]", PatchSounds}, {NULL, NULL}, }; +DoomObjectContainer SoundMap(ARRAY_LENGTH(doom_SoundMap)); + +void D_Initialize_SoundMap(const char** source, int count) +{ + SoundMap.clear(); + if (source) + { + for (int i = 0; i < count; i++) + { + SoundMap.insert(source[i] ? strdup(source[i]) : NULL, i); + } + } +#if defined _DEBUG + Printf(PRINT_HIGH, "D_Allocate_sounds:: allocated %d sounds.\n", count); +#endif +} + static int HandleMode(const char* mode, int num); static BOOL HandleKey(const struct Key* keys, void* structure, const char* key, int value, const int structsize = 0); @@ -530,6 +550,7 @@ typedef struct DoomObjectContainer backupStates; // boomstates DoomObjectContainer backupMobjInfo; // doom_mobjinfo DoomObjectContainer backupSprnames; // doom_sprnames + DoomObjectContainer backupSoundMap; // doom_SoundMap weaponinfo_t backupWeaponInfo[NUMWEAPONS + 1]; int backupMaxAmmo[NUMAMMO]; int backupClipAmmo[NUMAMMO]; @@ -542,6 +563,7 @@ DoomBackup doomBackup; typedef DoomObjectContainer::const_iterator StatesIterator; typedef DoomObjectContainer::const_iterator MobjIterator; typedef DoomObjectContainer::const_iterator SpriteNamesIterator; +typedef DoomObjectContainer::const_iterator SoundMapIterator; static void BackupData(void) { @@ -593,6 +615,15 @@ static void BackupData(void) doomBackup.backupSprnames.insert(spr, it.first); } + // sounds + doomBackup.backupSoundMap.resize(ARRAY_LENGTH(doom_SoundMap)); + doomBackup.backupSoundMap.clear(); + for(const std::pair & it : SoundMap) + { + const char* sound = strdup(it.second); + doomBackup.backupSoundMap.insert(sound, it.first); + } + std::copy(weaponinfo, weaponinfo + ::NUMWEAPONS + 1, doomBackup.backupWeaponInfo); std::copy(clipammo, clipammo + ::NUMAMMO, doomBackup.backupClipAmmo); std::copy(maxammo, maxammo + ::NUMAMMO, doomBackup.backupMaxAmmo); @@ -626,7 +657,8 @@ void D_UndoDehPatch() D_Initialize_sprnames(doomBackup.backupSprnames.data(), ::NUMSPRITES, SPR_TROO); D_Initialize_States(doomBackup.backupStates.data(), ::NUMSTATES); D_Initialize_Mobjinfo(doomBackup.backupMobjInfo.data(), ::NUMMOBJTYPES); - + D_Initialize_SoundMap(doomBackup.backupSoundMap.data(), ARRAY_LENGTH(doom_SoundMap)); + extern bool isFast; isFast = false; @@ -1034,7 +1066,6 @@ static int PatchThing(int thingy) m.meleerange = MELEERANGE; m.translucency = 0x10000; m.altspeed = NO_ALTSPEED; - m.ripsound = ""; return m; }; mobjinfo_t* mobj = (mobjinfo_t*) M_Calloc(1, sizeof(mobjinfo_t)); @@ -1052,13 +1083,6 @@ static int PatchThing(int thingy) while ((result = GetLine()) == 1) { - size_t sndmap = atoi(Line2); - - if (sndmap >= ARRAY_LENGTH(SoundMap)) - { - sndmap = 0; - } - size_t val = atoi(Line2); int linelen = strlen(Line1); @@ -1103,12 +1127,17 @@ static int PatchThing(int thingy) { char* snd; - if (val == 0 || val >= ARRAY_LENGTH(SoundMap)) + // If sound is not yet in SoundMap, store the index to be used in PatchSounds + auto soundIt = SoundMap.find(val); + if (soundIt == SoundMap.end()) { - val = 0; + snd = Line2; + stripwhite(snd); + } + else + { + snd = (char*)soundIt->second; } - - snd = (char*)SoundMap[val]; if (!strnicmp(Line1, "Alert", 5)) { @@ -1572,7 +1601,7 @@ static int PatchFrame(int frameNum) {NULL, 0}}; int result; state_t *info, dummy; - + static const struct { short Bit; @@ -1814,6 +1843,56 @@ static int PatchSprites(int dummy) return result; } +void IdxToSoundName(const char* sound) +{ + if (sound && sound[0] && IsNum(sound)) + { + auto soundIt = SoundMap.find(atoi(sound)); + sound = soundIt == SoundMap.end() ? nullptr : (char*)soundIt->second; + } +} + +static int PatchSounds(int dummy) +{ + int result; +#if defined _DEBUG + DPrintf("[Sounds]\n"); +#endif + while ((result = GetLine()) == 1) + { + char* newname = Line2; + stripwhite(newname); + OLumpName newnameds = fmt::sprintf("DS%s", newname); + + if (IsNum(Line1)) + { + int32_t soundIdx = atoi(Line1); + SoundMap.insert(strdup(newname), soundIdx); + S_AddSound(newname, newnameds.c_str()); + } + else + { + int lumpnum = W_CheckNumForName(fmt::sprintf("DS%s", Line1).c_str()); + int sndIdx = S_FindSoundByLump(lumpnum); + if (sndIdx == -1) + I_Error("Sound %s not found.", Line1); + S_AddSound(S_sfx[sndIdx].name, newnameds.c_str()); + } + } + for (auto& pair : mobjinfo) + { + auto& info = pair.second; + IdxToSoundName(info->seesound); + IdxToSoundName(info->attacksound); + IdxToSoundName(info->painsound); + IdxToSoundName(info->deathsound); + IdxToSoundName(info->activesound); + IdxToSoundName(info->ripsound); + } + S_HashSounds(); + return result; +} + static int PatchAmmo(int ammoNum) { extern int clipammo[NUMAMMO]; @@ -2704,7 +2783,7 @@ bool CheckIfDehActorDefined(const mobjtype_t mobjtype) if (mobj.doomednum == -1 && mobj.spawnstate == S_TNT1 && mobj.spawnhealth == 0 && - mobj.gibhealth == 0 && + mobj.gibhealth == 0 && mobj.seestate == S_NULL && mobj.seesound == NULL && mobj.reactiontime == 0 && @@ -2782,7 +2861,7 @@ static void PrintMobjinfo(int index) { return; } - + mobjinfo_t* mob = it->second; std::stringstream ss; ss << "%4d | "; @@ -2815,7 +2894,7 @@ BEGIN_COMMAND(mobinfo) Printf("Must pass one or two mobjinfo indexes. (0 to %d)\n", ::num_mobjinfo_types() - 1); return; } - + int index1 = atoi(argv[1]); if (mobjinfo.find(index1) == mobjinfo.end()) { @@ -2823,7 +2902,7 @@ BEGIN_COMMAND(mobinfo) return; } int index2 = index1; - + if (argc == 3) { index2 = atoi(argv[2]); @@ -2833,12 +2912,12 @@ BEGIN_COMMAND(mobinfo) return; } } - + if (index2 < index1) { std::swap(index1, index2); } - + for(int i = index1; i <= index2; i++) { PrintMobjinfo(i); diff --git a/common/d_dehacked.h b/common/d_dehacked.h index 394352e68..c979977ed 100644 --- a/common/d_dehacked.h +++ b/common/d_dehacked.h @@ -28,7 +28,7 @@ // Sound equivalences. When a patch tries to change a sound, // use these sound names. -static const char* SoundMap[] = { NULL, +static const char* doom_SoundMap[] = {NULL, "weapons/pistol", "weapons/shotgf", "weapons/shotgr", @@ -223,7 +223,10 @@ static const char* SoundMap[] = { NULL, // ZDOOM-Specific sounds "misc/teamchat"}; +extern DoomObjectContainer SoundMap; + void D_UndoDehPatch(); void D_PostProcessDeh(); bool D_DoDehPatch(const OResFile* patchfile, const int lump); bool CheckIfDehActorDefined(const mobjtype_t mobjtype); +void D_Initialize_SoundMap(const char** source, int count); diff --git a/common/p_enemy.cpp b/common/p_enemy.cpp index c730fe58f..fb4bd0b14 100644 --- a/common/p_enemy.cpp +++ b/common/p_enemy.cpp @@ -3103,14 +3103,20 @@ void A_PlaySound(AActor* mo) // Play the sound from the SoundMap int sndmap = mo->state->misc1; + char* snd; - if (sndmap >= static_cast(ARRAY_LENGTH(SoundMap))) + auto soundIt = SoundMap.find(sndmap); + if (soundIt == SoundMap.end()) { DPrintf("Warning: Sound ID is beyond the array of the Sound Map!\n"); - sndmap = 0; + snd = nullptr; + } + else + { + snd = (char*)soundIt->second; } - S_Sound(mo, CHAN_BODY, SoundMap[sndmap], 1, + S_Sound(mo, CHAN_BODY, snd, 1, (mo->state->misc2 ? ATTN_NONE : ATTN_NORM)); } diff --git a/common/p_pspr.cpp b/common/p_pspr.cpp index a0cf797a9..352d63993 100644 --- a/common/p_pspr.cpp +++ b/common/p_pspr.cpp @@ -1091,10 +1091,17 @@ void A_WeaponMeleeAttack(AActor* mo) hitsound = psp->state->args[3]; range = psp->state->args[4]; - if (hitsound >= static_cast(ARRAY_LENGTH(SoundMap))) + char* snd; + + auto soundIt = SoundMap.find(hitsound); + if (soundIt == SoundMap.end()) { DPrintf("Warning: Weapon Melee Hitsound ID is beyond the array of the Sound Map!\n"); - hitsound = 0; + snd = nullptr; + } + else + { + snd = (char*)soundIt->second; } if (range <= 0) @@ -1123,7 +1130,7 @@ void A_WeaponMeleeAttack(AActor* mo) return; // un-missed! - UV_SoundAvoidPlayer(player->mo, CHAN_WEAPON, SoundMap[hitsound], + UV_SoundAvoidPlayer(player->mo, CHAN_WEAPON, snd, ATTN_NORM); // turn to face target @@ -1146,14 +1153,20 @@ void A_WeaponSound(AActor *mo) return; int sndmap = psp->state->args[0]; + char* snd; - if (sndmap >= static_cast(ARRAY_LENGTH(SoundMap))) + auto soundIt = SoundMap.find(sndmap); + if (soundIt == SoundMap.end()) + { + DPrintf("Warning: Weapon sound ID is beyond the array of the Sound Map!\n"); + snd = nullptr; + } + else { - DPrintf("Warning: Weapon Sound ID is beyond the array of the Sound Map!\n"); - sndmap = 0; + snd = (char*)soundIt->second; } - UV_SoundAvoidPlayer(player->mo, CHAN_WEAPON, SoundMap[sndmap], + UV_SoundAvoidPlayer(player->mo, CHAN_WEAPON, snd, (psp->state->args[1] ? ATTN_NONE : ATTN_NORM)); } diff --git a/server/src/d_main.cpp b/server/src/d_main.cpp index faf55b83b..bb1bdc91f 100644 --- a/server/src/d_main.cpp +++ b/server/src/d_main.cpp @@ -202,7 +202,7 @@ void STACK_ARGS D_Shutdown() // stop sound effects and music S_Stop(); - + DThinker::DestroyAllThinkers(); D_UndoDehPatch(); @@ -217,7 +217,7 @@ void STACK_ARGS D_Shutdown() // [AM] Level is now invalid due to torching zone memory. g_ValidLevel = false; - + // [AM] All of our dyncolormaps are freed, tidy up so we // don't follow wild pointers. NormalLight.next = NULL; @@ -244,6 +244,7 @@ void D_DoomMain() D_Initialize_States(boomstates, ::NUMSTATES); D_Initialize_Mobjinfo(doom_mobjinfo, ::NUMMOBJTYPES); D_Initialize_sprnames(doom_sprnames, ::NUMSPRITES, SPR_TROO); + D_Initialize_SoundMap(doom_SoundMap, ARRAY_LENGTH(doom_SoundMap)); // Initialize all extra frames D_Init_Nightmare_Flags(); // Initialize the odamex specific objects @@ -387,7 +388,7 @@ void D_DoomMain() startmap = Args.GetArg(p + 1); ((char*)Args.GetArg(p))[0] = '-'; } - + level.mapname = startmap; G_ChangeMap();