From f8dbaac91134469a5d152812a84451572a726f5a Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Mon, 14 Mar 2022 18:04:54 -0400 Subject: [PATCH 01/13] Initial push - need to check with more custom banks --- MMR.Randomizer/Builder.cs | 9 +- MMR.Randomizer/Models/Rom/SequenceInfo.cs | 14 +++ MMR.Randomizer/Resources/mods.Designer.cs | 42 ++++++++- MMR.Randomizer/Resources/mods.resx | 12 +++ MMR.Randomizer/Resources/mods/dummyinstsets | Bin 0 -> 1424 bytes .../Resources/mods/instrumentset-patch | Bin 0 -> 605 bytes .../Resources/mods/loadnewaudiotable | Bin 0 -> 725 bytes .../Resources/mods/moveaudiostatebytes | Bin 0 -> 485 bytes MMR.Randomizer/Utils/RomUtils.cs | 6 ++ MMR.Randomizer/Utils/SequenceUtils.cs | 87 +++++++++++++++--- 10 files changed, 154 insertions(+), 16 deletions(-) create mode 100644 MMR.Randomizer/Resources/mods/dummyinstsets create mode 100644 MMR.Randomizer/Resources/mods/instrumentset-patch create mode 100644 MMR.Randomizer/Resources/mods/loadnewaudiotable create mode 100644 MMR.Randomizer/Resources/mods/moveaudiostatebytes diff --git a/MMR.Randomizer/Builder.cs b/MMR.Randomizer/Builder.cs index bdd7d16ab..e4ed23154 100644 --- a/MMR.Randomizer/Builder.cs +++ b/MMR.Randomizer/Builder.cs @@ -71,6 +71,7 @@ void WriteOutput(string str) WriteOutput(" Randomizing " + RomData.TargetSequences.Count + " song slots, with " + unassigned.Count + " available songs:"); SequenceUtils.ResetBudget(); + SequenceUtils.ResetFreeBankIndex(); // songtest filename token allows music makers and users to force a song into a MMR seed for recording/testing SequenceUtils.CheckSongTest(unassigned, log); @@ -341,6 +342,10 @@ private void WriteMiscellaneousChanges() } WriteCrashDebuggerShow(); + + // Dolphin/WiiVC audiothread shutdown workaround + ReadWriteUtils.WriteU16ToROM(0xB3C000 + 0x0CD320, 0x1000); + } /// @@ -3050,7 +3055,8 @@ private void WriteStartupStrings() //ResourceUtils.ApplyHack(ModsDir + "postman-testing"); return; } - RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); + RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBank"); + //RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); } public void OutputHashIcons(IEnumerable iconFileIndices, string filename) @@ -3368,6 +3374,7 @@ public void MakeROM(OutputSettings outputSettings, IProgressReporter progressRep WriteInstruments(new Random(BitConverter.ToInt32(hash, 0))); progressReporter.ReportProgress(73, "Writing music..."); + SequenceUtils.MoveAudioBankTableToFile(); WriteAudioSeq(new Random(BitConverter.ToInt32(hash, 0)), outputSettings); WriteMuteMusic(); WriteEnemyCombatMusicMute(); diff --git a/MMR.Randomizer/Models/Rom/SequenceInfo.cs b/MMR.Randomizer/Models/Rom/SequenceInfo.cs index 64d13cfb4..7d69fbf88 100644 --- a/MMR.Randomizer/Models/Rom/SequenceInfo.cs +++ b/MMR.Randomizer/Models/Rom/SequenceInfo.cs @@ -31,5 +31,19 @@ public void ClearUnavailableBanks() || (u.InstrumentSet.Hash != 0 && u.InstrumentSet.Hash == RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Hash))); } + + public bool UsesModifiedBanks() + { + var yoink = this.SequenceBinaryList.FindAll(u => RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Modified != 0); + + if (yoink.Count != 0) + { + return true; + } + + return false; + } + + } } diff --git a/MMR.Randomizer/Resources/mods.Designer.cs b/MMR.Randomizer/Resources/mods.Designer.cs index 4af456f09..75805277b 100644 --- a/MMR.Randomizer/Resources/mods.Designer.cs +++ b/MMR.Randomizer/Resources/mods.Designer.cs @@ -19,7 +19,7 @@ namespace MMR.Randomizer.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class mods { @@ -210,6 +210,16 @@ internal static byte[] dm_4 { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] dummyinstsets { + get { + object obj = ResourceManager.GetObject("dummyinstsets", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -670,6 +680,16 @@ internal static byte[] instant_pictobox { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] instrumentset_patch { + get { + object obj = ResourceManager.GetObject("instrumentset_patch", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -710,6 +730,16 @@ internal static byte[] lenient_goron_spikes { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] loadnewaudiotable { + get { + object obj = ResourceManager.GetObject("loadnewaudiotable", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -730,6 +760,16 @@ internal static byte[] misc_changes { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] moveaudiostatebytes { + get { + object obj = ResourceManager.GetObject("moveaudiostatebytes", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/MMR.Randomizer/Resources/mods.resx b/MMR.Randomizer/Resources/mods.resx index 0f6fcf9b5..0d70a49f6 100644 --- a/MMR.Randomizer/Resources/mods.resx +++ b/MMR.Randomizer/Resources/mods.resx @@ -163,6 +163,9 @@ mods\dm-4;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + mods\dummyinstsets;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + mods\enable-sunssong;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -301,6 +304,9 @@ mods\instant-pictobox;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + mods\instrumentset-patch;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + mods\key-boss-open;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -313,12 +319,18 @@ mods\lenient-goron-spikes.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + mods\loadnewaudiotable;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + mods\logo-text;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 mods\misc-changes;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + mods\moveaudiostatebytes;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + mods\movement-1;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/MMR.Randomizer/Resources/mods/dummyinstsets b/MMR.Randomizer/Resources/mods/dummyinstsets new file mode 100644 index 0000000000000000000000000000000000000000..312708760f44dcff4adbee83b4ec0dc70c57cde2 GIT binary patch literal 1424 mcmZQzl4xLHV7S1<$oQWT$Y2=dkA}x+dKk?QqvgSXl!pN3k=Q=~ literal 0 HcmV?d00001 diff --git a/MMR.Randomizer/Resources/mods/instrumentset-patch b/MMR.Randomizer/Resources/mods/instrumentset-patch new file mode 100644 index 0000000000000000000000000000000000000000..fa3b92aa3eae1386f35c4dff3757f98b03087375 GIT binary patch literal 605 zcmb7=KS;w+5XP@0N`|6wGSn&+qE>Kl$lzFPQLu|>1-lhmu&6^o7ePwrk~D9~;NYmE ze+DPpp*-v0AUH_}hYlTF#KEOb`du5OE`kTieeb*baqk{UFHS_NIZirBZ=H4ZDxQHZ zuog!Yf!^=wB2ADialh^vR+B~_AcK&l1e7LH6cH=jmw&<82&z9x6j0ycdeMX#c0aAA z`);*pWT^};hM$hFyL-nDWHtyfR5>)7BPl^gC6YdpKsfYwBkqJEm^-<~n!Jc2Roa_F*uPxvin z!o$n2B<(i$gt~gnNfRk;(q{HZBUwA{v2VXv%&1)lYzOR9pS5G|U7vOGaAZBlzB9o3 zS-wx*htG4{U>n>M>Vmxw*mJylAtVPDA=@ZttQ9O$SSVN|-Pv8CorQ%T zaO49{Kfq5A(pU=Tn~BHS?3d0v7Sx(1w1(d?pJzl#cmnIP8o!Uz6mYn`}D0Y+4IW&jCczCr++IxUC!?8 zh1NIKm53ROTU|?Ul8K<2N9AYYDDR<~JLTu%DtA!Ly||&(KV@A#$>%M6q{&0P*X^C} z1J^U(NHf5#7q4OO0rQAP)F1xoW8i3neJ;3j%$$k?`Y@-$V?T2()~VA!!ETGZf0lZ> pOPxL`|5mqncc}6rZ*qEdc@H_$@Vz literal 0 HcmV?d00001 diff --git a/MMR.Randomizer/Utils/RomUtils.cs b/MMR.Randomizer/Utils/RomUtils.cs index 59bbe9677..40115562e 100644 --- a/MMR.Randomizer/Utils/RomUtils.cs +++ b/MMR.Randomizer/Utils/RomUtils.cs @@ -282,6 +282,7 @@ private static void ExtractAll(BinaryReader ROM) public static void ReadFileTable(BinaryReader ROM) { + int ReadCount = 0; RomData.MMFileList = new List(); ROM.BaseStream.Seek(FILE_TABLE, SeekOrigin.Begin); while (true) @@ -299,6 +300,11 @@ public static void ReadFileTable(BinaryReader ROM) break; } RomData.MMFileList.Add(Current_File); + ReadCount ++; + if (ReadCount == 1539) + { + break; + } } ExtractAll(ROM); } diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index b232eaccc..cf31bcd6d 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -32,6 +32,12 @@ public class SequenceUtils public static int MAX_COMBAT_BUDGET = 0x3800; // unk public static int MAX_TYPE2_MUSIC_BUDGET = 0x6000; // vanilla: 0x4100 + public static int New_AudioBankTable = 0; // for mmfilelist + public static int NewInstrumentSetAddress; // for bgm shuffle functions to work on + public static int CurrentFreeBank = 0x29; + public static int NextFreeBank = 0x2A; + + public static void ResetBudget() { MAX_BGM_BUDGET = 0x3800; @@ -777,6 +783,44 @@ private static void RelocateSeq(int f) ReadWriteUtils.WriteToROM(0x00C2739C, new byte[] { 0x3C, 0x08, 0x80, 0x0A, 0x8D, 0x05, (byte)(offset >> 8), (byte)(offset & 0xFF) }); } + public static void MoveAudioBankTableToFile() + { + // grab original audiobanktable out of code, plus extra for modifying + var table = ReadWriteUtils.ReadBytes(0xB3C000 + 0x13B6C0, 0x820); + New_AudioBankTable = RomUtils.AddNewFile(table); + + ResourceUtils.ApplyHack(Resources.mods.instrumentset_patch); + ResourceUtils.ApplyHack(Resources.mods.moveaudiostatebytes); + ResourceUtils.ApplyHack(Resources.mods.loadnewaudiotable); + ReadWriteUtils.WriteCodeNOP(0x80190E70); + ReadWriteUtils.WriteCodeNOP(0x80190E74); + ReadWriteUtils.WriteCodeNOP(0x80190E78); + ReadWriteUtils.WriteCodeNOP(0x80190E7C); + ReadWriteUtils.WriteCodeNOP(0x80190E80); + + // To do: make this dynamic with payload length, at some point. maybe. + ReadWriteUtils.WriteU32ToROM(0xC776C0, 0x807343D0); //RAM address to move audiobanktable into + + int f = RomUtils.GetFileIndexForWriting(New_AudioBankTable); + var fileData = RomData.MMFileList[f].Addr; + ReadWriteUtils.WriteToROM(0xC776C4, (uint)fileData ); //VROM address of new audiobanktable + ReadWriteUtils.WriteU32ToROM(0xC776C8, 0x00000820); //file length + + NewInstrumentSetAddress = RomData.MMFileList[f].Addr + 0x10; + + ReadWriteUtils.WriteU16ToROM(RomData.MMFileList[f].Addr, 0x0080); // Increase AudioBankTable amount + // place dummy audiobanktable metadata into new file, this could've been done better + ReadWriteUtils.WriteToROM(NewInstrumentSetAddress + 0x280, Resources.mods.dummyinstsets); + + } + + public static void ResetFreeBankIndex() + { + CurrentFreeBank = 0x29; + NextFreeBank = 0x2A; + } + + public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targetSlot, StringBuilder log, Random rng, List unassignedSequences) { /// test if the testSeq can be used with available instrument set slots @@ -790,20 +834,27 @@ public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targe testSeq.SequenceBinaryList = testSeq.SequenceBinaryList.OrderBy(x => rng.Next()).ToList(); } - testSeq.ClearUnavailableBanks(); // clear the sequence list of {bank/sequence} we cannot use + //testSeq.ClearUnavailableBanks(); // clear the sequence list of {bank/sequence} we cannot use + //if (testSeq.SequenceBinaryList.Count == 0) // all removed, song is dead. + //{ + // log.AppendLine($"{ testSeq.Name,-50} cannot be used because it requires custom audiobank(s) already claimed "); + // unassignedSequences.Remove(testSeq); + // return false; + //} - if (testSeq.SequenceBinaryList.Count == 0) // all removed, song is dead. + var BanksUsed = testSeq.UsesModifiedBanks(); + + if (BanksUsed == true) { - log.AppendLine($"{ testSeq.Name,-50} cannot be used because it requires custom audiobank(s) already claimed "); - unassignedSequences.Remove(testSeq); - return false; + testSeq.SequenceBinaryList[0].InstrumentSet.BankSlot = CurrentFreeBank; + CurrentFreeBank = +1; } // some slots are rarely heard in-game, dont waste a custom instrument set on them, check if this slot is one of them - if (IsBlockedByLowUse(testSeq, targetSlot, log)) - { - return false; - } + //if (IsBlockedByLowUse(testSeq, targetSlot, log)) + //{ + // return false; + //} } return true; // sequences with banks, or without needing banks, available } @@ -1079,6 +1130,12 @@ public static bool SearchForValidSongReplacement(List unassignedSe if (testSeq.Type.Intersect(targetSlot.Type).Any()) { AssignSequenceSlot(targetSlot, testSeq, unassignedSequences, "", log); + + if (CurrentFreeBank == NextFreeBank) + { + NextFreeBank = +1; + } + return true; } @@ -1255,10 +1312,11 @@ public static void ReadInstrumentSetList() /// traverse the whole audiobank index and grab details about every bank /// use those details to generate a list from the vanilla game that we can modify as needed RomData.InstrumentSetList = new List(); - for (int audiobankIndex = 0; audiobankIndex <= 0x28; ++audiobankIndex) + // audiobankindex can go up to 0x81 with current extended bank table file + for (int audiobankIndex = 0; audiobankIndex <= 0x80; ++audiobankIndex) { // each bank has one 16 byte sentence of data, first word is address, second is length, last 2 words metadata - int audiobankIndexAddr = Addresses.AudiobankTable + (audiobankIndex * 0x10); + int audiobankIndexAddr = NewInstrumentSetAddress + (audiobankIndex * 0x10); int audiobankBankOffset = (ReadWriteUtils.ReadU16(audiobankIndexAddr) << 16) + ReadWriteUtils.ReadU16(audiobankIndexAddr + 2); int bankLength = (ReadWriteUtils.ReadU16(audiobankIndexAddr + 4) << 16) + ReadWriteUtils.ReadU16(audiobankIndexAddr + 6); @@ -1383,15 +1441,16 @@ public static void WriteNewSoundSamples(List InstrumentSetLis public static void RebuildAudioBank(List InstrumentSetList) { // get index for the old audiobank, we're putting it back in the same spot but letting it expand into audioseq's spot, which was moved to the end - int fid = RomUtils.GetFileIndexForWriting(Addresses.AudiobankTable); + int fid = RomUtils.GetFileIndexForWriting(NewInstrumentSetAddress); // the DMA table doesn't point directly to the indextable on the rom, its part of a larger yaz0 file, we have to use an offset to get the address in the file - int audiobankIndexOffset = Addresses.AudiobankTable - RomData.MMFileList[RomUtils.GetFileIndexForWriting(Addresses.AudiobankTable)].Addr; + int audiobankIndexOffset = NewInstrumentSetAddress - RomData.MMFileList[RomUtils.GetFileIndexForWriting(NewInstrumentSetAddress)].Addr; int audiobankBankOffset = 0; var audiobankData = new byte[0]; // for each bank, concat onto the new bank byte object, update the table to match the new instrument sets - for (int audiobankIndex = 0; audiobankIndex <= 0x28; ++audiobankIndex) + // NextFreeBank is used so not all unused dummy audiobanks get written to rom + for (int audiobankIndex = 0; audiobankIndex <= NextFreeBank; ++audiobankIndex) { var currentBank = InstrumentSetList[audiobankIndex]; audiobankData = audiobankData.Concat(currentBank.BankBinary).ToArray(); From 591064dac3e06cdf93f693bef16e726be07623c4 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Tue, 15 Mar 2022 03:32:39 -0400 Subject: [PATCH 02/13] i forgot how to increment numbers? how did i get this far --- MMR.Randomizer/Utils/SequenceUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index cf31bcd6d..73f5d14a3 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -847,7 +847,7 @@ public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targe if (BanksUsed == true) { testSeq.SequenceBinaryList[0].InstrumentSet.BankSlot = CurrentFreeBank; - CurrentFreeBank = +1; + CurrentFreeBank = ++CurrentFreeBank; } // some slots are rarely heard in-game, dont waste a custom instrument set on them, check if this slot is one of them @@ -1133,7 +1133,7 @@ public static bool SearchForValidSongReplacement(List unassignedSe if (CurrentFreeBank == NextFreeBank) { - NextFreeBank = +1; + NextFreeBank = ++NextFreeBank; } return true; From ba78dc51cbd8daec23ef341f34fd0dcd0dd1c702 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Wed, 16 Mar 2022 20:37:00 -0400 Subject: [PATCH 03/13] Handle seqs with multiple bank options a little better, set next free bank during seq assignment instead of before --- MMR.Randomizer/Models/Rom/SequenceInfo.cs | 17 +++++++++-------- MMR.Randomizer/Utils/SequenceUtils.cs | 23 +++++++++-------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/MMR.Randomizer/Models/Rom/SequenceInfo.cs b/MMR.Randomizer/Models/Rom/SequenceInfo.cs index 7d69fbf88..69d4aac9b 100644 --- a/MMR.Randomizer/Models/Rom/SequenceInfo.cs +++ b/MMR.Randomizer/Models/Rom/SequenceInfo.cs @@ -32,18 +32,19 @@ public void ClearUnavailableBanks() && u.InstrumentSet.Hash == RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Hash))); } - public bool UsesModifiedBanks() + public bool CheckAvailableBanks() { - var yoink = this.SequenceBinaryList.FindAll(u => RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Modified != 0); - - if (yoink.Count != 0) + // get list of banks that: their slot has not been modified, or their bank is already used by another song and can be reused + var banks = this.SequenceBinaryList.FindAll(u => u.InstrumentSet == null + || (RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Modified == 0 + || (u.InstrumentSet.Hash != 0 + && u.InstrumentSet.Hash == RomData.InstrumentSetList[u.InstrumentSet.BankSlot].Hash))); + if (banks.Count == 0) { - return true; + return false; } - - return false; + return true; } - } } diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index 73f5d14a3..726fa4d8d 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -35,7 +35,6 @@ public class SequenceUtils public static int New_AudioBankTable = 0; // for mmfilelist public static int NewInstrumentSetAddress; // for bgm shuffle functions to work on public static int CurrentFreeBank = 0x29; - public static int NextFreeBank = 0x2A; public static void ResetBudget() @@ -817,7 +816,6 @@ public static void MoveAudioBankTableToFile() public static void ResetFreeBankIndex() { CurrentFreeBank = 0x29; - NextFreeBank = 0x2A; } @@ -842,14 +840,13 @@ public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targe // return false; //} - var BanksUsed = testSeq.UsesModifiedBanks(); - - if (BanksUsed == true) + var testBanks = testSeq.CheckAvailableBanks(); + if (testBanks == false) // all custom banks have been claimed { testSeq.SequenceBinaryList[0].InstrumentSet.BankSlot = CurrentFreeBank; - CurrentFreeBank = ++CurrentFreeBank; } + // some slots are rarely heard in-game, dont waste a custom instrument set on them, check if this slot is one of them //if (IsBlockedByLowUse(testSeq, targetSlot, log)) //{ @@ -974,6 +971,10 @@ public static void AssignSequenceSlot(SequenceInfo slotSequence, SequenceInfo re // if the song has a custom instrument set, lock the sequence, update inst set value, debug output if (replacementSequence.SequenceBinaryList != null && replacementSequence.SequenceBinaryList[0] != null && replacementSequence.SequenceBinaryList[0].InstrumentSet != null) { + if (replacementSequence.SequenceBinaryList[0].InstrumentSet.BankSlot == CurrentFreeBank) + { + CurrentFreeBank++; + } replacementSequence.Instrument = replacementSequence.SequenceBinaryList[0].InstrumentSet.BankSlot; // update to the one we want to use if (RomData.InstrumentSetList[replacementSequence.Instrument].Modified > 0) { @@ -1130,12 +1131,6 @@ public static bool SearchForValidSongReplacement(List unassignedSe if (testSeq.Type.Intersect(targetSlot.Type).Any()) { AssignSequenceSlot(targetSlot, testSeq, unassignedSequences, "", log); - - if (CurrentFreeBank == NextFreeBank) - { - NextFreeBank = ++NextFreeBank; - } - return true; } @@ -1449,8 +1444,8 @@ public static void RebuildAudioBank(List InstrumentSetList) var audiobankData = new byte[0]; // for each bank, concat onto the new bank byte object, update the table to match the new instrument sets - // NextFreeBank is used so not all unused dummy audiobanks get written to rom - for (int audiobankIndex = 0; audiobankIndex <= NextFreeBank; ++audiobankIndex) + // CurrentFreeBank is used so not all unused dummy audiobanks get written to rom + for (int audiobankIndex = 0; audiobankIndex <= CurrentFreeBank; ++audiobankIndex) { var currentBank = InstrumentSetList[audiobankIndex]; audiobankData = audiobankData.Concat(currentBank.BankBinary).ToArray(); From c39885ae1193c85746abed7aa48f5ff40aea39ab Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Wed, 16 Mar 2022 21:29:19 -0400 Subject: [PATCH 04/13] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1d4a5db03..175161a82 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +### This branch attempts to move the instrument set list to a file outside of code, modifies code to access and use that file, and have the Randomizer use the extra space. + Majora's Mask Randomizer is a Windows application that randomizes item locations, music, and more for Majora's Mask, presenting millions of combinations and new ways to replay the game. A video tutorial of setting up MMR is found here: https://www.youtube.com/watch?v=D0n829cYzl4 From 46f267efc704489ab32dcc5c0ab75c3495d42449 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Thu, 17 Mar 2022 20:22:11 -0400 Subject: [PATCH 05/13] Restored nulled filelist entries, check if new instrument set entries don't go past 0x80 --- MMR.Randomizer/Builder.cs | 2 +- MMR.Randomizer/Utils/RomUtils.cs | 12 ++++++------ MMR.Randomizer/Utils/SequenceUtils.cs | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/MMR.Randomizer/Builder.cs b/MMR.Randomizer/Builder.cs index e4ed23154..39dfa12e4 100644 --- a/MMR.Randomizer/Builder.cs +++ b/MMR.Randomizer/Builder.cs @@ -3055,7 +3055,7 @@ private void WriteStartupStrings() //ResourceUtils.ApplyHack(ModsDir + "postman-testing"); return; } - RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBank"); + RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBankv2"); //RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); } diff --git a/MMR.Randomizer/Utils/RomUtils.cs b/MMR.Randomizer/Utils/RomUtils.cs index 40115562e..04847bd56 100644 --- a/MMR.Randomizer/Utils/RomUtils.cs +++ b/MMR.Randomizer/Utils/RomUtils.cs @@ -282,7 +282,7 @@ private static void ExtractAll(BinaryReader ROM) public static void ReadFileTable(BinaryReader ROM) { - int ReadCount = 0; + //int ReadCount = 0; RomData.MMFileList = new List(); ROM.BaseStream.Seek(FILE_TABLE, SeekOrigin.Begin); while (true) @@ -300,11 +300,11 @@ public static void ReadFileTable(BinaryReader ROM) break; } RomData.MMFileList.Add(Current_File); - ReadCount ++; - if (ReadCount == 1539) - { - break; - } + //ReadCount ++; + //if (ReadCount == 1539) + //{ + // break; + //} } ExtractAll(ROM); } diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index 726fa4d8d..b8ec6fb6a 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -843,10 +843,14 @@ public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targe var testBanks = testSeq.CheckAvailableBanks(); if (testBanks == false) // all custom banks have been claimed { + if (CurrentFreeBank > 0x0080) + { + return false; // can't overwrite any more entries + } + testSeq.SequenceBinaryList[0].InstrumentSet.BankSlot = CurrentFreeBank; } - // some slots are rarely heard in-game, dont waste a custom instrument set on them, check if this slot is one of them //if (IsBlockedByLowUse(testSeq, targetSlot, log)) //{ From d842f6b9f4f48f58eb260742c461545608f15d8a Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Sat, 19 Mar 2022 22:53:29 -0400 Subject: [PATCH 06/13] Added instructions to audio hack binary --- MMR.Randomizer/Builder.cs | 2 +- .../Resources/mods/moveaudiostatebytes | Bin 485 -> 525 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/MMR.Randomizer/Builder.cs b/MMR.Randomizer/Builder.cs index 39dfa12e4..682f5a141 100644 --- a/MMR.Randomizer/Builder.cs +++ b/MMR.Randomizer/Builder.cs @@ -3055,7 +3055,7 @@ private void WriteStartupStrings() //ResourceUtils.ApplyHack(ModsDir + "postman-testing"); return; } - RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBankv2"); + RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBankv3"); //RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); } diff --git a/MMR.Randomizer/Resources/mods/moveaudiostatebytes b/MMR.Randomizer/Resources/mods/moveaudiostatebytes index 89c225b0c7f7e474ec0e46f4b628e2ec66ceda06..4240e7070950b4ba1c164ddde184b5902baf0070 100644 GIT binary patch delta 49 zcmaFL+{?1z38N;%Az2*;1_l-zz6LoU+XTc`JtrIhWV-;_95(z7a;ooz8vX+SG42di delta 9 QcmeBWdCI)u2_xfw026lv4*&oF From 017fdc3d4caf9aafc3d60eb216e5e09c4f42a495 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Mon, 28 Mar 2022 00:34:05 -0400 Subject: [PATCH 07/13] dummy instrumentsets are written in programme, and added comments on what each audio hack binary does --- MMR.Randomizer/Builder.cs | 5 ++-- MMR.Randomizer/Resources/mods.Designer.cs | 10 ------- MMR.Randomizer/Resources/mods.resx | 3 -- MMR.Randomizer/Resources/mods/dummyinstsets | Bin 1424 -> 0 bytes MMR.Randomizer/Utils/RomUtils.cs | 6 ---- MMR.Randomizer/Utils/SequenceUtils.cs | 29 ++++++++++++++++++-- 6 files changed, 28 insertions(+), 25 deletions(-) delete mode 100644 MMR.Randomizer/Resources/mods/dummyinstsets diff --git a/MMR.Randomizer/Builder.cs b/MMR.Randomizer/Builder.cs index 682f5a141..fa0d238fa 100644 --- a/MMR.Randomizer/Builder.cs +++ b/MMR.Randomizer/Builder.cs @@ -71,7 +71,6 @@ void WriteOutput(string str) WriteOutput(" Randomizing " + RomData.TargetSequences.Count + " song slots, with " + unassigned.Count + " available songs:"); SequenceUtils.ResetBudget(); - SequenceUtils.ResetFreeBankIndex(); // songtest filename token allows music makers and users to force a song into a MMR seed for recording/testing SequenceUtils.CheckSongTest(unassigned, log); @@ -115,6 +114,7 @@ private void WriteAudioSeq(Random random, OutputSettings _settings) RomData.PointerizedSequences = new List(); SequenceUtils.ReadSequenceInfo(); SequenceUtils.ReadInstrumentSetList(); + SequenceUtils.ResetFreeBankIndex(); if (_cosmeticSettings.Music == Music.Random) { SequenceUtils.PointerizeSequenceSlots(); @@ -3055,8 +3055,7 @@ private void WriteStartupStrings() //ResourceUtils.ApplyHack(ModsDir + "postman-testing"); return; } - RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", $"-AudBankv3"); - //RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); + RomUtils.SetStrings(Resources.mods.logo_text, $"v{Randomizer.AssemblyVersion}", string.Empty); } public void OutputHashIcons(IEnumerable iconFileIndices, string filename) diff --git a/MMR.Randomizer/Resources/mods.Designer.cs b/MMR.Randomizer/Resources/mods.Designer.cs index 75805277b..21b5499ab 100644 --- a/MMR.Randomizer/Resources/mods.Designer.cs +++ b/MMR.Randomizer/Resources/mods.Designer.cs @@ -210,16 +210,6 @@ internal static byte[] dm_4 { } } - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] dummyinstsets { - get { - object obj = ResourceManager.GetObject("dummyinstsets", resourceCulture); - return ((byte[])(obj)); - } - } - /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/MMR.Randomizer/Resources/mods.resx b/MMR.Randomizer/Resources/mods.resx index 0d70a49f6..ff6f5482c 100644 --- a/MMR.Randomizer/Resources/mods.resx +++ b/MMR.Randomizer/Resources/mods.resx @@ -163,9 +163,6 @@ mods\dm-4;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - mods\dummyinstsets;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - mods\enable-sunssong;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/MMR.Randomizer/Resources/mods/dummyinstsets b/MMR.Randomizer/Resources/mods/dummyinstsets deleted file mode 100644 index 312708760f44dcff4adbee83b4ec0dc70c57cde2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1424 mcmZQzl4xLHV7S1<$oQWT$Y2=dkA}x+dKk?QqvgSXl!pN3k=Q=~ diff --git a/MMR.Randomizer/Utils/RomUtils.cs b/MMR.Randomizer/Utils/RomUtils.cs index 04847bd56..59bbe9677 100644 --- a/MMR.Randomizer/Utils/RomUtils.cs +++ b/MMR.Randomizer/Utils/RomUtils.cs @@ -282,7 +282,6 @@ private static void ExtractAll(BinaryReader ROM) public static void ReadFileTable(BinaryReader ROM) { - //int ReadCount = 0; RomData.MMFileList = new List(); ROM.BaseStream.Seek(FILE_TABLE, SeekOrigin.Begin); while (true) @@ -300,11 +299,6 @@ public static void ReadFileTable(BinaryReader ROM) break; } RomData.MMFileList.Add(Current_File); - //ReadCount ++; - //if (ReadCount == 1539) - //{ - // break; - //} } ExtractAll(ROM); } diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index b8ec6fb6a..685ff0042 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -788,9 +788,21 @@ public static void MoveAudioBankTableToFile() var table = ReadWriteUtils.ReadBytes(0xB3C000 + 0x13B6C0, 0x820); New_AudioBankTable = RomUtils.AddNewFile(table); + // instrumentset_patch: modifies audiobank metadata read and writes, instrument/drum/sfx pointer read and writes, + // nops a metadata copy function, and sets a fixed size for the audiobank pointer index ResourceUtils.ApplyHack(Resources.mods.instrumentset_patch); + + // moveaudiostatebytes: sets where read and writes for sequence and instrumentset states go + // in this hack, they're moved from 0x80205008 to end of old instrumentset table in code and given more space + // if these don't get moved, new banks at 0x30 and up will overflow into sequence states and can knock out sound ResourceUtils.ApplyHack(Resources.mods.moveaudiostatebytes); + + // loadnewaudiotable: where the copy metadata function loop was, sets a jump to code placed at the old instrumentset list + // which DMAs new audiobanktable from a file, relocates the addresses in the table, and sets the + // instrumentset table pointer to the new file ResourceUtils.ApplyHack(Resources.mods.loadnewaudiotable); + + // can't update addresses in an audiobank table that's moved and not loaded yet ReadWriteUtils.WriteCodeNOP(0x80190E70); ReadWriteUtils.WriteCodeNOP(0x80190E74); ReadWriteUtils.WriteCodeNOP(0x80190E78); @@ -808,8 +820,19 @@ public static void MoveAudioBankTableToFile() NewInstrumentSetAddress = RomData.MMFileList[f].Addr + 0x10; ReadWriteUtils.WriteU16ToROM(RomData.MMFileList[f].Addr, 0x0080); // Increase AudioBankTable amount - // place dummy audiobanktable metadata into new file, this could've been done better - ReadWriteUtils.WriteToROM(NewInstrumentSetAddress + 0x280, Resources.mods.dummyinstsets); + + // insert dummy metadata (kamaro's dance bank duplicates) + int dummybankindexOffset = NewInstrumentSetAddress + 0x280; + int totaldummybanks = 0x58; + ulong dummybankmetadata0 = 0x00021880000000D0; + ulong dummybankmetadata1 = 0x020101FF01000000; + + for (int dummybankIndex = 0; dummybankIndex <= totaldummybanks; ++dummybankIndex) + { + ReadWriteUtils.WriteU64ToROM(dummybankindexOffset, dummybankmetadata0); + ReadWriteUtils.WriteU64ToROM(dummybankindexOffset + 0x08, dummybankmetadata1); + dummybankindexOffset += 0x10; + } } @@ -1311,7 +1334,7 @@ public static void ReadInstrumentSetList() /// traverse the whole audiobank index and grab details about every bank /// use those details to generate a list from the vanilla game that we can modify as needed RomData.InstrumentSetList = new List(); - // audiobankindex can go up to 0x81 with current extended bank table file + // audiobankindex can go up to 0x80 with current extended bank table file for (int audiobankIndex = 0; audiobankIndex <= 0x80; ++audiobankIndex) { // each bank has one 16 byte sentence of data, first word is address, second is length, last 2 words metadata From 6ad983c585f09c2431f78445bb67fcc771d90843 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:35:54 -0400 Subject: [PATCH 08/13] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 175161a82..1d4a5db03 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -### This branch attempts to move the instrument set list to a file outside of code, modifies code to access and use that file, and have the Randomizer use the extra space. - Majora's Mask Randomizer is a Windows application that randomizes item locations, music, and more for Majora's Mask, presenting millions of combinations and new ways to replay the game. A video tutorial of setting up MMR is found here: https://www.youtube.com/watch?v=D0n829cYzl4 From 0c494c145e2fcc8afc28cf88da251a17fab8a832 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Mon, 4 Apr 2022 15:42:15 -0400 Subject: [PATCH 09/13] Update ram address for audiobank table. --- MMR.Randomizer/Utils/SequenceUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index 685ff0042..88082ae61 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -810,7 +810,7 @@ public static void MoveAudioBankTableToFile() ReadWriteUtils.WriteCodeNOP(0x80190E80); // To do: make this dynamic with payload length, at some point. maybe. - ReadWriteUtils.WriteU32ToROM(0xC776C0, 0x807343D0); //RAM address to move audiobanktable into + ReadWriteUtils.WriteU32ToROM(0xC776C0, 0x80734730); //RAM address to move audiobanktable into int f = RomUtils.GetFileIndexForWriting(New_AudioBankTable); var fileData = RomData.MMFileList[f].Addr; From 7906633a1a7dc794e58af8e9da57e6b772fd157a Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Tue, 5 Apr 2022 21:45:36 -0400 Subject: [PATCH 10/13] Remove claimed banks on seqs/mmrs with one or more still available existing bank options --- MMR.Randomizer/Utils/SequenceUtils.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index 88082ae61..dea06a2f8 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -864,7 +864,11 @@ public static bool TestIfAvailableBanks(SequenceInfo testSeq, SequenceInfo targe //} var testBanks = testSeq.CheckAvailableBanks(); - if (testBanks == false) // all custom banks have been claimed + if (testBanks == true) + { + testSeq.ClearUnavailableBanks(); // remove any already claimed bank sequences + } + else // all custom banks have been claimed { if (CurrentFreeBank > 0x0080) { From 26aeb71e40c1f9f8ddf600413534977e43757ff2 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Wed, 6 Apr 2022 19:10:10 -0400 Subject: [PATCH 11/13] Read payload length from asm/symbols.json, so audiobank table ram address can shift with payload changes. --- MMR.Randomizer/Utils/SequenceUtils.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index dea06a2f8..10ff915e2 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -809,8 +809,9 @@ public static void MoveAudioBankTableToFile() ReadWriteUtils.WriteCodeNOP(0x80190E7C); ReadWriteUtils.WriteCodeNOP(0x80190E80); - // To do: make this dynamic with payload length, at some point. maybe. - ReadWriteUtils.WriteU32ToROM(0xC776C0, 0x80734730); //RAM address to move audiobanktable into + var symbols = Symbols.Load(); + var tableAddr = 0x80720000 + (symbols.PayloadEnd - symbols.PayloadStart); //payload ram address + length + ReadWriteUtils.WriteU32ToROM(0xC776C0, tableAddr); //RAM address to move audiobanktable into int f = RomUtils.GetFileIndexForWriting(New_AudioBankTable); var fileData = RomData.MMFileList[f].Addr; From ba5e50e06f18d9534b7602814c3329db574978e1 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Sat, 9 Apr 2022 15:55:14 -0400 Subject: [PATCH 12/13] Throw error if audiobanks spill into audiotable space. --- MMR.Randomizer/Utils/SequenceUtils.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MMR.Randomizer/Utils/SequenceUtils.cs b/MMR.Randomizer/Utils/SequenceUtils.cs index 10ff915e2..3b6252a78 100644 --- a/MMR.Randomizer/Utils/SequenceUtils.cs +++ b/MMR.Randomizer/Utils/SequenceUtils.cs @@ -1515,6 +1515,19 @@ public static void RebuildAudioBank(List InstrumentSetList) var audiobankFile = RomData.MMFileList[RomUtils.GetFileIndexForWriting(Addresses.Audiobank)]; audiobankFile.Data = audiobankData; audiobankFile.End = audiobankFile.Addr + audiobankFile.Data.Length; + + // check if audiobank has overflowed past the old audioseq space and into audiotable + if (audiobankFile.End > RomData.MMFileList[5].Addr) + { + int wowthatsalotofbanks = audiobankFile.End - RomData.MMFileList[5].Addr; + string oopsy = wowthatsalotofbanks.ToString(); + throw new Exception("\nAudio banks have overflowed into audiotable\n" + + "by " + + oopsy + + " bytes.\n\n" + + "Please try another seed for a different music roll, " + + "or bring down the amount of MMRS files with custom banks."); + } } } } From dd71bd9d6138c27df9a330cef0ff648fd3c645c6 Mon Sep 17 00:00:00 2001 From: Rebbacus <100238547+Rebbacus@users.noreply.github.com> Date: Sun, 10 Apr 2022 15:27:33 -0400 Subject: [PATCH 13/13] Update audio hack binary (loadnewaudiotable) --- MMR.Randomizer/Resources/mods/loadnewaudiotable | Bin 725 -> 725 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/MMR.Randomizer/Resources/mods/loadnewaudiotable b/MMR.Randomizer/Resources/mods/loadnewaudiotable index f1647efa30e2aa8198f78581199908cad4f84250..5b2329c2c30ce9433c06a86a6fd54ae7021ac0e8 100644 GIT binary patch delta 34 qcmcc0dX;s86x;t7>-RH=OjI!E6k&eAz@fgEL1JT~2h-#gOu7KyLkoZa delta 32 ocmcc0dX;s86dMD>`uz+76BW$a1(+W&aH#LynCQVYc^Q*F0G-eYcK`qY