Skip to content

Commit

Permalink
Godot player basic save/load and colourizing
Browse files Browse the repository at this point in the history
  • Loading branch information
qkmaxware committed Jan 23, 2024
1 parent 687108a commit 2141bd6
Show file tree
Hide file tree
Showing 19 changed files with 591 additions and 111 deletions.
28 changes: 28 additions & 0 deletions Gameboy.Player.Godot/Debuggers/CartInfoDebug.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Godot;
using System;
using System.Linq;
using System.Collections.Generic;
using Qkmaxware.Emulators.Gameboy.Hardware;

namespace Qkmaxware.Emulators.Gameboy.Player;
public partial class CartInfoDebug : Control {

[Export] public TextureRenderer Player;

private RichTextLabel text;

// Called when the node enters the scene tree for the first time.
public override void _Ready() {
text = this.GetNode<RichTextLabel>("ScrollContainer/MarginContainer/RichTextLabel");
}

public void Refresh() {
var str = string.Empty;

if (Player?.Console?.GetCartridge() is Cartridge cart) {
str = cart.Info.ToString();
}

this.text.Text = str;
}
}
49 changes: 49 additions & 0 deletions Gameboy.Player.Godot/Debuggers/CartInfoDebug.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[gd_scene load_steps=3 format=3 uid="uid://t7khq15qfjuw"]

[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="1_0a8i2"]
[ext_resource type="Script" path="res://Debuggers/CartInfoDebug.cs" id="1_m4mxx"]

[node name="Cartridge Info" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_m4mxx")

[node name="ScrollContainer" type="ScrollContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = 44.0
grow_horizontal = 2
grow_vertical = 2

[node name="MarginContainer" type="MarginContainer" parent="ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10

[node name="RichTextLabel" type="RichTextLabel" parent="ScrollContainer/MarginContainer"]
layout_mode = 2
size_flags_horizontal = 3
fit_content = true

[node name="Reload" type="Button" parent="."]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -95.0
offset_bottom = 31.0
grow_horizontal = 0
text = "Reload"
icon = ExtResource("1_0a8i2")
expand_icon = true

[connection signal="pressed" from="Reload" to="." method="Refresh"]
71 changes: 71 additions & 0 deletions Gameboy.Player.Godot/Debuggers/Disassembler.Row.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
[gd_scene load_steps=2 format=3 uid="uid://c2fsn6ee6p522"]

[ext_resource type="Script" path="res://Debuggers/DisassemblerRow.cs" id="1_1mo4q"]

[node name="Row" type="HBoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 31.0
grow_horizontal = 2
size_flags_horizontal = 3
script = ExtResource("1_1mo4q")

[node name="Address" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3

[node name="Decimal" type="Button" parent="Address"]
layout_mode = 2
text = "x10"

[node name="Hex" type="Button" parent="Address"]
layout_mode = 2
text = "x16"

[node name="Label" type="Label" parent="Address"]
layout_mode = 2
text = "0x900"

[node name="Instruction" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3

[node name="Decimal" type="Button" parent="Instruction"]
layout_mode = 2
text = "x10"

[node name="Hex" type="Button" parent="Instruction"]
layout_mode = 2
text = "x16"

[node name="Name" type="Button" parent="Instruction"]
layout_mode = 2
text = "Inst"

[node name="Label" type="Label" parent="Instruction"]
layout_mode = 2
text = "Jump"

[node name="Args" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3

[node name="Decimal" type="Button" parent="Args"]
layout_mode = 2
text = "x10"

[node name="Hex" type="Button" parent="Args"]
layout_mode = 2
text = "x16"

[node name="Label" type="Label" parent="Args"]
layout_mode = 2
text = "120"

[connection signal="pressed" from="Address/Decimal" to="." method="AddressModeDecimal"]
[connection signal="pressed" from="Address/Hex" to="." method="AddressModeHex"]
[connection signal="pressed" from="Instruction/Decimal" to="." method="InstructionModeDecimal"]
[connection signal="pressed" from="Instruction/Hex" to="." method="InstructionModeHex"]
[connection signal="pressed" from="Instruction/Name" to="." method="InstructionModeName"]
[connection signal="pressed" from="Args/Decimal" to="." method="ArgModeDecimal"]
[connection signal="pressed" from="Args/Hex" to="." method="ArgModeHex"]
54 changes: 43 additions & 11 deletions Gameboy.Player.Godot/Debuggers/Disassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,59 @@ public partial class Disassembler : Control {

[Export] public TextureRenderer Player;

private RichTextLabel text;
[Export] public PackedScene RowPrefab;

private Control container;
private Label pageLabel;

public int Page {get; private set;}
public int PageSize = 1000;

private Qkmaxware.Vm.LR35902.Disassembler disassembler = new Qkmaxware.Vm.LR35902.Disassembler(Endianness.LittleEndian);

// Called when the node enters the scene tree for the first time.
public override void _Ready() {
text = this.GetNode<RichTextLabel>("ScrollContainer/RichTextLabel");
container = this.GetNode<Control>("ScrollContainer/MarginContainer/VBoxContainer");
pageLabel = this.GetNode<Label>("Navigator/Label");
pageLabel.Text = Page.ToString();
}

public void PrevPage() {
if (Page > 0) {
Page --;
updateListing();
pageLabel.Text = Page.ToString();
}
}
public void NextPage() {
Page++;
updateListing();
pageLabel.Text = Page.ToString();
}

public void Clear() {
foreach (Node node in container.GetChildren()) {
if (node is DisassemblerRow) {
container.RemoveChild(node);
node.QueueFree();
}
}
}

public void Refresh() {
text.Text = string.Empty;
this.Page = 0;
updateListing();
}

private void updateListing() {
Clear();
var cart = Player?.Console?.GetCartridge();
if (cart is not null) {
var bytes = cart.GetBytes().Skip(0x014F); // End of header at: 0x014F = 335
foreach (var instr in disassembler.Disassemble(bytes)) {
if (instr.Operation is not null) {
var argString = string.Join(' ', instr.Arguments.Select(x => x.ToString("X4")));
text.Text += $"0x{instr.Address:X4} {instr.Operation.Name} {argString}" + System.Environment.NewLine;
} else {
text.Text += $"0x{instr.Address:X4} {instr.Opcode:X2}";
}
var bytes = cart.Bytes; // End of header at: 0x014F = 335, max 1000 entries
foreach (var instr in disassembler.Disassemble(bytes).Skip(Page * PageSize).Take(PageSize)) {
var row = RowPrefab.Instantiate<DisassemblerRow>();
container.AddChild(row);
row.SetInfo(instr);
}
}
}
Expand Down
76 changes: 72 additions & 4 deletions Gameboy.Player.Godot/Debuggers/Disassembler.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://cs764ed0jafqu"]
[gd_scene load_steps=4 format=3 uid="uid://cs764ed0jafqu"]

[ext_resource type="Script" path="res://Debuggers/Disassembler.cs" id="1_bgd2f"]
[ext_resource type="PackedScene" uid="uid://c2fsn6ee6p522" path="res://Debuggers/Disassembler.Row.tscn" id="2_hoclf"]
[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="3_5ffph"]

[node name="Disassembler" type="Control"]
Expand All @@ -11,6 +12,7 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_bgd2f")
RowPrefab = ExtResource("2_hoclf")

[node name="ScrollContainer" type="ScrollContainer" parent="."]
layout_mode = 1
Expand All @@ -22,11 +24,53 @@ grow_horizontal = 2
grow_vertical = 2
horizontal_scroll_mode = 0

[node name="RichTextLabel" type="RichTextLabel" parent="ScrollContainer"]
[node name="MarginContainer" type="MarginContainer" parent="ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
fit_content = true
autowrap_mode = 0
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10

[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer/MarginContainer"]
layout_mode = 2

[node name="Header" type="HBoxContainer" parent="ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3

[node name="Address" type="HBoxContainer" parent="ScrollContainer/MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3

[node name="Label" type="Label" parent="ScrollContainer/MarginContainer/VBoxContainer/Header/Address"]
layout_mode = 2
size_flags_horizontal = 3
text = "Address"
horizontal_alignment = 1

[node name="Instruction" type="HBoxContainer" parent="ScrollContainer/MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3

[node name="Label" type="Label" parent="ScrollContainer/MarginContainer/VBoxContainer/Header/Instruction"]
layout_mode = 2
size_flags_horizontal = 3
text = "Instruction"
horizontal_alignment = 1

[node name="Args" type="HBoxContainer" parent="ScrollContainer/MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3

[node name="Label" type="Label" parent="ScrollContainer/MarginContainer/VBoxContainer/Header/Args"]
layout_mode = 2
size_flags_horizontal = 3
text = "Arguments"
horizontal_alignment = 1

[node name="Row" parent="ScrollContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_hoclf")]
layout_mode = 2

[node name="Reload" type="Button" parent="."]
layout_mode = 1
Expand All @@ -40,4 +84,28 @@ text = "Reload"
icon = ExtResource("3_5ffph")
expand_icon = true

[node name="Navigator" type="HBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -41.0
offset_right = 41.0
offset_bottom = 40.0
grow_horizontal = 2

[node name="Prev" type="Button" parent="Navigator"]
layout_mode = 2
text = " < "

[node name="Label" type="Label" parent="Navigator"]
layout_mode = 2
text = "Page"

[node name="Next" type="Button" parent="Navigator"]
layout_mode = 2
text = " > "

[connection signal="pressed" from="Reload" to="." method="Refresh"]
[connection signal="pressed" from="Navigator/Prev" to="." method="PrevPage"]
[connection signal="pressed" from="Navigator/Next" to="." method="NextPage"]
65 changes: 65 additions & 0 deletions Gameboy.Player.Godot/Debuggers/DisassemblerRow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Godot;
using System;
using System.Linq;
using Qkmaxware.Emulators.Gameboy.Hardware;
using Qkmaxware.Vm.LR35902;

namespace Qkmaxware.Emulators.Gameboy.Player;

public partial class DisassemblerRow : HBoxContainer {

private InstructionInfo info;

private Label addressLabel;
private Label instructionLabel;
private Label argsLabel;

const string EmptyArgument = "--";

// Called when the node enters the scene tree for the first time.
public override void _Ready() {
this.addressLabel = GetNode<Label>("Address/Label");
this.instructionLabel = GetNode<Label>("Instruction/Label");
this.argsLabel = GetNode<Label>("Args/Label");
}

public void SetInfo(InstructionInfo info) {
this.info = info;

AddressModeHex();
InstructionModeName();
ArgModeDecimal();
}

public void AddressModeDecimal() {
this.addressLabel.Text = info.Address.ToString();
}
public void AddressModeHex() {
this.addressLabel.Text = "0x" + info.Address.ToString("X4");
}

public void InstructionModeDecimal() {
this.instructionLabel.Text = info.Opcode.ToString();
}
public void InstructionModeHex() {
this.instructionLabel.Text = "0x" + info.Opcode.ToString("X2");
}
public void InstructionModeName() {
this.instructionLabel.Text = info.Operation?.Name ?? info.Opcode.ToString();
}

public void ArgModeDecimal() {
if (info.Arguments is null || info.Arguments.Length == 0) {
this.argsLabel.Text = EmptyArgument;
return;
}
this.argsLabel.Text = string.Join(' ', info.Arguments.Select(x => x.ToString()));
}
public void ArgModeHex() {
if (info.Arguments is null || info.Arguments.Length == 0) {
this.argsLabel.Text = EmptyArgument;
return;
}
this.argsLabel.Text = string.Join(' ', info.Arguments.Select(x => "0x" + x.ToString("X2")));
}
}
Loading

0 comments on commit 2141bd6

Please sign in to comment.