KungFuFurby / AddMusicKFF

Fork of AddMusicK, a compiler/inserter of music for Super Mario World
23 stars 15 forks source link

Music/Song Groups #60

Open KungFuFurby opened 3 years ago

KungFuFurby commented 3 years ago

Requested by imamelia on the SMWCentral forums.

This is currently in the conceptual phase, because of memory location shenanigans that I would have to do to make this work. This will take teamwork from the C++-side, the SNES-side and the SPC700-side to get right.

Currently I'm thinking of using a one ID system for globals and locals, and an optional two-ID system with quoted pathnames on custom song groups by name: one required ID for the master ID, and a second ID for a fixed sub-tune ID (this must not be less than the highest global song ID, and if not defined, occupies the last known slot, which usually increments sequentially). The master ID is allowed to be duplicated across song groups under the condition that it is the exact same track.

In addition, I will allow the use of the # character to refer to non-global, non-local groups to include in a song.

Locals are by default single songs, and also count as a unique song group of one song. They automatically take up the lowest non-global sub-tune ID. These should be defined after all other groups to prevent complications with tracking IDs manually.

To implement the dynamic pointer scenario, p4plus2 proposed a simple relocation table method. For me, it simply means swapping in and out pre-computed pointers that are already computed wherever needed, and it is only needed if there is a song that belongs in more than one song (being in the local section counts as being in a unique song group). I have ultimately decided that I shouldn't do this citing a factorial factor down the road, so instead I came up with something that won't require scanning the raw data format. See #133 for further details.

This concept can also be expanded to dynamically load VCMD code on the fly, but that's a little bit out of scope.

When song groups are loaded, all of the samples must be accounted for that are defined on a per-song basis, and the sample IDs used can get quite a good deal inconsistent. This will be a very interesting conflict to resolve if one uses #default and the other uses #optimized as a nice example case...

Outside the scope of sample group conflicts, for the extra samples, I think I can upload them by real sample ID (taking care to account for duplicates), and then make a table to convert them to the expected sample ID that the song data expects. This would also only apply to the custom song groups: locals don't have this problem since they're just a single song.

We also need to take care of #instruments. Custom instruments can end up duplicated in each song, and therefore I feel that we can partially obsolete the AMK-style header and instead put them all just before the songs, giving them a nice, fixed location to be housed at. Instead, taking its place will be a translation table. Global songs with custom instruments will have their own array separate from the song groups. See #131 for further details.

Example .txt file demonstrating each type

Click to show ``` Globals: 01 Silence.txt 02 Fanfare.txt InGameFanfares: 03 "Stage Clear.txt" 04 "Invincibility.txt" 05 "Death.txt" InGameMusicSet1: #InGameFanfares 06 08 "Stage Theme 1.txt" InGameMusicSet2: #InGameFanfares 07 08 "Stage Theme 2.txt" InGameMusicSet3: #InGameFanfares 08 08 "Stage Theme 3.txt" 09 06 "Secret Area Theme 1.txt" 0A 07 "Secret Area Theme 2.txt" MenuThemes: 0B 06 "Main Menu.txt" 0C 07 "Options.txt" 0D 08 "Password.txt" 0E 09 "Nothing To See Here.txt" 03 0A "Stage Clear.txt" Locals: 0F Title Screen.txt 10 Ending.txt 11 Game Over.txt ```
KungFuFurby commented 1 month ago

I have decided that I should take a stepped approach to this. Yes, the data version will get incremented multiple times as a result, but it should tone down the amount of time it takes for me to implement this stuff in a form that can be reasonably plugged in to the compiler that AddmusicK has.

The earliest version of the song group will likely not contain the dynamic pointers (this means music data will be duplicated as a side effect with pointer differences, but it also makes the instrument situation easier on me), and the instrument data will remain duplicated in the song header to avoid SPC-side shenanigans. Sample IDs will be handled in a merged fashion, unless #236 is factored in.

In addition, I have determined that I need to redefine the ID system a little bit so that $1DFB can call any sub-tune ID on the fly. Namely... the sub-tune IDs cannot conflict with the IDs that are used to call the song group loaders. That is, they go immediately after the global songs, and before what would normally be the local songs, which are now the IDs that access the song group directly. The ID system will also be fully defined below: