1 Commits

Author SHA1 Message Date
9844d657b0 fix: implement Ace Lightning (2002) obscure behaviour 2023-04-01 01:23:18 -05:00
8 changed files with 32 additions and 163 deletions

View File

@@ -65,9 +65,9 @@ pub fn build(b: *std.Build) void {
const zgui_pkg = zgui.package(b, target, optimize, .{ .options = .{ .backend = .sdl2_opengl3, .shared = true } });
zgui_pkg.link(exe);
b.installArtifact(exe);
exe.install();
const run_cmd = b.addRunArtifact(exe);
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);

View File

@@ -205,6 +205,10 @@ 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, .{});

View File

@@ -39,7 +39,7 @@ pub const arm = struct {
}
fn populate() [0x1000]InstrFn {
return comptime comptime_blk: {
comptime {
@setEvalBranchQuota(0xE000);
var table = [_]InstrFn{und} ** 0x1000;
@@ -106,8 +106,8 @@ pub const arm = struct {
};
}
break :comptime_blk table;
};
return table;
}
}
};
@@ -135,7 +135,7 @@ pub const thumb = struct {
}
fn populate() [0x400]InstrFn {
return comptime comptime_blk: {
comptime {
@setEvalBranchQuota(5025); // This is exact
var table = [_]InstrFn{und} ** 0x400;
@@ -228,8 +228,8 @@ pub const thumb = struct {
};
}
break :comptime_blk table;
};
return table;
}
}
};

View File

@@ -31,25 +31,13 @@ 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);
return .{
.title = handleTitle(title_opt),
.fps_hist = RingBuffer(u32).init(history),
};
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) };
}
pub fn deinit(self: *@This(), allocator: Allocator) void {
@@ -68,8 +56,7 @@ 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| {
@@ -89,38 +76,16 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
break :blk;
};
state.title = handleTitle(&cpu.bus.pak.title);
state.title = cpu.bus.pak.title ++ [_:0]u8{};
}
}
if (zgui.beginMenu("Emulation", true)) {
defer zgui.endMenu();
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", .{}))
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;
}
}
}
@@ -135,51 +100,8 @@ 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 } });
}
// 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 });
{
_ = zgui.begin("Information", .{});
defer zgui.end();
for (0..8) |i| {
@@ -202,8 +124,8 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
widgets.interrupts("IRQ", cpu.bus.io.irq);
}
if (state.win_stat.show_perf) {
_ = zgui.begin("Performance", .{ .popen = &state.win_stat.show_perf });
{
_ = zgui.begin("Performance", .{});
defer zgui.end();
const tmp = blk: {
@@ -265,8 +187,8 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
zgui.text(" 1% Low: {:0>3} fps", .{stats[2]});
}
if (state.win_stat.show_schedule) {
_ = zgui.begin("Schedule", .{ .popen = &state.win_stat.show_schedule });
{
_ = zgui.begin("Scheduler", .{});
defer zgui.end();
const scheduler = cpu.sched;
@@ -287,59 +209,12 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void {
}
}
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);
}
// {
// 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;
@@ -430,13 +305,3 @@ 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{};
}

View File

@@ -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 != 0 or paths.bios == null) {
if (config.config().guest.skip_bios or result.args.skip 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 != 0) {
if (result.args.gdb) {
const Server = @import("gdbstub").Server;
const EmuThing = @import("core/emu.zig").EmuThing;