77 lines
2.1 KiB
C#
77 lines
2.1 KiB
C#
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) + ")";
|
|
}
|