diff --git a/src/Gui.zig b/src/Gui.zig index ec29e8b..1e38f4f 100644 --- a/src/Gui.zig +++ b/src/Gui.zig @@ -136,12 +136,13 @@ pub fn initAudio(self: *Self, apu: *Apu) void { self.audio.?.play(); } -pub fn deinit(self: Self) void { - if (self.audio) |aud| aud.deinit(); +pub fn deinit(self: *Self) void { + if (self.audio) |*aud| aud.deinit(); SDL.SDL_DestroyTexture(self.texture); SDL.SDL_DestroyRenderer(self.renderer); SDL.SDL_DestroyWindow(self.window); SDL.SDL_Quit(); + self.* = undefined; } const Audio = struct { @@ -168,8 +169,9 @@ const Audio = struct { }; } - fn deinit(this: This) void { - SDL.SDL_CloseAudioDevice(this.device); + fn deinit(self: *This) void { + SDL.SDL_CloseAudioDevice(self.device); + self.* = undefined; } pub fn play(this: *This) void { diff --git a/src/core/Bus.zig b/src/core/Bus.zig index 408b5ee..4ea4343 100644 --- a/src/core/Bus.zig +++ b/src/core/Bus.zig @@ -49,8 +49,8 @@ io: Io, cpu: ?*Arm7tdmi, sched: *Scheduler, -pub fn init(alloc: Allocator, sched: *Scheduler, paths: FilePaths) !Self { - return Self{ +pub fn init(self: *Self, alloc: Allocator, sched: *Scheduler, cpu: *Arm7tdmi, paths: FilePaths) !void { + self.* = .{ .pak = try GamePak.init(alloc, paths.rom, paths.save), .bios = try Bios.init(alloc, paths.bios), .ppu = try Ppu.init(alloc, sched), @@ -60,21 +60,34 @@ pub fn init(alloc: Allocator, sched: *Scheduler, paths: FilePaths) !Self { .dma = createDmaTuple(), .tim = createTimerTuple(sched), .io = Io.init(), - .cpu = null, + .cpu = cpu, .sched = sched, }; } -pub fn deinit(self: Self) void { +// pub fn init(alloc: Allocator, sched: *Scheduler, paths: FilePaths) !Self { +// return Self{ +// .pak = try GamePak.init(alloc, paths.rom, paths.save), +// .bios = try Bios.init(alloc, paths.bios), +// .ppu = try Ppu.init(alloc, sched), +// .apu = Apu.init(sched), +// .iwram = try Iwram.init(alloc), +// .ewram = try Ewram.init(alloc), +// .dma = createDmaTuple(), +// .tim = createTimerTuple(sched), +// .io = Io.init(), +// .cpu = null, +// .sched = sched, +// }; +// } + +pub fn deinit(self: *Self) void { self.iwram.deinit(); self.ewram.deinit(); self.pak.deinit(); self.bios.deinit(); self.ppu.deinit(); -} - -pub fn attach(self: *Self, cpu: *Arm7tdmi) void { - self.cpu = cpu; + self.* = undefined; } pub fn dbgRead(self: *const Self, comptime T: type, address: u32) T { diff --git a/src/core/bus/Bios.zig b/src/core/bus/Bios.zig index d17a1f2..09dfc6b 100644 --- a/src/core/bus/Bios.zig +++ b/src/core/bus/Bios.zig @@ -27,8 +27,9 @@ pub fn init(alloc: Allocator, maybe_path: ?[]const u8) !Self { }; } -pub fn deinit(self: Self) void { +pub fn deinit(self: *Self) void { if (self.buf) |buf| self.alloc.free(buf); + self.* = undefined; } pub fn read(self: *Self, comptime T: type, r15: u32, addr: u32) T { diff --git a/src/core/bus/Ewram.zig b/src/core/bus/Ewram.zig index 80d493b..ce764a7 100644 --- a/src/core/bus/Ewram.zig +++ b/src/core/bus/Ewram.zig @@ -17,8 +17,9 @@ pub fn init(alloc: Allocator) !Self { }; } -pub fn deinit(self: Self) void { +pub fn deinit(self: *Self) void { self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *const Self, comptime T: type, address: usize) T { diff --git a/src/core/bus/GamePak.zig b/src/core/bus/GamePak.zig index 98504d1..995298a 100644 --- a/src/core/bus/GamePak.zig +++ b/src/core/bus/GamePak.zig @@ -58,9 +58,10 @@ inline fn isLarge(self: *const Self) bool { return self.buf.len > 0x100_0000; } -pub fn deinit(self: Self) void { - self.alloc.free(self.buf); +pub fn deinit(self: *Self) void { self.backup.deinit(); + self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *Self, comptime T: type, address: u32) T { diff --git a/src/core/bus/Iwram.zig b/src/core/bus/Iwram.zig index 40a83c9..ef247b3 100644 --- a/src/core/bus/Iwram.zig +++ b/src/core/bus/Iwram.zig @@ -17,8 +17,9 @@ pub fn init(alloc: Allocator) !Self { }; } -pub fn deinit(self: Self) void { +pub fn deinit(self: *Self) void { self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *const Self, comptime T: type, address: usize) T { diff --git a/src/core/bus/backup.zig b/src/core/bus/backup.zig index 3ffda65..327a78f 100644 --- a/src/core/bus/backup.zig +++ b/src/core/bus/backup.zig @@ -74,9 +74,10 @@ pub const Backup = struct { return null; } - pub fn deinit(self: Self) void { + pub fn deinit(self: *Self) void { if (self.save_path) |path| self.writeSaveToDisk(self.alloc, path) catch |e| log.err("Failed to write save: {}", .{e}); self.alloc.free(self.buf); + self.* = undefined; } fn loadSaveFromDisk(self: *Self, allocator: Allocator, path: []const u8) !void { diff --git a/src/core/cpu.zig b/src/core/cpu.zig index 7ef1014..1ea89cb 100644 --- a/src/core/cpu.zig +++ b/src/core/cpu.zig @@ -250,7 +250,7 @@ pub const Arm7tdmi = struct { logger: ?Logger, - pub fn init(sched: *Scheduler, bus: *Bus) Self { + pub fn init(sched: *Scheduler, bus: *Bus, log_file: ?std.fs.File) Self { return Self{ .r = [_]u32{0x00} ** 16, .sched = sched, @@ -260,14 +260,10 @@ pub const Arm7tdmi = struct { .banked_fiq = [_]u32{0x00} ** 10, .banked_r = [_]u32{0x00} ** 12, .banked_spsr = [_]PSR{.{ .raw = 0x0000_0000 }} ** 5, - .logger = null, + .logger = if (log_file) |file| Logger.init(file) else null, }; } - pub fn attach(self: *Self, log_file: std.fs.File) void { - self.logger = Logger.init(log_file); - } - inline fn bankedIdx(mode: Mode, kind: BankedKind) usize { const idx: usize = switch (mode) { .User, .System => 0, diff --git a/src/core/ppu.zig b/src/core/ppu.zig index 42cf7f0..1465045 100644 --- a/src/core/ppu.zig +++ b/src/core/ppu.zig @@ -46,23 +46,17 @@ pub const Ppu = struct { scanline_sprites: [128]?Sprite, scanline: Scanline, - pub fn init(alloc: Allocator, sched: *Scheduler) !Self { + pub fn init(allocator: Allocator, sched: *Scheduler) !Self { // Queue first Hblank sched.push(.Draw, 240 * 4); - const framebufs = try alloc.alloc(u8, (framebuf_pitch * height) * 2); - std.mem.set(u8, framebufs, 0); - - const scanline_buf = try alloc.alloc(?u16, width * 2); - std.mem.set(?u16, scanline_buf, null); - return Self{ - .vram = try Vram.init(alloc), - .palette = try Palette.init(alloc), - .oam = try Oam.init(alloc), + .vram = try Vram.init(allocator), + .palette = try Palette.init(allocator), + .oam = try Oam.init(allocator), .sched = sched, - .framebuf = FrameBuffer.init(framebufs), - .alloc = alloc, + .framebuf = try FrameBuffer.init(allocator), + .alloc = allocator, // Registers .win = Window.init(), @@ -75,17 +69,18 @@ pub const Ppu = struct { .bldalpha = .{ .raw = 0x0000 }, .bldy = .{ .raw = 0x0000 }, - .scanline = Scanline.init(scanline_buf), + .scanline = try Scanline.init(allocator), .scanline_sprites = [_]?Sprite{null} ** 128, }; } - pub fn deinit(self: Self) void { - self.framebuf.deinit(self.alloc); - self.scanline.deinit(self.alloc); + pub fn deinit(self: *Self) void { + self.framebuf.deinit(); + self.scanline.deinit(); self.vram.deinit(); self.palette.deinit(); self.oam.deinit(); + self.* = undefined; } pub fn setBgOffsets(self: *Self, comptime n: u2, word: u32) void { @@ -641,8 +636,9 @@ const Palette = struct { }; } - fn deinit(self: Self) void { + fn deinit(self: *Self) void { self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *const Self, comptime T: type, address: usize) T { @@ -689,8 +685,9 @@ const Vram = struct { }; } - fn deinit(self: Self) void { + fn deinit(self: *Self) void { self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *const Self, comptime T: type, address: usize) T { @@ -749,8 +746,9 @@ const Oam = struct { }; } - fn deinit(self: Self) void { + fn deinit(self: *Self) void { self.alloc.free(self.buf); + self.* = undefined; } pub fn read(self: *const Self, comptime T: type, address: usize) T { @@ -1213,35 +1211,38 @@ fn copyToSpriteBuffer(bldcnt: io.BldCnt, scanline: *Scanline, x: u9, bgr555: u16 const Scanline = struct { const Self = @This(); - buf: [2][]?u16, - original: []?u16, + layers: [2][]?u16, + buf: []?u16, - fn init(buf: []?u16) Self { - std.debug.assert(buf.len == width * 2); + allocator: Allocator, - const top_slice = buf[0..][0..width]; - const btm_slice = buf[width..][0..width]; + fn init(allocator: Allocator) !Self { + const buf = try allocator.alloc(?u16, width * 2); // Top & Bottom Scanline + std.mem.set(?u16, buf, null); return .{ - .buf = [_][]?u16{ top_slice, btm_slice }, - .original = buf, + // Top & Bototm Layers + .layers = [_][]?u16{ buf[0..][0..width], buf[width..][0..width] }, + .buf = buf, + .allocator = allocator, }; } fn reset(self: *Self) void { - std.mem.set(?u16, self.original, null); + std.mem.set(?u16, self.buf, null); } - fn deinit(self: Self, alloc: Allocator) void { - alloc.free(self.original); + fn deinit(self: *Self) void { + self.allocator.free(self.buf); + self.* = undefined; } fn top(self: *Self) []?u16 { - return self.buf[0]; + return self.layers[0]; } fn btm(self: *Self) []?u16 { - return self.buf[1]; + return self.layers[1]; } }; @@ -1249,31 +1250,36 @@ const Scanline = struct { const FrameBuffer = struct { const Self = @This(); - buf: [2][]u8, - original: []u8, + layers: [2][]u8, + buf: []u8, current: u1, + allocator: Allocator, + // TODO: Rename const Device = enum { Emulator, Renderer, }; - pub fn init(bufs: []u8) Self { - std.debug.assert(bufs.len == framebuf_pitch * height * 2); - - const front = bufs[0 .. framebuf_pitch * height]; - const back = bufs[framebuf_pitch * height ..]; + pub fn init(allocator: Allocator) !Self { + const framebuf_len = framebuf_pitch * height; + const buf = try allocator.alloc(u8, framebuf_len * 2); + std.mem.set(u8, buf, 0); return .{ - .buf = [2][]u8{ front, back }, - .original = bufs, + // Front and Back Framebuffers + .layers = [_][]u8{ buf[0..][0..framebuf_len], buf[framebuf_len..][0..framebuf_len] }, + .buf = buf, .current = 0, + + .allocator = allocator, }; } - fn deinit(self: Self, alloc: Allocator) void { - alloc.free(self.original); + fn deinit(self: *Self) void { + self.allocator.free(self.buf); + self.* = undefined; } pub fn swap(self: *Self) void { @@ -1281,6 +1287,6 @@ const FrameBuffer = struct { } pub fn get(self: *Self, comptime dev: Device) []u8 { - return self.buf[if (dev == .Emulator) self.current else ~self.current]; + return self.layers[if (dev == .Emulator) self.current else ~self.current]; } }; diff --git a/src/core/scheduler.zig b/src/core/scheduler.zig index 43c4b9e..8112262 100644 --- a/src/core/scheduler.zig +++ b/src/core/scheduler.zig @@ -21,8 +21,9 @@ pub const Scheduler = struct { return sched; } - pub fn deinit(self: Self) void { + pub fn deinit(self: *Self) void { self.queue.deinit(); + self.* = undefined; } pub inline fn now(self: *const Self) u64 { diff --git a/src/main.zig b/src/main.zig index 62a2518..82c5728 100644 --- a/src/main.zig +++ b/src/main.zig @@ -40,22 +40,20 @@ pub fn main() anyerror!void { const paths = try handleArguments(allocator, &result); defer if (paths.save) |path| allocator.free(path); + const log_file: ?std.fs.File = if (arm7tdmi_logging) try std.fs.cwd().createFile("zba.log", .{}) else null; + defer if (log_file) |file| file.close(); + // TODO: Take Emulator Init Code out of main.zig var scheduler = Scheduler.init(allocator); defer scheduler.deinit(); - var bus = try Bus.init(allocator, &scheduler, paths); - defer bus.deinit(); - - var arm7tdmi = Arm7tdmi.init(&scheduler, &bus); - - const log_file: ?std.fs.File = if (arm7tdmi_logging) try std.fs.cwd().createFile("zba.log", .{}) else null; - defer if (log_file) |file| file.close(); - - if (log_file) |file| arm7tdmi.attach(file); - bus.attach(&arm7tdmi); // TODO: Shrink Surface (only CPSR and r15?) + var bus: Bus = undefined; + var arm7tdmi = Arm7tdmi.init(&scheduler, &bus, log_file); if (paths.bios == null) arm7tdmi.fastBoot(); + try bus.init(allocator, &scheduler, &arm7tdmi, paths); + defer bus.deinit(); + var gui = Gui.init(bus.pak.title, width, height); gui.initAudio(&bus.apu); defer gui.deinit();