feat(input): add joypad register and button state handling

This commit is contained in:
dualfroz committed 2026-08-24 13:11:36 +02:00
1 parent 485e61c8ef
commit 42b357550f
1 file changed
+81
+81
View File
@@ -0,0 +1,81 @@
using System.IO;
using GameBoy.Cpu;
namespace GameBoy.Input
{
public enum JoypadButton
{
Right = 0,
Left = 1,
Up = 2,
Down = 3,
A = 4,
B = 5,
Select = 6,
Start = 7
}
public sealed class Joypad
{
private readonly InterruptController interrupts;
private byte selectLines = 0x30;
private byte directions;
private byte actions;
public Joypad(InterruptController interrupts)
{
this.interrupts = interrupts;
}
public void SetButton(JoypadButton button, bool pressed)
{
int index = (int)button;
byte mask = (byte)(1 << (index & 3));
bool isDirection = index < 4;
byte before = ReadLines();
if (isDirection)
directions = pressed ? (byte)(directions | mask) : (byte)(directions & ~mask);
else
actions = pressed ? (byte)(actions | mask) : (byte)(actions & ~mask);
byte after = ReadLines();
if ((before & ~after & 0x0F) != 0)
interrupts.Request(Interrupt.Joypad);
}
private byte ReadLines()
{
byte lines = 0x0F;
if ((selectLines & 0x10) == 0)
lines &= (byte)~directions;
if ((selectLines & 0x20) == 0)
lines &= (byte)~actions;
return lines;
}
public byte Read()
{
return (byte)(0xC0 | selectLines | ReadLines());
}
public void Write(byte value)
{
selectLines = (byte)(value & 0x30);
}
public void SaveState(BinaryWriter writer)
{
writer.Write(selectLines);
writer.Write(directions);
writer.Write(actions);
}
public void LoadState(BinaryReader reader)
{
selectLines = reader.ReadByte();
directions = reader.ReadByte();
actions = reader.ReadByte();
}
}
}