initial commit
This commit is contained in:
parent
13e19258e0
commit
269514038c
8 changed files with 1772 additions and 0 deletions
122
MainForm.Designer.cs
generated
Normal file
122
MainForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,122 @@
|
|||
namespace SharpCreditsCrediter
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
bLoadROM = new Button();
|
||||
bExtract = new Button();
|
||||
bImport = new Button();
|
||||
rIsZM = new RadioButton();
|
||||
rIsFusion = new RadioButton();
|
||||
SuspendLayout();
|
||||
//
|
||||
// bLoadROM
|
||||
//
|
||||
bLoadROM.Location = new Point(12, 12);
|
||||
bLoadROM.Name = "bLoadROM";
|
||||
bLoadROM.Size = new Size(154, 23);
|
||||
bLoadROM.TabIndex = 0;
|
||||
bLoadROM.Text = "Load ROM";
|
||||
bLoadROM.UseVisualStyleBackColor = true;
|
||||
bLoadROM.Click += bLoadROM_Click;
|
||||
//
|
||||
// bExtract
|
||||
//
|
||||
bExtract.Enabled = false;
|
||||
bExtract.Location = new Point(12, 70);
|
||||
bExtract.Name = "bExtract";
|
||||
bExtract.Size = new Size(154, 23);
|
||||
bExtract.TabIndex = 1;
|
||||
bExtract.Text = "Extract";
|
||||
bExtract.UseVisualStyleBackColor = true;
|
||||
bExtract.Click += bExtract_Click;
|
||||
//
|
||||
// bImport
|
||||
//
|
||||
bImport.Enabled = false;
|
||||
bImport.Location = new Point(12, 41);
|
||||
bImport.Name = "bImport";
|
||||
bImport.Size = new Size(154, 23);
|
||||
bImport.TabIndex = 2;
|
||||
bImport.Text = "Import";
|
||||
bImport.UseVisualStyleBackColor = true;
|
||||
bImport.Click += bImport_Click;
|
||||
//
|
||||
// rIsZM
|
||||
//
|
||||
rIsZM.AutoSize = true;
|
||||
rIsZM.Checked = true;
|
||||
rIsZM.Enabled = false;
|
||||
rIsZM.Location = new Point(172, 14);
|
||||
rIsZM.Name = "rIsZM";
|
||||
rIsZM.Size = new Size(93, 19);
|
||||
rIsZM.TabIndex = 3;
|
||||
rIsZM.TabStop = true;
|
||||
rIsZM.Text = "Zero Mission";
|
||||
rIsZM.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// rIsFusion
|
||||
//
|
||||
rIsFusion.AutoSize = true;
|
||||
rIsFusion.Enabled = false;
|
||||
rIsFusion.Location = new Point(172, 43);
|
||||
rIsFusion.Name = "rIsFusion";
|
||||
rIsFusion.Size = new Size(60, 19);
|
||||
rIsFusion.TabIndex = 4;
|
||||
rIsFusion.Text = "Fusion";
|
||||
rIsFusion.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(302, 110);
|
||||
Controls.Add(rIsFusion);
|
||||
Controls.Add(rIsZM);
|
||||
Controls.Add(bImport);
|
||||
Controls.Add(bExtract);
|
||||
Controls.Add(bLoadROM);
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
Name = "MainForm";
|
||||
Text = "SharpCreditsCrediter";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Button bLoadROM;
|
||||
private Button bExtract;
|
||||
private Button bImport;
|
||||
private RadioButton rIsZM;
|
||||
private RadioButton rIsFusion;
|
||||
}
|
||||
}
|
134
MainForm.cs
Normal file
134
MainForm.cs
Normal file
|
@ -0,0 +1,134 @@
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SharpCreditsCrediter
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private ROMFile? curROM;
|
||||
private string? curROMPath;
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void bLoadROM_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog()
|
||||
{
|
||||
Filter = "GBA ROMs (*.gba)|*.gba",
|
||||
Title = "Open the ROM"
|
||||
};
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (curROM != null)
|
||||
{
|
||||
curROM.changeFile(ofd.FileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
curROM = new ROMFile(ofd.FileName);
|
||||
}
|
||||
curROMPath = ofd.FileName;
|
||||
bExtract.Enabled = bImport.Enabled = curROM.isLoaded();
|
||||
rIsZM.Checked = curROM.getisZM();
|
||||
rIsFusion.Checked = !curROM.getisZM();
|
||||
MessageBox.Show("ROM loaded successfully.\nProbed game: " + (curROM.getisZM() ? "Zero Mission" : "Fusion"), "SCC", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Cannot load ROM: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bExtract_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog()
|
||||
{
|
||||
Filter = "Credits text (*.txt)|*.txt",
|
||||
Title = "Open the text file",
|
||||
CheckFileExists = false
|
||||
};
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.UseWaitCursor = true;
|
||||
FileStream creditsFile = new FileStream(ofd.FileName, FileMode.Create);
|
||||
#pragma warning disable CS8602 // if this button is enabled, curROM is already != null
|
||||
creditsFile.Write(Encoding.ASCII.GetBytes(curROM.getCredits()));
|
||||
#pragma warning restore CS8602
|
||||
creditsFile.Dispose();
|
||||
this.UseWaitCursor = false;
|
||||
MessageBox.Show("Credits exported successfully.", "SCC", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.UseWaitCursor = false;
|
||||
MessageBox.Show("Could not open file: " + ex.Message, "SCC", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bImport_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog()
|
||||
{
|
||||
Filter = "Credits text (*.txt)|*.txt",
|
||||
Title = "Open the text file"
|
||||
};
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamReader creditsFile = new StreamReader(ofd.FileName);
|
||||
|
||||
OpenFileDialog ofdOutput = new OpenFileDialog()
|
||||
{
|
||||
Filter = "GBA ROMs (*.gba)|*.gba",
|
||||
Title = "Open the output ROM",
|
||||
CheckFileExists = false
|
||||
};
|
||||
|
||||
if (ofdOutput.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
this.UseWaitCursor = true;
|
||||
#pragma warning disable CS8602 // if this button is enabled, curROM
|
||||
#pragma warning disable CS8604 // and curROMPath are already != null
|
||||
curROM.Dispose();
|
||||
File.Copy(curROMPath, ofdOutput.FileName, true);
|
||||
curROM.changeFile(ofdOutput.FileName);
|
||||
#pragma warning restore CS8604
|
||||
|
||||
if (curROM.writeCredits(creditsFile))
|
||||
{
|
||||
this.UseWaitCursor = false;
|
||||
MessageBox.Show("Credits imported successfully.", "SCC", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.UseWaitCursor = false;
|
||||
MessageBox.Show("Failed to import the credits.", "SCC", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
#pragma warning restore CS8602
|
||||
curROM.changeFile(curROMPath);
|
||||
creditsFile.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.UseWaitCursor = false;
|
||||
MessageBox.Show("Could not open file: " + ex.Message, "SCC", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1253
MainForm.resx
Normal file
1253
MainForm.resx
Normal file
File diff suppressed because it is too large
Load diff
17
Program.cs
Normal file
17
Program.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace SharpCreditsCrediter
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
192
ROMFile.cs
Normal file
192
ROMFile.cs
Normal file
|
@ -0,0 +1,192 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpCreditsCrediter
|
||||
{
|
||||
internal class ROMFile
|
||||
{
|
||||
private FileStream? romFile;
|
||||
const long ZM_credits_start = 0x54C10C;
|
||||
const long ZM_credits_end = 0x54E2A9;
|
||||
const long MF_credits_start = 0x74B0B0;
|
||||
const long MF_credits_end = 0x74DC25;
|
||||
private bool isZM = true;
|
||||
|
||||
private readonly Dictionary<char, int> textToIntTable = new Dictionary<char, int>() {
|
||||
{ ' ', 0x20 }, { 'A', 0x41 }, { 'B', 0x42 }, { 'C', 0x43 }, { 'D', 0x44 }, { 'E', 0x45 }, { 'F', 0x46 }, { 'G', 0x47 },
|
||||
{ 'H', 0x48 }, { 'I', 0x49 }, { 'J', 0x4A }, { 'K', 0x4B }, { 'L', 0x4C }, { 'M', 0x4D }, { 'N', 0x4E }, { 'O', 0x4F },
|
||||
{ 'P', 0x50 }, { 'Q', 0x51 }, { 'R', 0x52 }, { 'S', 0x53 }, { 'T', 0x54 }, { 'U', 0x55 }, { 'V', 0x56 }, { 'W', 0x57 },
|
||||
{ 'X', 0x58 }, { 'Y', 0x59 }, { 'Z', 0x5A }, { 'a', 0x61 }, { 'b', 0x62 }, { 'c', 0x63 }, { 'd', 0x64 }, { 'e', 0x65 },
|
||||
{ 'f', 0x66 }, { 'g', 0x67 }, { 'h', 0x68 }, { 'i', 0x69 }, { 'j', 0x6A }, { 'k', 0x6B }, { 'l', 0x6C }, { 'm', 0x6D },
|
||||
{ 'n', 0x6E }, { 'o', 0x6F }, { 'p', 0x70 }, { 'q', 0x71 }, { 'r', 0x72 }, { 's', 0x73 }, { 't', 0x74 }, { 'u', 0x75 },
|
||||
{ 'v', 0x76 }, { 'w', 0x77 }, { 'x', 0x78 }, { 'y', 0x79 }, { 'z', 0x7A }, { '&', 0x26 }
|
||||
};
|
||||
|
||||
private readonly Dictionary<int, string> intToTextTable = new Dictionary<int, string>() {
|
||||
{ 0x20, " " }, { 0x41, "A" }, { 0x42, "B" }, { 0x43, "C" }, { 0x44, "D" }, { 0x45, "E" }, { 0x46, "F" }, { 0x47, "G" },
|
||||
{ 0x48, "H" }, { 0x49, "I" }, { 0x4A, "J" }, { 0x4B, "K" }, { 0x4C, "L" }, { 0x4D, "M" }, { 0x4E, "N" }, { 0x4F, "O" },
|
||||
{ 0x50, "P" }, { 0x51, "Q" }, { 0x52, "R" }, { 0x53, "S" }, { 0x54, "T" }, { 0x55, "U" }, { 0x56, "V" }, { 0x57, "W" },
|
||||
{ 0x58, "X" }, { 0x59, "Y" }, { 0x5A, "Z" }, { 0x61, "a" }, { 0x62, "b" }, { 0x63, "c" }, { 0x64, "d" }, { 0x65, "e" },
|
||||
{ 0x66, "f" }, { 0x67, "g" }, { 0x68, "h" }, { 0x69, "i" }, { 0x6A, "j" }, { 0x6B, "k" }, { 0x6C, "l" }, { 0x6D, "m" },
|
||||
{ 0x6E, "n" }, { 0x6F, "o" }, { 0x70, "p" }, { 0x71, "q" }, { 0x72, "r" }, { 0x73, "s" }, { 0x74, "t" }, { 0x75, "u" },
|
||||
{ 0x76, "v" }, { 0x77, "w" }, { 0x78, "x" }, { 0x79, "y" }, { 0x7A, "z" }, { 0x26, "&" }
|
||||
};
|
||||
|
||||
private string intToText(int value)
|
||||
{
|
||||
try {
|
||||
return intToTextTable[value];
|
||||
} catch(Exception)
|
||||
{
|
||||
return String.Format("{0:X2}", Convert.ToInt32(value));
|
||||
}
|
||||
}
|
||||
|
||||
private int textToInt(char value)
|
||||
{
|
||||
try
|
||||
{
|
||||
return textToIntTable[value];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public ROMFile(String pathToROM)
|
||||
{
|
||||
this.changeFile(pathToROM);
|
||||
}
|
||||
private void probeGame()
|
||||
{
|
||||
if(this.isLoaded())
|
||||
{
|
||||
#pragma warning disable CS8602 // isLoaded checks already if romFile is null or not
|
||||
byte[] gameCodeBuf = new byte[4];
|
||||
romFile.Position = 0xAC;
|
||||
if (romFile.Read(gameCodeBuf, 0, 4) == 4)
|
||||
{
|
||||
string gameCode = Encoding.ASCII.GetString(gameCodeBuf);
|
||||
if (gameCode == "AMTE")
|
||||
{
|
||||
this.isZM = false;
|
||||
} else
|
||||
{
|
||||
this.isZM = true;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS8602
|
||||
}
|
||||
}
|
||||
public void changeFile(String pathToROM)
|
||||
{
|
||||
if (this.isLoaded()) this.Dispose();
|
||||
romFile = File.Open(pathToROM, FileMode.Open);
|
||||
this.probeGame();
|
||||
}
|
||||
|
||||
public bool isLoaded()
|
||||
{
|
||||
return romFile != null;
|
||||
}
|
||||
|
||||
public void setisZM(bool isZM)
|
||||
{
|
||||
this.isZM = isZM;
|
||||
}
|
||||
|
||||
public bool getisZM()
|
||||
{
|
||||
return isZM;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
romFile?.Dispose();
|
||||
}
|
||||
|
||||
public String getCredits()
|
||||
{
|
||||
string credits = "";
|
||||
if (romFile != null)
|
||||
{
|
||||
long credits_start = isZM ? ZM_credits_start : MF_credits_start;
|
||||
long credits_end = isZM ? ZM_credits_end : MF_credits_end;
|
||||
romFile.Position = credits_start;
|
||||
|
||||
bool end_reached = false;
|
||||
while (romFile.Position < credits_end && !end_reached)
|
||||
{
|
||||
int curChar = romFile.ReadByte();
|
||||
if (curChar == 6) end_reached = true;
|
||||
|
||||
credits += intToText(curChar) + " ";
|
||||
|
||||
for (int i = 0; i < 35; i++)
|
||||
{
|
||||
curChar = romFile.ReadByte();
|
||||
if (curChar != 0)
|
||||
credits += intToText(curChar);
|
||||
}
|
||||
|
||||
credits += Environment.NewLine;
|
||||
}
|
||||
}
|
||||
return credits;
|
||||
}
|
||||
|
||||
public bool writeCredits(StreamReader credits)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (romFile != null && credits != null)
|
||||
{
|
||||
long credits_start = isZM ? ZM_credits_start : MF_credits_start;
|
||||
romFile.Position = credits_start;
|
||||
|
||||
while (!credits.EndOfStream)
|
||||
{
|
||||
var currentLine = credits.ReadLine();
|
||||
if (currentLine != null)
|
||||
{
|
||||
if (currentLine.Length > 38) {
|
||||
currentLine = currentLine[..38];
|
||||
}
|
||||
|
||||
// get line marker byte
|
||||
int markerByte = Convert.ToInt32(currentLine[0..2], 16);
|
||||
|
||||
romFile.WriteByte((byte)markerByte);
|
||||
if (markerByte == 6) break;
|
||||
|
||||
if (currentLine.Length > 3)
|
||||
{
|
||||
byte[] actualText = Encoding.ASCII.GetBytes(currentLine[3..]);
|
||||
List<byte> textBytes = new List<byte>();
|
||||
|
||||
foreach (byte b in actualText)
|
||||
textBytes.Add((byte)textToInt((char)b));
|
||||
|
||||
foreach (byte c in textBytes)
|
||||
{
|
||||
romFile.WriteByte(c);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 38 - currentLine.Length; i++) romFile.WriteByte(0);
|
||||
}
|
||||
}
|
||||
romFile.Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
SharpCreditsCrediter.csproj
Normal file
29
SharpCreditsCrediter.csproj
Normal file
|
@ -0,0 +1,29 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<StartupObject>SharpCreditsCrediter.Program</StartupObject>
|
||||
<ApplicationIcon>fryble.ico</ApplicationIcon>
|
||||
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
||||
<EnableNETAnalyzers>False</EnableNETAnalyzers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="fryble.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
25
SharpCreditsCrediter.sln
Normal file
25
SharpCreditsCrediter.sln
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.7.34221.43
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpCreditsCrediter", "SharpCreditsCrediter.csproj", "{4EE92768-0DFE-4839-A4D5-E519E4C3E284}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4EE92768-0DFE-4839-A4D5-E519E4C3E284}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4EE92768-0DFE-4839-A4D5-E519E4C3E284}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4EE92768-0DFE-4839-A4D5-E519E4C3E284}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4EE92768-0DFE-4839-A4D5-E519E4C3E284}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2584821E-7577-4D28-B423-71E0D3E1ECA6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
fryble.ico
Normal file
BIN
fryble.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Loading…
Reference in a new issue