Compare commits
4 Commits
april-fool
...
3c619df3dc
Author | SHA1 | Date | |
---|---|---|---|
3c619df3dc | |||
13f5e7a480 | |||
8519187d9b | |||
a66428f24e |
Submodule lib/SDL.zig updated: cc3b023f50...37f4ba9e31
Submodule lib/zig-clap updated: 6310cbd576...ab69ef2db4
@@ -205,10 +205,6 @@ pub const Backup = struct {
|
||||
const file_path = try self.savePath(allocator, path);
|
||||
defer allocator.free(file_path);
|
||||
|
||||
// FIXME: communicate edge case to the user?
|
||||
if (std.mem.eql(u8, &self.title, "ACE LIGHTNIN"))
|
||||
return;
|
||||
|
||||
switch (self.kind) {
|
||||
.Sram, .Flash, .Flash1M, .Eeprom => {
|
||||
const file = try std.fs.createFileAbsolute(file_path, .{});
|
||||
|
165
src/imgui.zig
165
src/imgui.zig
@@ -31,13 +31,25 @@ pub const State = struct {
|
||||
fps_hist: RingBuffer(u32),
|
||||
should_quit: bool = false,
|
||||
|
||||
win_stat: WindowStatus = .{},
|
||||
|
||||
const WindowStatus = struct {
|
||||
show_deps: bool = false,
|
||||
show_regs: bool = false,
|
||||
show_schedule: bool = false,
|
||||
show_perf: bool = false,
|
||||
show_palette: bool = false,
|
||||
};
|
||||
|
||||
/// if zba is initialized with a ROM already provided, this initializer should be called
|
||||
/// with `title_opt` being non-null
|
||||
pub fn init(allocator: Allocator, title_opt: ?*const [12]u8) !@This() {
|
||||
const history = try allocator.alloc(u32, histogram_len);
|
||||
|
||||
const title: [12:0]u8 = if (title_opt) |t| t.* ++ [_:0]u8{} else "[No Title]\x00\x00".*;
|
||||
return .{ .title = title, .fps_hist = RingBuffer(u32).init(history) };
|
||||
return .{
|
||||
.title = handleTitle(title_opt),
|
||||
.fps_hist = RingBuffer(u32).init(history),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This(), allocator: Allocator) void {
|
||||
@@ -56,7 +68,8 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
if (zgui.beginMenu("File", true)) {
|
||||
defer zgui.endMenu();
|
||||
|
||||
if (zgui.menuItem("Quit", .{})) state.should_quit = true;
|
||||
if (zgui.menuItem("Quit", .{}))
|
||||
state.should_quit = true;
|
||||
|
||||
if (zgui.menuItem("Insert ROM", .{})) blk: {
|
||||
const maybe_path = nfd.openFileDialog("gba", null) catch |e| {
|
||||
@@ -76,16 +89,38 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
break :blk;
|
||||
};
|
||||
|
||||
state.title = cpu.bus.pak.title ++ [_:0]u8{};
|
||||
state.title = handleTitle(&cpu.bus.pak.title);
|
||||
}
|
||||
}
|
||||
|
||||
if (zgui.beginMenu("Emulation", true)) {
|
||||
defer zgui.endMenu();
|
||||
|
||||
if (zgui.menuItem("Restart", .{})) {
|
||||
if (zgui.menuItem("Registers", .{ .selected = state.win_stat.show_regs }))
|
||||
state.win_stat.show_regs = true;
|
||||
|
||||
if (zgui.menuItem("Palette", .{ .selected = state.win_stat.show_palette }))
|
||||
state.win_stat.show_palette = true;
|
||||
|
||||
if (zgui.menuItem("Schedule", .{ .selected = state.win_stat.show_schedule }))
|
||||
state.win_stat.show_schedule = true;
|
||||
|
||||
if (zgui.menuItem("Restart", .{}))
|
||||
emu.reset(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
if (zgui.beginMenu("Stats", true)) {
|
||||
defer zgui.endMenu();
|
||||
|
||||
if (zgui.menuItem("Performance", .{ .selected = state.win_stat.show_perf }))
|
||||
state.win_stat.show_perf = true;
|
||||
}
|
||||
|
||||
if (zgui.beginMenu("Help", true)) {
|
||||
defer zgui.endMenu();
|
||||
|
||||
if (zgui.menuItem("Dependencies", .{ .selected = state.win_stat.show_deps }))
|
||||
state.win_stat.show_deps = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +135,51 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
zgui.image(@intToPtr(*anyopaque, tex_id), .{ .w = w, .h = h, .uv0 = .{ 0, 1 }, .uv1 = .{ 1, 0 } });
|
||||
}
|
||||
|
||||
{
|
||||
_ = zgui.begin("Information", .{});
|
||||
// TODO: Any other steps to respect the copyright of the libraries I use?
|
||||
if (state.win_stat.show_deps) {
|
||||
_ = zgui.begin("Dependencies", .{ .popen = &state.win_stat.show_deps });
|
||||
defer zgui.end();
|
||||
|
||||
zgui.bulletText("SDL.zig by Felix Queißner", .{});
|
||||
{
|
||||
zgui.indent(.{});
|
||||
defer zgui.unindent(.{});
|
||||
|
||||
zgui.bulletText("SDL by Sam Lantinga", .{});
|
||||
}
|
||||
|
||||
zgui.bulletText("known-folders by ziglibs", .{});
|
||||
zgui.bulletText("nfd-zig by Fabio Arnold", .{});
|
||||
{
|
||||
zgui.indent(.{});
|
||||
defer zgui.unindent(.{});
|
||||
|
||||
zgui.bulletText("nativefiledialog by Michael Labbe", .{});
|
||||
}
|
||||
zgui.bulletText("zba-gdbstub by Rekai Musuka", .{});
|
||||
zgui.bulletText("zba-util by Rekai Musuka", .{});
|
||||
zgui.bulletText("zgui by Michal Ziulek", .{});
|
||||
{
|
||||
zgui.indent(.{});
|
||||
defer zgui.unindent(.{});
|
||||
|
||||
zgui.bulletText("DearImGui by Omar Cornut", .{});
|
||||
}
|
||||
zgui.bulletText("zig-clap by Jimmi Holst Christensen", .{});
|
||||
zgui.bulletText("zig-datetime by Jairus Martin", .{});
|
||||
zgui.bulletText("zig-opengl by Felix Queißner", .{});
|
||||
{
|
||||
zgui.indent(.{});
|
||||
defer zgui.unindent(.{});
|
||||
|
||||
zgui.bulletText("OpenGL-Registry by The Khronos Group", .{});
|
||||
}
|
||||
zgui.bulletText("zig-toml by Aeron Avery", .{});
|
||||
zgui.bulletText("bitfield.zig by Hannes Bredberg and FlorenceOS contributors", .{});
|
||||
}
|
||||
|
||||
if (state.win_stat.show_regs) {
|
||||
_ = zgui.begin("Guest Registers", .{ .popen = &state.win_stat.show_regs });
|
||||
defer zgui.end();
|
||||
|
||||
for (0..8) |i| {
|
||||
@@ -124,8 +202,8 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
widgets.interrupts("IRQ", cpu.bus.io.irq);
|
||||
}
|
||||
|
||||
{
|
||||
_ = zgui.begin("Performance", .{});
|
||||
if (state.win_stat.show_perf) {
|
||||
_ = zgui.begin("Performance", .{ .popen = &state.win_stat.show_perf });
|
||||
defer zgui.end();
|
||||
|
||||
const tmp = blk: {
|
||||
@@ -187,8 +265,8 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
zgui.text(" 1% Low: {:0>3} fps", .{stats[2]});
|
||||
}
|
||||
|
||||
{
|
||||
_ = zgui.begin("Scheduler", .{});
|
||||
if (state.win_stat.show_schedule) {
|
||||
_ = zgui.begin("Schedule", .{ .popen = &state.win_stat.show_schedule });
|
||||
defer zgui.end();
|
||||
|
||||
const scheduler = cpu.sched;
|
||||
@@ -209,12 +287,59 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
|
||||
}
|
||||
}
|
||||
|
||||
// {
|
||||
// zgui.showDemoWindow(null);
|
||||
// }
|
||||
if (state.win_stat.show_palette) {
|
||||
_ = zgui.begin("Palette", .{ .popen = &state.win_stat.show_palette });
|
||||
defer zgui.end();
|
||||
|
||||
widgets.paletteGrid(.Background, cpu);
|
||||
|
||||
zgui.sameLine(.{ .spacing = 20.0 });
|
||||
|
||||
widgets.paletteGrid(.Object, cpu);
|
||||
}
|
||||
|
||||
{
|
||||
zgui.showDemoWindow(null);
|
||||
}
|
||||
}
|
||||
|
||||
const widgets = struct {
|
||||
const PaletteKind = enum { Background, Object };
|
||||
|
||||
fn paletteGrid(comptime kind: PaletteKind, cpu: *const Arm7tdmi) void {
|
||||
_ = zgui.beginGroup();
|
||||
defer zgui.endGroup();
|
||||
|
||||
const address: u32 = switch (kind) {
|
||||
.Background => 0x0500_0000,
|
||||
.Object => 0x0500_0200,
|
||||
};
|
||||
|
||||
for (0..0x100) |i| {
|
||||
const offset = @truncate(u32, i);
|
||||
const bgr555 = cpu.bus.dbgRead(u16, address + offset * @sizeOf(u16));
|
||||
widgets.colourSquare(bgr555);
|
||||
|
||||
if ((i + 1) % 0x10 != 0) zgui.sameLine(.{});
|
||||
}
|
||||
zgui.text(@tagName(kind), .{});
|
||||
}
|
||||
|
||||
fn colourSquare(bgr555: u16) void {
|
||||
// FIXME: working with the packed struct enum is currently broken :pensive:
|
||||
const ImguiColorEditFlags_NoInputs: u32 = 1 << 5;
|
||||
const ImguiColorEditFlags_NoPicker: u32 = 1 << 2;
|
||||
const flags = @bitCast(zgui.ColorEditFlags, ImguiColorEditFlags_NoInputs | ImguiColorEditFlags_NoPicker);
|
||||
|
||||
const b = @intToFloat(f32, bgr555 >> 10 & 0x1f);
|
||||
const g = @intToFloat(f32, bgr555 >> 5 & 0x1F);
|
||||
const r = @intToFloat(f32, bgr555 & 0x1F);
|
||||
|
||||
var col = [_]f32{ r / 31.0, g / 31.0, b / 31.0 };
|
||||
|
||||
_ = zgui.colorEdit3("", .{ .col = &col, .flags = flags });
|
||||
}
|
||||
|
||||
fn interrupts(comptime label: []const u8, int: anytype) void {
|
||||
const h = 15.0;
|
||||
const w = 9.0 * 2 + 3.5;
|
||||
@@ -305,3 +430,13 @@ const widgets = struct {
|
||||
}.inner;
|
||||
}
|
||||
};
|
||||
|
||||
fn handleTitle(title_opt: ?*const [12]u8) [12:0]u8 {
|
||||
if (title_opt == null) return "[N/A Title]\x00".*; // No ROM present
|
||||
const title = title_opt.?;
|
||||
|
||||
// ROM Title is an empty string (ImGui hates these)
|
||||
if (title[0] == '\x00') return "[No Title]\x00\x00".*;
|
||||
|
||||
return title.* ++ [_:0]u8{};
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ pub fn main() void {
|
||||
bus.init(allocator, &scheduler, &cpu, paths) catch |e| exitln("failed to init zba bus: {}", .{e});
|
||||
defer bus.deinit();
|
||||
|
||||
if (config.config().guest.skip_bios or result.args.skip or paths.bios == null) {
|
||||
if (config.config().guest.skip_bios or result.args.skip != 0 or paths.bios == null) {
|
||||
cpu.fastBoot();
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pub fn main() void {
|
||||
var items: [0x100]u8 = undefined;
|
||||
var channel = TwoWayChannel.init(&items);
|
||||
|
||||
if (result.args.gdb) {
|
||||
if (result.args.gdb != 0) {
|
||||
const Server = @import("gdbstub").Server;
|
||||
const EmuThing = @import("core/emu.zig").EmuThing;
|
||||
|
||||
|
Reference in New Issue
Block a user