mirror of
https://github.com/mogzol/BrawlBuilder.git
synced 2025-02-22 03:27:11 +01:00
Many improvements to GCT patching, other misc. fixes
I'm not dead! Just busy with other stuff and havent had much time to work on this. Anyway, this is pretty much ready for first release! With this commit the way GCT patching was being done has changed completely. GCT patches are applied by default, the user is no longer notified. GCT patches are also applied to all GCTs, not just Project M 3.6. The ProjM36Patches.txt file is now CodePatches.txt. The CHECK statement has been removed, and there is now an IF/ENDIF statement to specify patches to apply only if certain codes exist. A patch has been added for the replacement soundbank engine, making mods that make use of it (sfx folder with .sawnd files) load the sounds from disc instead of SD. Additionally, numerous bugs have been fixed, and some code has been cleaned up.
This commit is contained in:
parent
85644f908a
commit
3f81227d25
@ -13,10 +13,13 @@ namespace BrawlBuilder
|
||||
{
|
||||
partial class BrawlBuilder
|
||||
{
|
||||
private bool _pm36patches = false;
|
||||
private bool _remove_en;
|
||||
|
||||
private void buildWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
// Don't remove the _en suffix by default
|
||||
_remove_en = false;
|
||||
|
||||
// Set up wit
|
||||
bool showWit = Environment.GetCommandLineArgs().Contains("--show-wit");
|
||||
|
||||
@ -62,12 +65,17 @@ namespace BrawlBuilder
|
||||
}
|
||||
|
||||
// STAGE 1: Analyze GCT
|
||||
if (!Analyze())
|
||||
File.Delete(@"./Resources/temp.gct"); // Make sure any leftover gct gets removed
|
||||
if (!Environment.GetCommandLineArgs().Contains("--no-gct-patch"))
|
||||
{
|
||||
e.Cancel = true;
|
||||
return;
|
||||
if (!Analyze())
|
||||
{
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// STAGE 2: Extract Brawl
|
||||
if (!Extract(pStartInfo))
|
||||
{
|
||||
@ -141,18 +149,26 @@ namespace BrawlBuilder
|
||||
{
|
||||
SetStatus("Analyzing...");
|
||||
|
||||
if (File.Exists(@".\Resources\ProjM36Patches.txt"))
|
||||
if (File.Exists(@".\Resources\CodePatches.txt"))
|
||||
{
|
||||
// First we'll read the patches we are going to make
|
||||
string[] actions = { "CHECK", "REMOVE", "PATCH", "TO" };
|
||||
string[] actions = { "REMOVE", "PATCH", "TO", "IF", "ENDIF", "REMOVE_EN" };
|
||||
string action = "";
|
||||
bool doActions = true;
|
||||
|
||||
string check = "";
|
||||
List<string> remove = new List<string>();
|
||||
List<string> patch = new List<string>();
|
||||
List<string> to = new List<string>();
|
||||
string bytesString = "";
|
||||
string patchBytesString = "";
|
||||
|
||||
foreach (string s in File.ReadLines(@".\Resources\ProjM36Patches.txt"))
|
||||
int removes = 0;
|
||||
int successfulRemoves = 0;
|
||||
|
||||
int patches = 0;
|
||||
int successfulPatches = 0;
|
||||
|
||||
// Load GCT into memory
|
||||
byte[] gctBytes = File.ReadAllBytes(gctFile.Text);
|
||||
|
||||
foreach (string s in File.ReadLines(@".\Resources\CodePatches.txt"))
|
||||
{
|
||||
string line = s.Trim();
|
||||
|
||||
@ -161,142 +177,117 @@ namespace BrawlBuilder
|
||||
|
||||
if (actions.Contains(line))
|
||||
{
|
||||
action = line;
|
||||
|
||||
switch (action)
|
||||
// Handle one-liner statements. These don't affect action
|
||||
if (line == "ENDIF")
|
||||
{
|
||||
case "CHECK":
|
||||
check = ""; // There should only be 1 check
|
||||
break;
|
||||
case "REMOVE":
|
||||
remove.Add("");
|
||||
break;
|
||||
case "PATCH":
|
||||
patch.Add("");
|
||||
break;
|
||||
case "TO":
|
||||
to.Add("");
|
||||
break;
|
||||
doActions = true; // 'IF' statement is over, start doing actions again (if they were ever stopped)
|
||||
continue;
|
||||
}
|
||||
else if (line == "REMOVE_EN" && doActions)
|
||||
{
|
||||
_remove_en = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
action = line;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!doActions)
|
||||
continue; // If we aren't doing actions just keep looping until the 'ENDIF'
|
||||
|
||||
// Handle multi-line statements
|
||||
switch (action)
|
||||
{
|
||||
case "CHECK":
|
||||
if (line == "")
|
||||
case "IF":
|
||||
if (line == "") // Blank line means end of codes block, so we can handle the 'IF' statement now.
|
||||
{
|
||||
action = "";
|
||||
|
||||
if (bytesString.Length > 0)
|
||||
{
|
||||
byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
|
||||
if (SearchBytes(gctBytes, bytes) < 1)
|
||||
doActions = false; // If code wasn't found, stop doing actions until the 'ENDIF' statement
|
||||
}
|
||||
|
||||
bytesString = "";
|
||||
}
|
||||
else
|
||||
check += line.Replace(" ", "");
|
||||
bytesString += line.Replace(" ", "");
|
||||
break;
|
||||
case "REMOVE":
|
||||
if (line == "")
|
||||
{
|
||||
action = "";
|
||||
|
||||
if (bytesString.Length > 0)
|
||||
{
|
||||
removes++;
|
||||
byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
|
||||
int index = SearchBytes(gctBytes, bytes);
|
||||
if (index >= 0)
|
||||
{
|
||||
IEnumerable<byte> before = gctBytes.Take(index);
|
||||
IEnumerable<byte> after = gctBytes.Skip(index + bytes.Length);
|
||||
|
||||
gctBytes = before.Concat(after).ToArray();
|
||||
successfulRemoves++;
|
||||
}
|
||||
|
||||
bytesString = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
remove[remove.Count - 1] += line.Replace(" ", "");
|
||||
bytesString += line.Replace(" ", "");
|
||||
break;
|
||||
case "PATCH":
|
||||
if (line == "")
|
||||
action = "";
|
||||
action = ""; // Patch is done after next 'TO'
|
||||
else
|
||||
patch[patch.Count - 1] += line.Replace(" ", "");
|
||||
patchBytesString += line.Replace(" ", "");
|
||||
break;
|
||||
case "TO":
|
||||
if (line == "")
|
||||
{
|
||||
action = "";
|
||||
|
||||
if (bytesString.Length > 0 && patchBytesString.Length > 0)
|
||||
{
|
||||
patches++;
|
||||
byte[] patchBytes = Enumerable.Range(0, patchBytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(patchBytesString.Substring(x, 2), 16)).ToArray();
|
||||
byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
|
||||
int index = SearchBytes(gctBytes, patchBytes);
|
||||
if (index >= 0)
|
||||
{
|
||||
IEnumerable<byte> before = gctBytes.Take(index);
|
||||
IEnumerable<byte> after = gctBytes.Skip(index + patchBytes.Length);
|
||||
|
||||
gctBytes = before.Concat(bytes.Concat(after)).ToArray();
|
||||
|
||||
successfulPatches++;
|
||||
}
|
||||
|
||||
bytesString = "";
|
||||
patchBytesString = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
to[to.Count - 1] += line.Replace(" ", "");
|
||||
bytesString += line.Replace(" ", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure patch has the same number of elements as to
|
||||
if (patch.Count != to.Count)
|
||||
{
|
||||
DialogResult result = MessageBox.Show("ProjM36Patches.txt contains unequal amounts of PATCH and TO statements. Do you want to continue without GCT patching? If your mod is Project M 3.6 or greater, the output ISO may not work without this.", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (result == DialogResult.No)
|
||||
buildWorker.CancelAsync();
|
||||
else
|
||||
return true;
|
||||
|
||||
if (buildWorker.CancellationPending)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert strings of hex values to byte arrays (http://stackoverflow.com/a/321404/1687909)
|
||||
byte[] checkBytes = Enumerable.Range(0, check.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(check.Substring(x, 2), 16)).ToArray();
|
||||
List<byte[]> removeBytes = new List<byte[]>();
|
||||
foreach (string hexBytes in remove)
|
||||
removeBytes.Add(Enumerable.Range(0, hexBytes.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hexBytes.Substring(x, 2), 16)).ToArray());
|
||||
|
||||
List<byte[]> patchBytes = new List<byte[]>();
|
||||
foreach (string hexBytes in patch)
|
||||
patchBytes.Add(Enumerable.Range(0, hexBytes.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hexBytes.Substring(x, 2), 16)).ToArray());
|
||||
|
||||
List<byte[]> toBytes = new List<byte[]>();
|
||||
foreach (string hexBytes in to)
|
||||
toBytes.Add(Enumerable.Range(0, hexBytes.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hexBytes.Substring(x, 2), 16)).ToArray());
|
||||
|
||||
// Load GCT into memory
|
||||
byte[] gctBytes = File.ReadAllBytes(gctFile.Text);
|
||||
|
||||
// Check for 3.6
|
||||
int index = SearchBytes(gctBytes, checkBytes);
|
||||
if (index > 0)
|
||||
{
|
||||
DialogResult r = MessageBox.Show("Project M 3.6 codes detected. This may cause issues with the output ISO. Would you like the program to attempt to fix known problem codes?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (r == DialogResult.Yes)
|
||||
_pm36patches = true;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // Not 3.6, don't need to patch gct.
|
||||
}
|
||||
|
||||
// Do removes
|
||||
int successfulRemoves = 0;
|
||||
foreach (byte[] removeArr in removeBytes)
|
||||
{
|
||||
index = SearchBytes(gctBytes, removeArr);
|
||||
if (index > 0)
|
||||
{
|
||||
IEnumerable<byte> before = gctBytes.Take(index);
|
||||
IEnumerable<byte> after = gctBytes.Skip(index + removeArr.Length);
|
||||
|
||||
gctBytes = before.Concat(after).ToArray();
|
||||
successfulRemoves++;
|
||||
}
|
||||
}
|
||||
|
||||
// Do patches
|
||||
int successfulPatches = 0;
|
||||
for (int i = 0; i < patch.Count; i++)
|
||||
{
|
||||
index = SearchBytes(gctBytes, patchBytes[i]);
|
||||
if (index > 0)
|
||||
{
|
||||
IEnumerable<byte> before = gctBytes.Take(index);
|
||||
IEnumerable<byte> after = gctBytes.Skip(index + patchBytes[i].Length);
|
||||
|
||||
gctBytes = before.Concat(toBytes[i].Concat(after)).ToArray();
|
||||
|
||||
successfulPatches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (successfulRemoves < remove.Count || successfulPatches < patch.Count)
|
||||
MessageBox.Show("There were issues fixing known problem codes:\n\nRemoved codes: " + successfulRemoves + "/" + remove.Count + "\nPatched Codes: " + successfulPatches + "/" + patch.Count + "\n\nThere may be issues with the output ISO.", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
if (Environment.GetCommandLineArgs().Contains("--notify-gct-patch"))
|
||||
MessageBox.Show("Removed codes: " + successfulRemoves + "/" + removes + "\nPatched Codes: " + successfulPatches + "/" + patches + "\nRemove '_en': " + _remove_en, "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
|
||||
File.WriteAllBytes(@".\Resources\temp.gct", gctBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
DialogResult result = MessageBox.Show("ProjM36Patches.txt not found. Do you want to continue without GCT patching? If your mod is Project M 3.6 or greater, the output ISO may not work without this.", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
DialogResult result = MessageBox.Show("CodePatches.txt not found. Do you want to continue without GCT patching? The output ISO may not work without this.", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (result == DialogResult.No)
|
||||
buildWorker.CancelAsync();
|
||||
@ -478,7 +469,7 @@ namespace BrawlBuilder
|
||||
if (Directory.Exists(modFolder.Text))
|
||||
{
|
||||
SetStatus("Copying...");
|
||||
|
||||
|
||||
// Get mod files in alphabetical order (makes alt stage checking easy)
|
||||
string[] modFilesAbsolute = Directory.GetFiles(modFolder.Text, "*", SearchOption.AllDirectories);
|
||||
Array.Sort(modFilesAbsolute);
|
||||
@ -519,15 +510,15 @@ namespace BrawlBuilder
|
||||
Directory.CreateDirectory(@"ssbb.d\files" + Path.GetDirectoryName(relativeFile)); // Just in case it doesn't already exist
|
||||
|
||||
// If we are doing alt stage, then code has been patched and we don't need the _en files
|
||||
if (!_pm36patches)
|
||||
{
|
||||
File.Copy(absoluteFile, needs_en ? @"ssbb.d\files" + relativeFile_en : @"ssbb.d\files" + relativeFile, true);
|
||||
}
|
||||
else
|
||||
if (_remove_en)
|
||||
{
|
||||
File.Copy(absoluteFile, @"ssbb.d\files" + relativeFile, true);
|
||||
File.Delete(@"ssbb.d\files" + relativeFile_en); // Get rid of those pesky space-wasting _en files, we don't need em here
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Copy(absoluteFile, needs_en ? @"ssbb.d\files" + relativeFile_en : @"ssbb.d\files" + relativeFile, true);
|
||||
}
|
||||
|
||||
_progress++;
|
||||
|
||||
@ -547,8 +538,9 @@ namespace BrawlBuilder
|
||||
while (blinker.IsBusy)
|
||||
Thread.Sleep(100);
|
||||
|
||||
// If we are doing alt stages, base stage files need to be padded to be the same size as their largest alt stage
|
||||
if (_pm36patches)
|
||||
// Base stage files need to be padded to be the same size as their largest alt stage
|
||||
// If there aren't alt stages this will do nothing
|
||||
if (!Environment.GetCommandLineArgs().Contains("--no-alt-pad"))
|
||||
{
|
||||
string[] stages = Directory.GetFiles(@"ssbb.d\files\stage\melee");
|
||||
|
||||
@ -567,7 +559,7 @@ namespace BrawlBuilder
|
||||
IEnumerable<string> altStages = stages.Where(s => Regex.IsMatch(s, filename + @"_[A-Z]\.pac$", RegexOptions.IgnoreCase));
|
||||
|
||||
// Determine the largest one (resharper converted my foreach loop. LINQ is cool.)
|
||||
long largest = altStages.Select(altStage => new FileInfo(altStage).Length).Concat(new long[] {0}).Max();
|
||||
long largest = altStages.Select(altStage => new FileInfo(altStage).Length).Concat(new long[] { 0 }).Max();
|
||||
|
||||
// If base stage is smaller, add padding to match largest alt stage
|
||||
long baseStageSize = new FileInfo(stage).Length;
|
||||
@ -640,7 +632,7 @@ namespace BrawlBuilder
|
||||
string patchArgs = "";
|
||||
string gct = gctFile.Text;
|
||||
|
||||
if (_pm36patches)
|
||||
if (File.Exists(@".\Resources\temp.gct"))
|
||||
gct = @".\Resources\temp.gct";
|
||||
|
||||
if (File.Exists(gct))
|
||||
@ -781,11 +773,15 @@ namespace BrawlBuilder
|
||||
if (curStatus == null)
|
||||
{
|
||||
// This should only happen if p is killed, but just in case
|
||||
p.Kill();
|
||||
p.WaitForExit(5000);
|
||||
if (!p.HasExited)
|
||||
{
|
||||
p.Kill();
|
||||
p.WaitForExit(5000);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Match m = r.Match(curStatus);
|
||||
|
||||
if (m.Groups.Count > 1)
|
||||
@ -797,8 +793,11 @@ namespace BrawlBuilder
|
||||
blinker.CancelAsync();
|
||||
|
||||
// Kill process
|
||||
p.Kill();
|
||||
p.WaitForExit(5000);
|
||||
if (!p.HasExited)
|
||||
{
|
||||
p.Kill();
|
||||
p.WaitForExit(5000);
|
||||
}
|
||||
|
||||
// Didn't finish working, delete ssbb.d
|
||||
DeleteBrawlFolder();
|
||||
@ -887,11 +886,11 @@ namespace BrawlBuilder
|
||||
if (e.Cancelled != true)
|
||||
MessageBox.Show("Build Completed!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
|
||||
private void blinker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
string statusBack = _curStatus;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 'Sleep' for ~2000ms, but cancel faster
|
||||
|
@ -54,7 +54,7 @@ namespace BrawlBuilder
|
||||
exit.Invalidate();
|
||||
Update();
|
||||
|
||||
for (double i = Opacity; i < 1; i += 0.01)
|
||||
for (double i = Opacity; i <= 1; i += 0.01)
|
||||
{
|
||||
Opacity = i;
|
||||
Thread.Sleep(8);
|
||||
@ -180,19 +180,22 @@ namespace BrawlBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
if (modFolder.Text != "" && !Directory.Exists(modFolder.Text))
|
||||
if (modFolder.Text != "")
|
||||
{
|
||||
MessageBox.Show("Mod folder location is invalid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
string[] brawlFolders = {"effect", "fighter", "game", "info", "info2", "item", "item_gen", "menu", "menu2", "minigame", "module", "movie", "net", "sound", "stage", "system", "toy"};
|
||||
if (!Directory.GetDirectories(modFolder.Text).Any(d => brawlFolders.Contains(new DirectoryInfo(d).Name)))
|
||||
{
|
||||
DialogResult badfolder = MessageBox.Show("It doesn't look like the mod folder you selected contains any replacement Brawl files, are you sure you selected the right foler? Usually it will be called 'pf'.\n\nDo you still want to attempt the build using the selected folder?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (badfolder == DialogResult.No)
|
||||
if (!Directory.Exists(modFolder.Text))
|
||||
{
|
||||
MessageBox.Show("Mod folder location is invalid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
string[] brawlFolders = { "effect", "fighter", "game", "info", "info2", "item", "item_gen", "menu", "menu2", "minigame", "module", "movie", "net", "sound", "stage", "system", "toy" };
|
||||
if (!Directory.GetDirectories(modFolder.Text).Any(d => brawlFolders.Contains(new DirectoryInfo(d).Name)))
|
||||
{
|
||||
DialogResult badfolder = MessageBox.Show("It doesn't look like the mod folder you selected contains any replacement Brawl files, are you sure you selected the right foler? Usually it will be called 'pf'.\n\nDo you still want to attempt the build using the selected folder?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (badfolder == DialogResult.No)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gctFile.Text != "" && !File.Exists(gctFile.Text))
|
||||
@ -201,9 +204,9 @@ namespace BrawlBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
if (customID.Checked && !Regex.IsMatch(gameID.Text, "^[a-zA-Z0-9_]{6}$"))
|
||||
if (customID.Checked && !Regex.IsMatch(gameID.Text, "^[A-Z0-9_]{6}$"))
|
||||
{
|
||||
MessageBox.Show("Game ID must be 6 characters and be made up of some combination of A-Z, 0-9, and underscores. No other characters are allowed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
MessageBox.Show("Game ID must be 6 characters and be made up of some combination of A-Z (uppercase only), 0-9, and underscores. No other characters are allowed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Ookii.Dialogs">
|
||||
<HintPath>..\Resources\Ookii.Dialogs.dll</HintPath>
|
||||
@ -96,6 +99,10 @@
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy "$(SolutionDir)Resources" "$(TargetDir)Resources" /s/h/e/k/q/i/y</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
120
Resources/CodePatches.txt
Normal file
120
Resources/CodePatches.txt
Normal file
@ -0,0 +1,120 @@
|
||||
### This file contains patches that get applied to the GCT file.
|
||||
###
|
||||
### Description of statement blocks:
|
||||
### REMOVE blocks will remove all occurences of their code from the GCT
|
||||
### PATCH/TO blocks will replace all occurences of the PATCH code with the TO code
|
||||
### IF/ENDIF sections will only apply the codes inside them if the IF code exists
|
||||
###
|
||||
### Note: All blocks (except for PATCH, which can be followed immediately by TO) must
|
||||
### have at least one blank (or commented) line after them.
|
||||
|
||||
# Individual Stock Icons fix, solves P:M 3.6 not booting.
|
||||
REMOVE
|
||||
044218EC 00095F00
|
||||
0442190C 00180000
|
||||
04494990 00095F00
|
||||
044949EC 80C23A60
|
||||
044949F0 00180000
|
||||
|
||||
PATCH
|
||||
7FFCFB78 3D8080C2
|
||||
A18C4314 3BA05F65
|
||||
TO
|
||||
7FFCFB78 3D8080C3
|
||||
A18CD114 3BA05F65
|
||||
# End of Individual Stock Icons fix.
|
||||
|
||||
|
||||
# File patch code mods:
|
||||
|
||||
# This loads files from disc instead of SD, allowing for alt stages in Project M 3.6.
|
||||
# The IF is checking for part of the alternate stage loader.
|
||||
IF
|
||||
91620000 90E20004
|
||||
91820008 90620010
|
||||
91220014 3C607072
|
||||
60636F6A 80E10020
|
||||
|
||||
# This tells BrawlBuilder to not add the _en suffix when copying files.
|
||||
REMOVE_EN
|
||||
|
||||
PATCH
|
||||
065A7E00 00000070
|
||||
TO
|
||||
065A7E00 00000088
|
||||
|
||||
PATCH
|
||||
38610088 4BA74DB9
|
||||
7C7C1B78 2C030000
|
||||
4082000C 38210080
|
||||
4800001C B8410008
|
||||
38210080 4BE524E5
|
||||
38610008 4BA742E1
|
||||
7C7C1B78 4BA741E8
|
||||
TO
|
||||
38610088 80830000
|
||||
3884000C 90830000
|
||||
4BA742FD 7C7C1B78
|
||||
2C030000 4082000C
|
||||
38210080 48000028
|
||||
B8410008 38210080
|
||||
4BE524D9 38610008
|
||||
80830000 3884FFF4
|
||||
90830000 4BA742C9
|
||||
7C7C1B78 4BA741D0
|
||||
|
||||
ENDIF
|
||||
|
||||
# This makes the /sfx/ files load from DVD instead of SD.
|
||||
# First IF is for the Project M version of the soundbank engine.
|
||||
IF
|
||||
2F70726F 6A656374
|
||||
6D2F7066 2F736678
|
||||
|
||||
PATCH
|
||||
90810018 3880FFFF
|
||||
9081001C 38610020
|
||||
90610008 7CE43B78
|
||||
38A00080 4BE529F5
|
||||
38610008 4BA752A1
|
||||
TO
|
||||
90810018 38800000
|
||||
9081001C 38610020
|
||||
90610008 7CE43B78
|
||||
38A00080 4BE529F5
|
||||
38610008 4BA747F1
|
||||
|
||||
PATCH
|
||||
60847D18 7F45D378
|
||||
TO
|
||||
60847D24 7F45D378
|
||||
|
||||
ENDIF
|
||||
|
||||
# And this one is for the regular soundbank engine.
|
||||
IF
|
||||
2F525342 452F7066
|
||||
2F736678
|
||||
|
||||
PATCH
|
||||
90810018 3880FFFF
|
||||
9081001C 38610020
|
||||
90610008 7CE43B78
|
||||
38A00080 4BE529F5
|
||||
38610008 4BA752A1
|
||||
TO
|
||||
90810018 38800000
|
||||
9081001C 38610020
|
||||
90610008 7CE43B78
|
||||
38A00080 4BE529F5
|
||||
38610008 4BA747F1
|
||||
|
||||
PATCH
|
||||
60847D18 7F45D378
|
||||
TO
|
||||
60847D30 7F45D378
|
||||
|
||||
ENDIF
|
||||
# End of File Patch Code mods.
|
||||
|
||||
### Make sure you have a blank line somewhere after the final statement.
|
@ -1,73 +0,0 @@
|
||||
# This check is part of the alternate stage loader.
|
||||
# If it's there we are asuming we are on 3.6
|
||||
CHECK
|
||||
91620000 90E20004
|
||||
91820008 90620010
|
||||
91220014 3C607072
|
||||
60636F6A 80E10020
|
||||
|
||||
REMOVE
|
||||
044218EC 00095F00
|
||||
0442190C 00180000
|
||||
04494990 00095F00
|
||||
044949EC 80C23A60
|
||||
044949F0 00180000
|
||||
|
||||
PATCH
|
||||
7FFCFB78 3D8080C2
|
||||
A18C4314 3BA05F65
|
||||
|
||||
TO
|
||||
7FFCFB78 3D8080C3
|
||||
A18CD114 3BA05F65
|
||||
|
||||
PATCH
|
||||
065A7E00 00000070
|
||||
38A00067 38810020
|
||||
3CE0805A 60E37C0C
|
||||
4BE52531 38A0007F
|
||||
3883FFF5 38610020
|
||||
4BE52521 38A00068
|
||||
60E47C0C 38610020
|
||||
9421FF80 BC410008
|
||||
38610088 4BA74DB9
|
||||
7C7C1B78 2C030000
|
||||
4082000C 38210080
|
||||
4800001C B8410008
|
||||
38210080 4BE524E5
|
||||
38610008 4BA742E1
|
||||
7C7C1B78 4BA741E8
|
||||
040223E0 48585BC0
|
||||
065A7FA0 00000028
|
||||
80010044 3C608001
|
||||
6063581C 7C001800
|
||||
4082000C 7FDDC850
|
||||
3BDEFFE0 93DB0008
|
||||
4BA7A424 00000000
|
||||
|
||||
TO
|
||||
065A7E00 00000088
|
||||
38A00067 38810020
|
||||
3CE0805A 60E37C0C
|
||||
4BE52531 38A0007F
|
||||
3883FFF5 38610020
|
||||
4BE52521 38A00068
|
||||
60E47C0C 38610020
|
||||
9421FF80 BC410008
|
||||
38610088 80830000
|
||||
3884000C 90830000
|
||||
4BA742FD 7C7C1B78
|
||||
2C030000 4082000C
|
||||
38210080 48000028
|
||||
B8410008 38210080
|
||||
4BE524D9 38610008
|
||||
80830000 3884FFF4
|
||||
90830000 4BA742C9
|
||||
7C7C1B78 4BA741D0
|
||||
040223E0 48585BC0
|
||||
065A7FA0 00000028
|
||||
80010044 3C608001
|
||||
6063581C 7C001800
|
||||
4082000C 7FDDC850
|
||||
3BDEFFE0 93DB0008
|
||||
4BA7A424 00000000
|
Loading…
x
Reference in New Issue
Block a user