Skip to content

Commit

Permalink
Support BCD raw values. Added a few more
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim-zhao committed Dec 24, 2021
1 parent 141c5fe commit b142985
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 40 deletions.
62 changes: 55 additions & 7 deletions editor/Cartridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public enum Types { TileSet, Palette, TileMap, SpriteTileSet, ForegroundTileMap,
public List<Point> TileGrouping { get; init; }
public int TilesPerRow { get; init; } = 16; // 16 is often the best default
public bool Hidden { get; init; }
public RawValue.Encodings Encoding { get; set; }

// These are in the original ROM, not where we loaded from
public int OriginalOffset { get; init; }
Expand Down Expand Up @@ -281,19 +282,22 @@ public int GetLength(Memory memory)
"Title screen music", new Game.Asset {
OriginalOffset = 0x12d8 + 1, // ld a,$06 ; 0012D8 3E 06
OriginalSize = 1,
Type = Game.Asset.Types.RawValue
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Byte
}
}, {
"Title screen \"PRESS BUTTON\" flash time", new Game.Asset {
OriginalOffset = 0x1308 + 1, // cp $40 ; 001308 FE 40
OriginalSize = 1,
Type = Game.Asset.Types.RawValue
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Byte
}
}, {
"Title screen \"PRESS BUTTON\" total time", new Game.Asset {
OriginalOffset = 0x12fd + 1, // cp $64 ; 0012FD FE 64
OriginalSize = 1,
Type = Game.Asset.Types.RawValue
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Byte
}
}, {
"Title screen palette", new Game.Asset {
Expand All @@ -306,6 +310,26 @@ public int GetLength(Memory memory)
},
Restrictions = { MaximumOffset = 0x4000 }
}
}, {
"Game Over: Continue top", new Game.Asset {
OriginalOffset = 0x14e6,
OriginalSize = 11,
Type = Game.Asset.Types.TileMapData,
References = new List<Game.Reference> {
new() {Offset = 0x147f + 1, Type = Game.Reference.Types.Absolute}, // ld hl,$14e6 ; 00147F 21 E6 14
},
Restrictions = { MaximumOffset = 0x4000 }
}
}, {
"Game Over: Continue bottom", new Game.Asset {
OriginalOffset = 0x14f1,
OriginalSize = 11,
Type = Game.Asset.Types.TileMapData,
References = new List<Game.Reference> {
new() {Offset = 0x1485 + 1, Type = Game.Reference.Types.Absolute}, // ld hl,$14f1 ; 001485 21 F1 14
},
Restrictions = { MaximumOffset = 0x4000 }
}
}, {
"Game Over palette", new Game.Asset {
OriginalOffset = 0x14fc,
Expand Down Expand Up @@ -438,6 +462,22 @@ public int GetLength(Memory memory)
},
Restrictions = { MaximumOffset = 0x4000 }
}
}, {
"Starting lives count", new Game.Asset
{
OriginalOffset = 0x1c4e + 1, // ld a,$03 ; 001C4E 3E 03
OriginalSize = 1,
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Byte
}
}, {
"Extra life at n x 10,000 points", new Game.Asset
{
OriginalOffset = 0x1c53 + 1, // ld a,$05 ; 001C53 3E 05
OriginalSize = 1,
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Bcd
}
}, {
"Ending palette", new Game.Asset {
OriginalOffset = 0x2828,
Expand All @@ -461,6 +501,14 @@ public int GetLength(Memory memory)
},
Restrictions = { MaximumOffset = 0x4000 }
}
}, {
"Extra life every n x 10,000 subsequent points", new Game.Asset
{
OriginalOffset = 0x39f6 + 1, // ld a,$05 ; 0039F6 3E 05
OriginalSize = 1,
Type = Game.Asset.Types.RawValue,
Encoding = RawValue.Encodings.Bcd
}
}, {
"End sign palette", new Game.Asset {
OriginalOffset = 0x626c,
Expand Down Expand Up @@ -1008,9 +1056,9 @@ public int GetLength(Memory memory)
{ "Map screen 2", new [] { "Map screen 2 tileset", "Map screen 2 tilemap 1", "Map screen 2 tilemap 2", "Map screen 2 palette", "Map screen 2 sprite tiles", "HUD sprite tiles", "Map screen text: Labyrinth", "Map screen text: Scrap Brain", "Map screen text: Sky Base" } },
{ "Sonic", new[] { "Sonic (right)", "Sonic (left)", "HUD sprite tiles", "Green Hill palette" } }, // HUD sprites contain the spring jump toes, the ones in the art seem unused...
{ "Monitors", new [] { "Monitor Art", "HUD sprite tiles", "Green Hill palette" } }, // Monitor bases are in the HUD sprites
{ "Title screen", new [] { "Title screen tiles", "Title screen sprites", "Title screen palette", "Title screen tilemap", "Title screen press button text 1", "Title screen press button text 2", "Title screen music", "Title screen \"PRESS BUTTON\" flash time", "Title screen \"PRESS BUTTON\" total time" } },
{ "Game Over", new [] { "Act Complete tiles", "Game Over palette", "Game Over tilemap" } },
{ "Act Complete", new [] { "Act Complete tiles", "Act Complete palette", "Act Complete tilemap", "HUD sprite tiles" } },
{ "Title screen", new [] { "Title screen tiles", "Title screen sprites", "Title screen palette", "Title screen tilemap", "Title screen press button text 1", "Title screen press button text 2", "Title screen music", "Title screen \"PRESS BUTTON\" flash time", "Title screen \"PRESS BUTTON\" total time", "Starting lives count" } },
{ "Game Over", new [] { "Act Complete tiles", "Game Over palette", "Game Over tilemap", "Game Over: Continue top", "Game Over: Continue bottom" } },
{ "Act Complete", new [] { "Act Complete tiles", "Act Complete palette", "Act Complete tilemap", "HUD sprite tiles", "Extra life at n x 10,000 points", "Extra life every n x 10,000 subsequent points" } },
{ "Special Stage Complete", new [] { "Act Complete tiles", "Act Complete palette", "Special Stage Complete tilemap", "HUD sprite tiles" } },
{ "Ending 1", new [] { "Map screen 1 tileset", "Ending palette", "Ending 1 tilemap" } },
{ "Ending 2", new [] { "Map screen 1 tileset", "Ending palette", "Ending 2 tilemap", "Ending text: box 1", "Ending text: box 2", "Ending text: box 3", "Ending text: box 4", "Ending text: box 5", "Ending text: box 6", "Ending text: box 7", "Ending text: box 8", "Ending text: Chaos Emerald", "Ending text: Sonic Left", "Ending text: Special Bonus" } },
Expand Down Expand Up @@ -1177,7 +1225,7 @@ private void ReadAssets()
item.SpriteTileSets.Add(tileSet);
break;
case Game.Asset.Types.RawValue:
var rawValue = new RawValue(Memory, part.Asset.OriginalOffset, part.Asset.OriginalSize, part.Name);
var rawValue = new RawValue(Memory, part.Asset.OriginalOffset, part.Asset.OriginalSize, part.Asset.Encoding, part.Name);
_assetsLookup[asset] = rawValue;
item.RawValues.Add(rawValue);
break;
Expand Down
33 changes: 27 additions & 6 deletions editor/Controls/RawValueEditor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows.Forms;
using System;
using System.Windows.Forms;
using sth1edwv.GameObjects;

namespace sth1edwv.Controls
Expand All @@ -15,16 +16,36 @@ public RawValueEditor(RawValue value)
numericUpDown1.Minimum = 0;
numericUpDown1.Maximum = value.Size switch
{
1 => 255,
2 => 65535,
_ => numericUpDown1.Maximum
1 => value.Encoding switch
{
RawValue.Encodings.Byte => 255,
RawValue.Encodings.Bcd => 99,
_ => throw new ArgumentOutOfRangeException()
},
2 => value.Encoding switch
{
RawValue.Encodings.Byte => 65535,
RawValue.Encodings.Bcd => 9999,
_ => throw new ArgumentOutOfRangeException()
},
_ => throw new ArgumentOutOfRangeException()
};
numericUpDown1.Value = value.Encoding switch
{
RawValue.Encodings.Byte => value.Value,
RawValue.Encodings.Bcd => Memory.FromBcd(value.Value),
_ => throw new ArgumentOutOfRangeException()
};
numericUpDown1.Value = value.Value;
}

private void numericUpDown1_ValueChanged(object sender, System.EventArgs e)
{
_value.Value = (int)numericUpDown1.Value;
_value.Value = _value.Encoding switch
{
RawValue.Encodings.Byte => (int)numericUpDown1.Value,
RawValue.Encodings.Bcd => Memory.ToBcd((int)numericUpDown1.Value),
_ => throw new ArgumentOutOfRangeException()
};
}
}
}
5 changes: 4 additions & 1 deletion editor/GameObjects/RawValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ public class RawValue : IDataItem
public int Size { get; }
public string Name { get; }
public int Value { get; set; }
public Encodings Encoding { get; }
public enum Encodings { Byte, Bcd }

public RawValue(Memory memory, int offset, int size, string name)
public RawValue(Memory memory, int offset, int size, Encodings encoding, string name)
{
Encoding = encoding;
Size = size;
Name = name;
Offset = offset;
Expand Down
34 changes: 8 additions & 26 deletions editor/GameObjects/SdscTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public SdscTag(Memory memory)
throw new Exception("No SDSC header");
}

Version = FromBcd(memory[0x7fe4]) + (decimal)FromBcd(memory[0x7fe5]) / 100;
Date = new DateTime(FromBcd(memory.Word(0x7fe8)), FromBcd(memory[0x7fe7]), FromBcd(memory[0x7fe6]));
Version = Memory.FromBcd(memory[0x7fe4]) + (decimal)Memory.FromBcd(memory[0x7fe5]) / 100;
Date = new DateTime(Memory.FromBcd(memory.Word(0x7fe8)), Memory.FromBcd(memory[0x7fe7]), Memory.FromBcd(memory[0x7fe6]));
Author = ReadString(memory, 0x7fea);
Title = ReadString(memory, 0x7fec);
Notes = ReadString(memory, 0x7fee);
Expand All @@ -38,36 +38,18 @@ private static string ReadString(Memory memory, int pointerOffset)
return pointer is 0 or 0xffff ? "" : memory.NullTerminatedString(pointer);
}

private static int FromBcd(int bcd)
{
var result = 0;
var multiplier = 1;
while (bcd > 0)
{
result += (bcd & 0xf) * multiplier;
bcd >>= 4;
multiplier *= 10;
}
return result;
}

public int Offset { get; set; }
public IList<byte> GetData()
{
return Encoding.ASCII.GetBytes("SDSC")
.Append(ToBcd((int)Version))
.Append(ToBcd((int)(Version * 100)))
.Append(ToBcd(Date.Day))
.Append(ToBcd(Date.Month))
.Append(ToBcd(Date.Year))
.Append(ToBcd(Date.Year / 100))
.Append((byte)Memory.ToBcd((int)Version))
.Append((byte)Memory.ToBcd((int)(Version * 100) % 100))
.Append((byte)Memory.ToBcd(Date.Day))
.Append((byte)Memory.ToBcd(Date.Month))
.Append((byte)Memory.ToBcd(Date.Year % 100))
.Append((byte)Memory.ToBcd(Date.Year / 100))
// Pointers are left empty
.ToList();
}

private static byte ToBcd(int value)
{
return (byte)((value % 10) + ((value / 10) % 10) * 16);
}
}
}
29 changes: 29 additions & 0 deletions editor/Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace sth1edwv
{
Expand Down Expand Up @@ -43,5 +44,33 @@ public string NullTerminatedString(int index)
}
return String(index, endIndex - index);
}

public static int FromBcd(int bcd)
{
var result = 0;
var multiplier = 1;
while (bcd > 0)
{
result += (bcd & 0xf) * multiplier;
bcd >>= 4;
multiplier *= 10;
}
return result;
}

public static int ToBcd(int value)
{
var result = 0;
var multiplier = 1;
while (value != 0)
{
// Get digit from value and add in the right place
result += (value % 10) * multiplier;
value /= 10;
multiplier *= 16;
}

return result;
}
}
}

0 comments on commit b142985

Please sign in to comment.