fabiangreffrath / crispy-doom

Crispy Doom is a limit-removing enhanced-resolution Doom source port based on Chocolate Doom.
https://fabiangreffrath.github.io/crispy-homepage
GNU General Public License v2.0
793 stars 130 forks source link

Play music tracks under specific lump names in TNT and Plutonia #426

Closed SoDOOManiac closed 5 years ago

SoDOOManiac commented 5 years ago

DoomMetalVol5.wad now includes music tracks for TNT and Plutonia, the track lumps have specific names, and recognising these names for loaded lumps should play them in certain maps:

TNT:

Map # | TNT track name | DoomMetalVol5 track name MAP01 | D_RUNNIN | D_SADIST MAP02 | D_STALKS | D_BURN MAP03 | D_COUNTD | D_AIM MAP04 | D_BETWEE | D_BELLS MAP05 | D_DOOM | D_MORE MAP06 | D_THE_DA | D_AGONY MAP07 | D_SHAWN | D_CHAOS MAP08 | D_DDTBLU | D_BEAST MAP09 | D_IN_CIT | D_SADIST MAP10 | D_DEAD | D_INFINI MAP11 | D_STLKS2 | D_KILL MAP12 | D_THEDA2 | D_CHAOS MAP13 | D_DOOM2 | D_BELLS MAP14 | D_DDTBL2 | D_COLD MAP15 | D_RUNNI2 | D_BURN2 MAP16 | D_DEAD2 | D_BLOOD MAP17 | D_STLKS3 | D_MORE MAP18 | D_ROMERO | D_INFINI MAP19 | D_SHAWN2 | D_CHAOS MAP20 | D_MESSAG | D_HORIZO MAP21 | D_COUNT2 | D_BLOOD MAP22 | D_DDTBL3 | D_COLD MAP23 | D_AMPIE | D_AIM MAP24 | D_THEDA3 | D_MORE MAP25 | D_ADRIAN | D_BELLS MAP26 | D_MESSG2 | D_BLOOD MAP27 | D_ROMER2 | D_BEAST MAP28 | D_TENSE | D_AIM MAP29 | D_SHAWN3 | D_DOOM3 MAP30 | D_OPENIN | D_BEAST MAP31 | D_EVIL | D_EVIL MAP32 | D_ULTIMA | D_ULTIMA Intermission| D_DM2INT | D_DM2INT

That is: D_SADIST: MAP 01 - System Control and MAP09 - Stronghold D_BURN: MAP 02 - Human BBQ D_AIM: MAP 03 - Power Control, MAP23 - Lunar Mining Project, MAP28 - Heck D_BELLS: MAP 04 - Wormhole, MAP 13 - Nukage Processing, MAP25 - Baron's Den D_MORE: MAP 05 - Hanger, MAP 17 - Processing Area, MAP24 - Quarry D_AGONY: MAP 06 - Open Season D_CHAOS: MAP 07 - Prison, MAP 12 - Crater, MAP 19 - Shipping Respawning D_BEAST: MAP 08 - Metal, MAP27 - Mount Pain, MAP30 - Last Call D_INFINI: MAP 10 - Redemption and MAP 18 - Mill D_KILL: MAP 11 - Storage D_COLD: MAP 14 - Steel Works, MAP22 - Habitat D_BURN2: MAP 15 - Dead Zone D_BLOOD: MAP 16 - Deepest Reaches, MAP 21 - Administration Center, MAP26 - Ballistyx D_HORIZO: MAP 20 - Central Processing D_DOOM3: MAP29 - River Styx

Plutonia - EDIT: Plutonia music is completely taken from Doom 1 and 2, but re-arranged, that is, Plutonia D_RUNNIN (for MAP01) is the renamed D_E1M2. So I have an idea: if DoomMetalVol5.wad or DoomMetalVol5_44100.wad are loaded, wouldn't it make sense to play the D_E1M2 replacement from DoomMetal in Plutonia?

Here's the replacement table: Map # | Plutonia track name | DoomMetalVol5 track name MAP01 | D_RUNNIN | D_E1M2 MAP02 | D_STALKS | D_E1M3 MAP03 | D_COUNTD | D_E1M6 MAP04 | D_BETWEE | D_E1M4 MAP05 | D_DOOM | D_E1M9 MAP06 | D_THE_DA | D_E1M8 MAP07 | D_SHAWN | D_E2M1 MAP08 | D_DDTBLU | D_E2M2 MAP09 | D_IN_CIT | D_E3M3 MAP10 | D_DEAD | D_E1M7 MAP11 | D_STLKS2 | D_BUNNY MAP12 | D_THEDA2 | D_E3M8 MAP13 | D_DOOM2 | D_E3M2 MAP14 | D_DDTBL2 | D_E2M8 MAP15 | D_RUNNI2 | D_E2M7 MAP16 | D_DEAD2 | D_E3M1 MAP17 | D_STLKS3 | D_E1M1 MAP18 | D_ROMERO | D_E2M5 MAP19 | D_SHAWN2 | D_E1M5 MAP20 | D_MESSAG | D_MESSAG MAP21 | D_COUNT2 | D_COUNT2 (D_READ_M has no instumental cover in Doom Metal) MAP22 | D_DDTBL3 | D_DDTBL3 MAP23 | D_AMPIE | D_AMPIE MAP24 | D_THEDA3 | D_THEDA3 MAP25 | D_ADRIAN | D_ADRIAN MAP26 | D_MESSG2 | D_MESSG2 MAP27 | D_ROMER2 | D_E2M1 MAP28 | D_TENSE | D_E2M2 MAP29 | D_SHAWN3 | D_E1M1 MAP30 | D_OPENIN | D_OPENIN (D_VICTOR has no instumental cover in Doom Metal) MAP31 | D_EVIL | D_E3M4 MAP32 | D_ULTIMA | D_E2M8 Cast seq| D_EVIL | D_E3M4

fabiangreffrath commented 5 years ago

So, Vol 5 introduced a new non-canonical set of songs for TNT.wad that you suggest to check for? How are these songs connected to the corresponding maps, via MAPINFO? What should I do if there is a music lump of one of these names available that isn't supposed to be TNT music?

SoDOOManiac commented 5 years ago

These new tracks are quite canonical instrumental remakes of TNT tracks, they have different names to place them in the same WAD as the tracks for Hell on Earth. They are connected to maps with the script in Brutal Doom, so I thought the same could be achieved by hard-coding in Crispy. I think these lumps can be detected just by name, because if they are replaced by some other WAD, this must be intended.

fabiangreffrath commented 5 years ago

So, the music-to-map assignment is somehow scripted into brutal doom?

WSSDude commented 5 years ago

Yep. There is DYNAMICLVL.txt in the mod that has that overloads. I was writting this but he was quicker so I removed that.

fabiangreffrath commented 5 years ago

And this file is somehow built into the mod? Sorry, but I am a complete ZDoom illiterate.

WSSDude commented 5 years ago

Yep. When you unpack .pk3 file, this file is there in the root. It is used by the mod to change contents of the levels (add some extra clutter etc.). I don't know if this is some kind of ZDoom extenstion (that DYNAMICLVL.TXT) or some addition that is checked and worked with directly by the mod somehow though.

fabiangreffrath commented 5 years ago

Okay, so we are all a little puzzled. :wink:

SoDOOManiac commented 5 years ago

Anyway, no matter how it works in Brutal Doom with GZDoom, is it possible to just code the music replacements for TNT into Crispy? Like: if (iwad==tnt) setmusic (map01)=D_SADIST (if available) etc.

WSSDude commented 5 years ago

There should be an easy way to mod this through mapinfo if I'm not mistaken. There are not that many new song names so there should be an easy way to create PWAD specifically for this. I may do it if this won't get implemented if you want and don't know how to do it yourself (although there are plenty of guides and this type of modification is pretty straight forward...)

I know this is kind of that solution that you need to load an extra PWAD just for those extra songs to play for specific IWAD, but it is better IMO than hard-coding it here...

There is a project called WADSmoosh that merges all Doom wads into one single .pk3 file that you can use as standalone without any IWADs and has all episodes.

It has a python script that generates this along with few other utils. It functions by changing map names and tracks etc. and modifying mapinfo accordingly (so attack.wad from master levels gets renamed to ML_MAP01 for example, MAP01 in TNT gets renamed to TN_MAP01 etc.). Songs are modified there too, starting too with those prefixes. All done with simple modifications inside mapinfo (and few).

WSSDude commented 5 years ago

BTW, bringing WADSmoosh out... It would be nice if this could play it somehow. It is super convenient to have all of Doom IWADs in one place.

But that is OT probably...

Is there a support for pk3s anyway? Too lazy too look into wiki... EDIT: ok, it seems like it doesn't... That's sad :/

fabiangreffrath commented 5 years ago

@WSSDude There is no MAPINFO in Crispy. Please remember that this is just a modified Chocolate Doom. Introducing MAPINFO support would mean to rewrite crucial parts of the engine and open the can of worms for even more ZDoom'isms. Not even beginning to speak of bugs - and lack of developer time. WADSmoosh and PK3 support is thus completely out of question!

Regarding the topic of this issue, I think I'll add some dehacked magic to detect if the music replacement lumps are available and override the lump names in this case.

Unfortunately, we are very limited with regard to additional music support in Doom. There is a hard-coded list of lump names that are supposed to contain the music. So, we either extend this list by more and more lump names (booh!), or we replace the entries where it makes sense. In the case of Sigil, I decided for the former, because it must be possible to play Sigil as episode 5 and then any of the other regular episodes. But if we have loaded either Plutonia or TNT as IWAD, then there is no risk of mixing music up with regular Doom 2.

SoDOOManiac commented 5 years ago

Edited the description, included the track replacement table for Plutonia.

fabiangreffrath commented 5 years ago

Cool, thanks!

Could you probably re-arrange the table for TNt in a similar way, so that I can see a map->original_music->replacement_music context?

SoDOOManiac commented 5 years ago

Here you are, I edited the post, adding the same kind of table for TNT. So finally I expect it to work this way: If DoomMetalVol5.wad or DoomMetalVol5_44100.wad is loaded, apply the respective music replacement table for both Plutonia and TNT IWADs.

fabiangreffrath commented 5 years ago
diff --git a/src/doom/s_sound.c b/src/doom/s_sound.c
index 42a87d19..7639b961 100644
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -107,6 +107,128 @@ static musicinfo_t *mus_playing = NULL;

 int snd_channels = 8;

+// [crispy] add support for alternative music tracks for Final Doom's
+// TNT and Plutonia as introduced in DoomMetalVol5.wad
+
+typedef struct {
+   const char *from, *to;
+} altmusic_t;
+
+static const altmusic_t altmusic_tnt[] =
+{
+   {"RUNNIN", "SADIST"}, // MAP01
+   {"STALKS", "BURN"},   // MAP02
+   {"COUNTD", "AIM"},    // MAP03
+   {"BETWEE", "BELLS"},  // MAP04
+   {"DOOM",   "MORE"},   // MAP05
+   {"THE_DA", "AGONY"},  // MAP06
+   {"SHAWN",  "CHAOS"},  // MAP07
+   {"DDTBLU", "BEAST"},  // MAP08
+   {"IN_CIT", "SADIST"}, // MAP09
+   {"DEAD",   "INFINI"}, // MAP10
+   {"STLKS2", "KILL"},   // MAP11
+   {"THEDA2", "CHAOS"},  // MAP12
+   {"DOOM2",  "BELLS"},  // MAP13
+   {"DDTBL2", "COLD"},   // MAP14
+   {"RUNNI2", "BURN2"},  // MAP15
+   {"DEAD2",  "BLOOD"},  // MAP16
+   {"STLKS3", "MORE"},   // MAP17
+   {"ROMERO", "INFINI"}, // MAP18
+   {"SHAWN2", "CHAOS"},  // MAP19
+   {"MESSAG", "HORIZO"}, // MAP20
+   {"COUNT2", "BLOOD"},  // MAP21
+   {"DDTBL3", "COLD"},   // MAP22
+   {"AMPIE",  "AIM"},    // MAP23
+   {"THEDA3", "MORE"},   // MAP24
+   {"ADRIAN", "BELLS"},  // MAP25
+   {"MESSG2", "BLOOD"},  // MAP26
+   {"ROMER2", "BEAST"},  // MAP27
+   {"TENSE",  "AIM"},    // MAP28
+   {"SHAWN3", "DOOM3"},  // MAP29
+   {"OPENIN", "BEAST"},  // MAP30
+// {"EVIL",   "EVIL"},   // MAP31
+// {"ULTIMA", "ULTIMA"}, // MAP32
+   {NULL,     NULL},
+};
+
+// Plutonia music is completely taken from Doom 1 and 2, but re-arranged.
+// That is, Plutonia's D_RUNNIN (for MAP01) is the renamed D_E1M2. So,
+// it makes sense to play the D_E1M2 replacement from DoomMetal in Plutonia.
+
+static const altmusic_t altmusic_plut[] =
+{
+   {"RUNNIN", "E1M2"},   // MAP01
+   {"STALKS", "E1M3"},   // MAP02
+   {"COUNTD", "E1M6"},   // MAP03
+   {"BETWEE", "E1M4"},   // MAP04
+   {"DOOM",   "E1M9"},   // MAP05
+   {"THE_DA", "E1M8"},   // MAP06
+   {"SHAWN",  "E2M1"},   // MAP07
+   {"DDTBLU", "E2M2"},   // MAP08
+   {"IN_CIT", "E3M3"},   // MAP09
+   {"DEAD",   "E1M7"},   // MAP10
+   {"STLKS2", "BUNNY"},  // MAP11
+   {"THEDA2", "E3M8"},   // MAP12
+   {"DOOM2",  "E3M2"},   // MAP13
+   {"DDTBL2", "E2M8"},   // MAP14
+   {"RUNNI2", "E2M7"},   // MAP15
+   {"DEAD2",  "E3M1"},   // MAP16
+   {"STLKS3", "E1M1"},   // MAP17
+   {"ROMERO", "E2M5"},   // MAP18
+   {"SHAWN2", "E1M5"},   // MAP19
+// {"MESSAG", "MESSAG"}, // MAP20
+// {"COUNT2", "COUNT2"}, // MAP21 (D_READ_M has no instumental cover in Doom Metal)
+// {"DDTBL3", "DDTBL3"}, // MAP22
+// {"AMPIE",  "AMPIE"},  // MAP23
+// {"THEDA3", "THEDA3"}, // MAP24
+// {"ADRIAN", "ADRIAN"}, // MAP25
+   {"MESSG2", "BLOOD"},  // MAP26
+   {"ROMER2", "E2M1"},   // MAP27
+   {"TENSE",  "E2M2"},   // MAP28
+   {"SHAWN3", "E1M1"},   // MAP29
+   {"OPENIN", "VICTOR"}, // MAP30
+   {"EVIL",   "E3M4"},   // MAP31
+   {"ULTIMA", "E2M8"},   // MAP32
+   {NULL,     NULL},
+};
+
+static void S_RegisterAltMusic()
+{
+   const altmusic_t *altmusic_fromto, *altmusic;
+
+   if (gamemission == pack_tnt)
+   {
+       altmusic_fromto = altmusic_tnt;
+   }
+   else
+   if (gamemission == pack_plut)
+   {
+       altmusic_fromto = altmusic_plut;
+   }
+   else
+   {
+       return;
+   }
+
+   // [crispy] chicken-out if only one lump is missing, something must be wrong
+   for (altmusic = altmusic_fromto; altmusic->to; altmusic++)
+   {
+       char name[9];
+
+       M_snprintf(name, sizeof(name), "d_%s", altmusic->to);
+
+       if (W_CheckNumForName(name) == -1)
+       {
+           return;
+       }
+   }
+
+   for (altmusic = altmusic_fromto; altmusic->to; altmusic++)
+   {
+       DEH_AddStringReplacement(altmusic->from, altmusic->to);
+   }
+}
+
 //
 // Initializes sound stuff, including volume
 // Sets channels, SFX and music volume,
@@ -177,6 +299,10 @@ void S_Init(int sfxVolume, int musicVolume)
         M_snprintf(namebuf, sizeof(namebuf), "d_%s", DEH_String(music->name));
         music->lumpnum = W_CheckNumForName(namebuf);
     }
+
+    // [crispy] add support for alternative music tracks for Final Doom's
+    // TNT and Plutonia as introduced in DoomMetalVol5.wad
+    S_RegisterAltMusic();
 }

 void S_Shutdown(void)
WSSDude commented 5 years ago

Ou, I though MAPINFO is vanilla thing lol... It is true I'm fairly new to Doom modding in a sense of creating my wads. Shame about that WADSmoosh though :/

What's with the diff btw? Should somebody try that or what?

SoDOOManiac commented 5 years ago

@WSSDude Fabian uses diffs in comments like 'notes to self' to apply the patch later.

fabiangreffrath commented 5 years ago

Indeed, I sometimes post my work-in-progress so that I still remember it later and people can try out and discuss.

fabiangreffrath commented 5 years ago

Things to consider:

SoDOOManiac commented 5 years ago

Lump name strings must be in lower case, DEHACKED is surprisingly strict about that.

Does that mean I should open DoomMetal with SLADE and rename lumps to lower case?

fabiangreffrath commented 5 years ago

Nope, I'll convert them to lower case in the code tomorrow. That's easier. :wink:

fabiangreffrath commented 5 years ago

It's only relevant for dehacked, the actual case of the lump names doesn't matter.

WSSDude commented 5 years ago

Wouldn't it be generally better to implement that MAPINFO? At least in some basic manner? I see there is an issue for this already (#372).

It should be much better than hardcoding... I kinda hate that thing :D But not my project so take it just as a personal opinion :)

WSSDude commented 5 years ago

If time is a concern, I still believe this should be an ultimate option. Like do this now if you must, making some marks where you did changes or something so it is easier to locate and patch it out later with MAPINFO replacement.

I may be able to help with this also (MAPINFO implementation), although I need still some time to get some basic orientation around the source (as I just got it fully running yesterday...)

fabiangreffrath commented 5 years ago

Oops, forgot to close the issue in https://github.com/fabiangreffrath/crispy-doom/commit/c13b937aaf7480861ac80e003ecdfbc09dbf7ee6, thanks @Zodomaniac and @WSSDude for your input.

fabiangreffrath commented 5 years ago

@WSSDude MAPINFO support isn't something that you "just add". Just like Boom support it is a major undertaking that requires severe changes that span through the entire game logic. And again, just like Boom support, implementing parts of it means that you eventually have to implement all of it, because a half-baked solution makes no sense.

Also, MAPINFO isn't port-agnostic. It's mostly a ZDoom/Eternity thing - to the point that both ports now have developed their own incompatible dialects in the form of ZMAPINFO and EMAPINFO. There is an ongoing effort to establish a "universal MAPINFO" format called UMAPINFO, with a reference implementation based on PrBoom+ currently maintained by Graf Zahl of GZDOom fame, but there isn't a single map available yet that supports this format (chicken and egg problem).

So, I'll be glad to review pull requests, but please don't expect me to put my own effort into this.

As an anecdote: When I started Crispy, I was employed as a post-doc at RWTH University which is a 2,5 hours train ride away from my home. This means, I had 5 hours to kill on a train on each working day! Now things are different. The ports has long reached its design goal and changes come incrementally. In hidnsight, if I was ever going to develop a source port supporting Boom or MAPINFO, I would have started with a different code base. But as things are now, this is the non-crashing high-resolution friend of Chocolate Doom - and not that much more.

SoDOOManiac commented 5 years ago

Works for TNT but doesn't work for Plutonia.

SoDOOManiac commented 5 years ago

This must work https://github.com/fabiangreffrath/crispy-doom/commit/3d8e1b86981628c14cf3d87793020d5855e67972

WSSDude commented 5 years ago

Just to answer in retrospect to what you said @fabiangreffrath.

I take it all, no issues. I too have times when I can work a lot on what I want and times I don't. That are just how things are :)

As for MAPINFO, I though that was vanilla thing for some reason lol... I'm quite new to Doom modding and many guides utilized this file. If there is some UMAPINFO in the making that should be standardized somehow, I may consider implementing that instead.

With that said, I would try to do this and some PR back after when I get some time myself. It would be a great exercise also in regards to understand more of the source. As I said few times, I would like to start contributing so let this be my first project here. I hope I meet your standards lol. But we'll see, that is for some time irrelevant I think.

fabiangreffrath commented 5 years ago

With that said, I would try to do this and some PR back after when I get some time myself.

This is probably not the right project size to start working on a code base. You will have to modify the code everywhere, even in very critical places. Isn't there anything "smaller" that you could start with?

WSSDude commented 5 years ago

Hm, probably true... What would you suggest? (you have probably better idea than me about everything here)

fabiangreffrath commented 5 years ago

Not sure, let me think about it. I guess the best is to follow the discussions here and on the Doomworld forums. Most ideas come while you talk about it - or listen to others. Most of the stuff on the issue tracker is currently gathering dust, either because it is so low on the priority scale, or because it is a major undertaking that nobody (including me) has dared to start yet. It's currently more like a lose collection of ideas - any actual bug is usually fixed rather quickly.