From c3ff2ed6c16b58eddb16143c434b7aa1d03c6f93 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:13 -0300 Subject: [PATCH] feat: parse cartridge header --- src/bus/GamePak.zig | 36 +++++++++++++++++++++++++++++++++--- src/main.zig | 11 +++++++---- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/bus/GamePak.zig b/src/bus/GamePak.zig index 979ce37..f7dd515 100644 --- a/src/bus/GamePak.zig +++ b/src/bus/GamePak.zig @@ -3,18 +3,48 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const Self = @This(); +title: [12]u8, buf: []u8, alloc: Allocator, +const log = std.log.scoped(.GamePak); + pub fn init(alloc: Allocator, path: []const u8) !Self { const file = try std.fs.cwd().openFile(path, .{}); defer file.close(); const len = try file.getEndPos(); + const buf = try file.readToEndAlloc(alloc, len); + const title = parseTitle(buf); - return Self{ - .buf = try file.readToEndAlloc(alloc, len), - .alloc = alloc, + const pak = Self{ .buf = buf, .alloc = alloc, .title = title }; + pak.parseHeader(); + + return pak; +} + +fn parseHeader(self: *const Self) void { + const title = parseTitle(self.buf); + const code = self.buf[0xAC..0xB0]; + const maker = self.buf[0xB0..0xB2]; + const version = self.buf[0xBC]; + + log.info("Title: {s}", .{title}); + if (version != 0) log.info("Version: {}", .{version}); + log.info("Game Code: {s}", .{code}); + if (lookupMaker(maker)) |c| log.info("Maker Code: {s}", .{c}) else log.info("Maker: {s}", .{maker}); +} + +fn parseTitle(buf: []u8) [12]u8 { + return buf[0xA0..0xAC].*; +} + +fn lookupMaker(slice: *const [2]u8) ?[]const u8 { + const num = @as(u16, slice[1]) << 8 | @as(u16, slice[0]); + + return switch (num) { + 0x3130 => "Nintendo", + else => null, }; } diff --git a/src/main.zig b/src/main.zig index 0fcb3e8..1095985 100644 --- a/src/main.zig +++ b/src/main.zig @@ -94,8 +94,11 @@ pub fn main() anyerror!void { if (status < 0) sdlPanic(); defer SDL.SDL_Quit(); + var title_buf: [0x20]u8 = [_]u8{0x00} ** 0x20; + const title = try std.fmt.bufPrint(&title_buf, "ZBA | {s}", .{bus.pak.title}); + var window = SDL.SDL_CreateWindow( - "ZBA", + title.ptr, SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, gba_width * window_scale, @@ -111,8 +114,8 @@ pub fn main() anyerror!void { defer SDL.SDL_DestroyTexture(texture); // Init FPS Timer + // var fps_buf: [0x100]u8 = [_]u8{0x00} ** 0x100; // var timer = Timer.start() catch unreachable; - // var title_buf: [0x30]u8 = [_]u8{0x00} ** 0x30; emu_loop: while (true) { var event: SDL.SDL_Event = undefined; @@ -167,8 +170,8 @@ pub fn main() anyerror!void { SDL.SDL_RenderPresent(renderer); // const fps = std.time.ns_per_s / timer.lap(); - // const title = std.fmt.bufPrint(&title_buf, "ZBA FPS: {d}", .{fps}) catch unreachable; - // SDL.SDL_SetWindowTitle(window, title.ptr); + // const fps_title = std.fmt.bufPrint(&fps_buf, "{s} [FPS: {d}]", .{ title, fps }) catch unreachable; + // SDL.SDL_SetWindowTitle(window, fps_title.ptr); pause.store(false, .Unordered); }