Skip to content

Commit

Permalink
Add GenerateDefaultTagData & GenerateTagData Methods
Browse files Browse the repository at this point in the history
Allows dynamic generation of the Game ID (GID) and Game Name (GNM) tags. The GenerateTagData can take any valid tags.
  • Loading branch information
Cuyler36 committed Jul 5, 2018
1 parent d29b851 commit 7e04d93
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
2 changes: 1 addition & 1 deletion ACNESCreator.CommandLine/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void Main(string[] args)
int RegionIdx = Array.IndexOf(RegionCodes, args[2].ToUpper());
if (RegionIdx > -1)
{
NES NESFile = new NES(args[0], File.ReadAllBytes(args[1]), (Region)RegionIdx, false, false);
NES NESFile = new NES(args[0], File.ReadAllBytes(args[1]), false, (Region)RegionIdx, false);

string OutputFile = Path.GetDirectoryName(args[1]) + "\\" + args[0] + "_" + args[2].ToUpper() + "_InjectedData.gci";
using (var Stream = new FileStream(OutputFile, FileMode.OpenOrCreate))
Expand Down
81 changes: 76 additions & 5 deletions ACNESCreator.Core/NES.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ public class NES

const byte DefaultFlags1 = 0xEA;
const byte DefaultFlags2 = 0;
const string DefaultTagData = "END\0";
readonly string[] RegionCodes = new string[4] { "J", "E", "P", "U" };
static readonly byte[] DefaultTagData = Encoding.ASCII.GetBytes("TAG\0" + "GNO\0x1F" + "END\0");
static readonly string[] RegionCodes = new string[4] { "J", "E", "P", "U" };
static readonly string[] TagList = new string[]
{
"END", "VEQ", "VNE", "GID", "GNM", "CPN", "OFS", "HSC",
"GNO", "BBR", "QDS", "SPE", "ISZ", "IFM", "REM", "TCS",
"ICS", "ESZ", "FIL", "ROM", "MOV", "NHD", "DIF", "PAT"
};

public class ACNESHeader
{
Expand Down Expand Up @@ -90,7 +96,7 @@ public ushort GetSize()
}

public readonly ACNESHeader Header;
public readonly byte[] TagData;
public byte[] TagData { get; internal set; }
public readonly Banner BannerData;
public readonly byte[] ROM;

Expand Down Expand Up @@ -135,7 +141,7 @@ public NES(string ROMName, byte[] ROMData, Region ACRegion, bool Compress, bool
MaxROMSize.ToString("X"), MaxROMSize.ToString("N0")));
}

TagData = Utility.GetPaddedStringData(DefaultTagData, (DefaultTagData.Length + 0xF) & ~0xF);
TagData = Utility.GetPaddedData(DefaultTagData, (DefaultTagData.Length + 0xF) & ~0xF);

BannerData = new Banner
{
Expand All @@ -157,8 +163,10 @@ public NES(string ROMName, byte[] ROMData, Region ACRegion, bool Compress, bool
};

ROM = ROMData;

GameRegion = ACRegion;

// Generate custom tag data if possible
GenerateDefaultTagData(ROMName);
}

public NES(string ROMName, byte[] ROMData, bool CanSave, Region ACRegion, bool Compress, bool IsDnMe, byte[] IconData = null)
Expand Down Expand Up @@ -186,6 +194,69 @@ internal void SetChecksum(ref byte[] Data)
Data[0x680] = (byte)-Checksum;
}

internal void GenerateDefaultTagData(string GameName)
{
if (GameName.Length > 1)
{
GameName = GameName.Trim().ToUpper();
Dictionary<string, byte[]> Tags = new Dictionary<string, byte[]>
{
{ "GID", Encoding.ASCII.GetBytes(GameName.Substring(0, 1) + GameName.Substring(GameName.Length - 1, 1)) },
{ "GNM", Encoding.ASCII.GetBytes(GameName) },
{ "GNO", new byte[1] { 0x1F } },
{ "END", new byte[0] }
};

GenerateTagData(Tags);
}
}

public void GenerateTagData(Dictionary<string, byte[]> Tags)
{
bool HasEND = false;

// The first tag is printed and then ignored, so we can put whatever we want here
string TagString = "TAG\0";
foreach (var TagInfo in Tags)
{
// Ensure the tag is capitalized
string Tag = TagInfo.Key.ToUpper();

// Confirm the tag is valid
if (Array.IndexOf(TagList, Tag) > -1)
{
// Add the tag
TagString += Tag;

if (Tag == "END")
{
HasEND = true;
}

// Add the tag data length
TagString += (char)(TagInfo.Value.Length & 0xFF);

// Add the tag data
for (int i = 0; i < TagInfo.Value.Length; i++)
{
TagString += (char)TagInfo.Value[i];
}
}
}

// Ensure that an END tag is present so the parser will stop
if (!HasEND)
{
TagString += "END\0";
}

byte[] TagBinaryData = Encoding.ASCII.GetBytes(TagString);
TagBinaryData = Utility.GetPaddedData(TagBinaryData, (TagBinaryData.Length + 0xF) & ~0xF);

Header.TagsSize = (ushort)TagBinaryData.Length;
TagData = TagBinaryData;
}

public byte[] GenerateGCIFile()
{
List<byte> Data = new List<byte>();
Expand Down

0 comments on commit 7e04d93

Please sign in to comment.