diff --git a/Gameboy.Player.Godot/BitmapTextureRect.cs b/Gameboy.Player.Godot/BitmapTextureRect.cs new file mode 100644 index 0000000..a3fcbe6 --- /dev/null +++ b/Gameboy.Player.Godot/BitmapTextureRect.cs @@ -0,0 +1,77 @@ +using Godot; +using System; +using Qkmaxware.Emulators.Gameboy; +using Qkmaxware.Emulators.Gameboy.Hardware; +using LcdBitmap = Qkmaxware.Emulators.Gameboy.Hardware.Bitmap; + +namespace Qkmaxware.Emulators.Gameboy.Player; + +public partial class BitmapTextureRect : TextureRect { + + [Export] + [ExportGroup("Colour Pallet/Background")] + public Color BgWhite = new Color(1, 1, 1); + [Export] + public Color BgLightGrey = new Color(0.6f, 0.6f, 0.6f); + [Export] + public Color BgDarkGrey = new Color(0.3f, 0.3f, 0.3f); + [Export] + public Color BgBlack = new Color(0, 0, 0); + + [Export] + [ExportGroup("Colour Pallet/Object 0")] + public Color Obj0White = new Color(1, 1, 1); + [Export] + public Color Obj0LightGrey = new Color(0.6f, 0.6f, 0.6f); + [Export] + public Color Obj0DarkGrey = new Color(0.3f, 0.3f, 0.3f); + [Export] + public Color Obj0Black = new Color(0, 0, 0); + + [Export] + [ExportGroup("Colour Pallet/Object 1")] + public Color Obj1White = new Color(1, 1, 1); + [Export] + public Color Obj1LightGrey = new Color(0.6f, 0.6f, 0.6f); + [Export] + public Color Obj1DarkGrey = new Color(0.3f, 0.3f, 0.3f); + [Export] + public Color Obj1Black = new Color(0, 0, 0); + + private ImageTexture texture; + + public void Redraw(LcdBitmap bmp) { + var pixels = Image.Create(width: bmp.Width, height: bmp.Height, useMipmaps: false, format: Image.Format.Rgb8); + + for (var col = 0; col < bmp.Height; col++) { + for (var row = 0; row < bmp.Width; row++) { + pixels.SetPixel(row, col, bmp[row, col] switch { + ColourPallet.BackgroundDark => BgBlack, + ColourPallet.Object0Dark => Obj0Black, + ColourPallet.Object1Dark => Obj1Black, + + ColourPallet.BackgroundMedium => BgDarkGrey, + ColourPallet.Object0Medium => Obj0DarkGrey, + ColourPallet.Object1Medium => Obj1DarkGrey, + + ColourPallet.BackgroundLight => BgLightGrey, + ColourPallet.Object0Light => Obj0LightGrey, + ColourPallet.Object1Light => Obj1LightGrey, + + ColourPallet.BackgroundWhite => BgWhite, + ColourPallet.Object0White => Obj0White, + ColourPallet.Object1White => Obj1White, + + _ => BgBlack, + }); + } + } + + if (texture is null) { + texture = ImageTexture.CreateFromImage(pixels); + } else { + texture.Update(pixels); + } + this.Texture = texture; + } +} \ No newline at end of file diff --git a/Gameboy.Player.Godot/Debuggers/Disassembler.cs b/Gameboy.Player.Godot/Debuggers/Disassembler.cs new file mode 100644 index 0000000..df2f2c1 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/Disassembler.cs @@ -0,0 +1,37 @@ +using Godot; +using System; +using System.Linq; +using Qkmaxware.Emulators.Gameboy.Hardware; +using Qkmaxware.Vm.LR35902; + +namespace Qkmaxware.Emulators.Gameboy.Player; + +public partial class Disassembler : Control { + + [Export] public TextureRenderer Player; + + private RichTextLabel text; + + 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("ScrollContainer/RichTextLabel"); + } + + public void Refresh() { + text.Text = string.Empty; + 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}"; + } + } + } + } +} diff --git a/Gameboy.Player.Godot/Debuggers/Disassembler.tscn b/Gameboy.Player.Godot/Debuggers/Disassembler.tscn new file mode 100644 index 0000000..0d78ea3 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/Disassembler.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=3 format=3 uid="uid://cs764ed0jafqu"] + +[ext_resource type="Script" path="res://Debuggers/Disassembler.cs" id="1_bgd2f"] +[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="3_5ffph"] + +[node name="Disassembler" 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_bgd2f") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 59.0 +grow_horizontal = 2 +grow_vertical = 2 +horizontal_scroll_mode = 0 + +[node name="RichTextLabel" type="RichTextLabel" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +fit_content = true +autowrap_mode = 0 + +[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("3_5ffph") +expand_icon = true + +[connection signal="pressed" from="Reload" to="." method="Refresh"] diff --git a/Gameboy.Player.Godot/Debuggers/Map Debugger.tscn b/Gameboy.Player.Godot/Debuggers/Map Debugger.tscn new file mode 100644 index 0000000..3440c53 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/Map Debugger.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=4 format=3 uid="uid://2uytp7r2ouod"] + +[ext_resource type="Script" path="res://Debuggers/MapDebugger.cs" id="1_gnyfy"] +[ext_resource type="Script" path="res://BitmapTextureRect.cs" id="2_0ayh7"] +[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="3_fd1ro"] + +[node name="Map Debugger" 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_gnyfy") + +[node name="Rect" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 34.0 +grow_horizontal = 2 +grow_vertical = 2 +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_0ayh7") + +[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("3_fd1ro") +expand_icon = true + +[connection signal="pressed" from="Reload" to="." method="Refresh"] diff --git a/Gameboy.Player.Godot/Debuggers/MapDebugger.cs b/Gameboy.Player.Godot/Debuggers/MapDebugger.cs new file mode 100644 index 0000000..41323d6 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/MapDebugger.cs @@ -0,0 +1,36 @@ +using Godot; +using System; +using Qkmaxware.Emulators.Gameboy.Hardware; + +namespace Qkmaxware.Emulators.Gameboy.Player; + +public enum MapType { + Background, Window +} + +public partial class MapDebugger : Control { + + [Export] public TextureRenderer Player; + [Export] public MapType Map; + + private BitmapTextureRect rect; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() { + this.rect = GetNode("Rect"); + } + + public void Refresh() { + var ppu = Player?.Console?.GPU; + if (ppu is IDebuggablePpu debug) { + switch (Map) { + case MapType.Background: + rect?.Redraw(debug.BackgroundMap.ToBitmap()); + break; + case MapType.Window: + rect?.Redraw(debug.WindowMap.ToBitmap()); + break; + } + } + } +} diff --git a/Gameboy.Player.Godot/Debuggers/PaletteDebugger.cs b/Gameboy.Player.Godot/Debuggers/PaletteDebugger.cs new file mode 100644 index 0000000..b347190 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/PaletteDebugger.cs @@ -0,0 +1,101 @@ +using Godot; +using System; +using System.Linq; +using System.Collections.Generic; +using Qkmaxware.Emulators.Gameboy.Hardware; + +namespace Qkmaxware.Emulators.Gameboy.Player; + +public partial class PaletteDebugger : Control { + + [Export] public TextureRenderer Player; + + private ColorRect[][] bg; + private ColorRect[][] obj; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() { + bg = new ColorRect[1][]; + bg[0] = new ColorRect[4]; + for (var i = 0; i < 4; i++) { + var b00 = Convert.ToString(i, 2).PadLeft(2, '0'); + bg[0][i] = this.GetNode("ScrollContainer/HSplitContainer/Background/VBoxContainer/HBoxContainer/"+b00); + } + + obj = new ColorRect[2][]; + obj[0] = new ColorRect[4]; + obj[1] = new ColorRect[4]; + for (var i = 0; i < 4; i++) { + var b00 = Convert.ToString(i, 2).PadLeft(2, '0'); + obj[0][i] = this.GetNode("ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer1/"+b00); + obj[1][i] = this.GetNode("ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer2/"+b00); + } + } + + public void Refresh() { + var ppu = Player?.Console?.GPU; + if (ppu is IDebuggablePpu debug) { + HashSet bgcolours = new HashSet(); + foreach (var palette in debug.BackgroundPalettes.Zip(bg)) { + foreach (var pair in palette.First.Zip(palette.Second)) { + var palettedColour = pair.First; + var rgb = palettedColour switch { + ColourPallet.BackgroundDark => new Color(0,0,0,1), + ColourPallet.Object0Dark => new Color(0,0,0,1), + ColourPallet.Object1Dark => new Color(0,0,0,1), + + ColourPallet.BackgroundMedium => new Color(0.3f,0.3f,0.3f,1), + ColourPallet.Object0Medium => new Color(0.3f,0.3f,0.3f,1), + ColourPallet.Object1Medium => new Color(0.3f,0.3f,0.3f,1), + + ColourPallet.BackgroundLight => new Color(0.6f,0.6f,0.6f,1), + ColourPallet.Object0Light => new Color(0.6f,0.6f,0.6f,1), + ColourPallet.Object1Light => new Color(0.6f,0.6f,0.6f,1), + + ColourPallet.BackgroundWhite => new Color(1f,1f,1f,1), + ColourPallet.Object0White => new Color(1f,1f,1f,1), + ColourPallet.Object1White => new Color(1f,1f,1f,1), + + _ => new Color(0,0,0,1), + }; + bgcolours.Add(palettedColour); + pair.Second.Color = rgb; + } + } + if (bgcolours.Count < 1) { + GD.PushError("Background palette is mono-colour."); + } + + HashSet objcolours = new HashSet(); + foreach (var palette in debug.ObjectPalettes.Zip(obj)) { + foreach (var pair in palette.First.Zip(palette.Second)) { + var palettedColour = pair.First; + var rgb = palettedColour switch { + ColourPallet.BackgroundDark => new Color(0,0,0,1), + ColourPallet.Object0Dark => new Color(0,0,0,1), + ColourPallet.Object1Dark => new Color(0,0,0,1), + + ColourPallet.BackgroundMedium => new Color(0.3f,0.3f,0.3f,1), + ColourPallet.Object0Medium => new Color(0.3f,0.3f,0.3f,1), + ColourPallet.Object1Medium => new Color(0.3f,0.3f,0.3f,1), + + ColourPallet.BackgroundLight => new Color(0.6f,0.6f,0.6f,1), + ColourPallet.Object0Light => new Color(0.6f,0.6f,0.6f,1), + ColourPallet.Object1Light => new Color(0.6f,0.6f,0.6f,1), + + ColourPallet.BackgroundWhite => new Color(1f,1f,1f,1), + ColourPallet.Object0White => new Color(1f,1f,1f,1), + ColourPallet.Object1White => new Color(1f,1f,1f,1), + + _ => new Color(0,0,0,1), + }; + objcolours.Add(palettedColour); + pair.Second.Color = rgb; + } + } + if (objcolours.Count < 1) { + GD.PushError("Object palette is mono-colour."); + } + } + } +} diff --git a/Gameboy.Player.Godot/Debuggers/PaletteDebugger.tscn b/Gameboy.Player.Godot/Debuggers/PaletteDebugger.tscn new file mode 100644 index 0000000..c80f7e1 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/PaletteDebugger.tscn @@ -0,0 +1,128 @@ +[gd_scene load_steps=3 format=3 uid="uid://b5psa1c0pvkya"] + +[ext_resource type="Script" path="res://Debuggers/PaletteDebugger.cs" id="1_sor31"] +[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="2_wsgsr"] + +[node name="Palette Debugger" 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_sor31") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 58.0 +grow_horizontal = 2 +grow_vertical = 2 +horizontal_scroll_mode = 0 + +[node name="HSplitContainer" type="HSplitContainer" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +split_offset = 512 + +[node name="Background" type="MarginContainer" parent="ScrollContainer/HSplitContainer"] +layout_mode = 2 +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/HSplitContainer/Background"] +layout_mode = 2 + +[node name="Label" type="Label" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer"] +layout_mode = 2 +text = "Backgrounds" + +[node name="HBoxContainer" type="HBoxContainer" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer"] +layout_mode = 2 + +[node name="00" type="ColorRect" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="01" type="ColorRect" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="10" type="ColorRect" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="11" type="ColorRect" parent="ScrollContainer/HSplitContainer/Background/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="Objects" type="MarginContainer" parent="ScrollContainer/HSplitContainer"] +layout_mode = 2 +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/HSplitContainer/Objects"] +layout_mode = 2 + +[node name="Label" type="Label" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer"] +layout_mode = 2 +text = "Objects" + +[node name="HBoxContainer1" type="HBoxContainer" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer"] +layout_mode = 2 + +[node name="00" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer1"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="01" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer1"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="10" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer1"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="11" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer1"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer"] +layout_mode = 2 + +[node name="00" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer2"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="01" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer2"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="10" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer2"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="11" type="ColorRect" parent="ScrollContainer/HSplitContainer/Objects/VBoxContainer/HBoxContainer2"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[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("2_wsgsr") +expand_icon = true + +[connection signal="pressed" from="Reload" to="." method="Refresh"] diff --git a/Gameboy.Player.Godot/Debuggers/Sprite Debugger.tscn b/Gameboy.Player.Godot/Debuggers/Sprite Debugger.tscn new file mode 100644 index 0000000..94d6b0f --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/Sprite Debugger.tscn @@ -0,0 +1,925 @@ +[gd_scene load_steps=5 format=3 uid="uid://yis4daekext1"] + +[ext_resource type="Texture2D" uid="uid://cip0keh15srys" path="res://cart.png" id="1_44h0a"] +[ext_resource type="Script" path="res://Debuggers/SpriteDebugger.cs" id="1_kpo0v"] +[ext_resource type="Script" path="res://BitmapTextureRect.cs" id="2_hqqgw"] +[ext_resource type="Texture2D" uid="uid://divrqb47wvwvt" path="res://reload.png" id="4_26upw"] + +[node name="Sprite Debugger" 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_kpo0v") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 59.0 +grow_horizontal = 2 +grow_vertical = 2 +horizontal_scroll_mode = 0 + +[node name="GridContainer" type="GridContainer" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/v_separation = 24 +columns = 10 + +[node name="Sprite 0" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 0"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 1" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 1"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 2" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 2"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 3" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 3"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 4" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 4"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 5" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 5"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 6" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 6"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 7" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 7"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 8" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 8"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 9" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 9"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 10" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 10"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 11" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 11"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 12" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 12"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 13" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 13"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 14" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 14"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 15" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 15"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 16" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 16"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 17" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 17"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 18" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 18"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 19" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 19"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 20" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 20"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 21" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 21"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 22" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 22"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 23" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 23"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 24" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 24"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 25" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 25"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 26" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 26"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 27" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 27"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 28" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 28"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 29" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 29"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 30" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 30"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 31" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 31"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 32" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 32"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 33" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 33"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 34" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 34"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 35" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 35"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 36" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 36"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 37" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 37"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 38" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 38"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[node name="Sprite 39" type="TextureRect" parent="ScrollContainer/GridContainer"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +size_flags_horizontal = 3 +texture = ExtResource("1_44h0a") +expand_mode = 1 +stretch_mode = 5 +script = ExtResource("2_hqqgw") + +[node name="Label" type="Label" parent="ScrollContainer/GridContainer/Sprite 39"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -1.0 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "0" +horizontal_alignment = 1 + +[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("4_26upw") +expand_icon = true + +[connection signal="pressed" from="Reload" to="." method="Refresh"] diff --git a/Gameboy.Player.Godot/Debuggers/SpriteDebugger.cs b/Gameboy.Player.Godot/Debuggers/SpriteDebugger.cs new file mode 100644 index 0000000..1faf2f6 --- /dev/null +++ b/Gameboy.Player.Godot/Debuggers/SpriteDebugger.cs @@ -0,0 +1,46 @@ +using Godot; +using System; +using System.Linq; +using Qkmaxware.Emulators.Gameboy.Hardware; + +namespace Qkmaxware.Emulators.Gameboy.Player; + +public partial class SpriteDebugger : Control { + + [Export] public TextureRenderer Player; + + private BitmapTextureRect[] spriteTextures; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() { + spriteTextures = new BitmapTextureRect[40]; + for (var i = 0; i < spriteTextures.Length; i++) { + var texture = this.GetNode("ScrollContainer/GridContainer/Sprite " + i); + var label = texture.GetNode