feat(analysis): add sprite scanner

This commit is contained in:
dualfroz committed 2026-08-25 19:30:05 +02:00
1 parent c9c9bbe68b
commit f7c48098ce
2 files changed
+172

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
using System.Globalization;
using System.Text;
namespace Chip8.Analysis;
public sealed class SpriteCandidate
{
public SpriteCandidate(ushort address, int rows, int bytesPerRow, byte[] bytes, ushort loadAddress, ushort drawAddress)
{
this.address = address;
this.rows = rows;
this.bytesPerRow = bytesPerRow;
this.bytes = bytes;
this.loadAddress = loadAddress;
this.drawAddress = drawAddress;
}
public ushort address { get; }
public int rows { get; }
public int bytesPerRow { get; }
public byte[] bytes { get; }
public ushort loadAddress { get; }
public ushort drawAddress { get; }
public int widthPixels => bytesPerRow * 8;
public int setPixelCount
{
get
{
int count = 0;
foreach (byte value in bytes)
{
int bits = value;
while (bits != 0)
{
count += bits & 1;
bits >>= 1;
}
}
return count;
}
}
public bool isBlank => setPixelCount == 0;
public bool pixel(int row, int column)
{
int byteIndex = row * bytesPerRow + column / 8;
if (byteIndex >= bytes.Length)
{
return false;
}
int bit = 7 - column % 8;
return (bytes[byteIndex] & (1 << bit)) != 0;
}
public string renderAscii(char on = '#', char off = '.')
{
var builder = new StringBuilder();
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < widthPixels; column++)
{
builder.Append(pixel(row, column) ? on : off);
}
builder.Append('\n');
}
return builder.ToString();
}
public override string ToString() =>
"sprite@0x" + address.ToString("X4", CultureInfo.InvariantCulture)
+ " " + widthPixels + "x" + rows
+ " (" + setPixelCount + " px, drawn at 0x" + drawAddress.ToString("X4", CultureInfo.InvariantCulture) + ")";
}