From a87b46898b3524036e4600efd76b47c1460ac131 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Wed, 27 Apr 2022 18:08:44 -0500 Subject: [PATCH] chore: special case saving for ROMS without titles --- src/bus/backup.zig | 26 ++++++++++++++++++-------- src/main.zig | 4 ++-- src/util.zig | 4 ++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/bus/backup.zig b/src/bus/backup.zig index 66e80b3..8b0c913 100644 --- a/src/bus/backup.zig +++ b/src/bus/backup.zig @@ -2,8 +2,8 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const log = std.log.scoped(.Backup); -const correctTitle = @import("../util.zig").correctTitle; -const safeTitle = @import("../util.zig").safeTitle; +const escape = @import("../util.zig").escape; +const asString = @import("../util.zig").asString; const intToBytes = @import("../util.zig").intToBytes; const backup_kinds = [5]Needle{ @@ -76,6 +76,11 @@ pub const Backup = struct { const file_path = try self.getSaveFilePath(path); defer self.alloc.free(file_path); + // FIXME: Don't rely on this lol + if (std.mem.eql(u8, file_path[file_path.len - 12 .. file_path.len], "untitled.sav")) { + return log.err("ROM header lacks title, no save loaded", .{}); + } + const file: std.fs.File = try std.fs.openFileAbsolute(file_path, .{}); const file_buf = try file.readToEndAlloc(self.alloc, try file.getEndPos()); defer self.alloc.free(file_buf); @@ -98,7 +103,10 @@ pub const Backup = struct { return log.info("Loaded Save from {s}", .{file_path}); } - log.err("EEPROM can either be 0x200 bytes or 0x2000 byes, but {s} was {X:} bytes", .{ file_path, file_buf.len, }); + log.err("EEPROM can either be 0x200 bytes or 0x2000 byes, but {s} was {X:} bytes", .{ + file_path, + file_buf.len, + }); }, .None => return SaveError.UnsupportedBackupKind, } @@ -112,8 +120,10 @@ pub const Backup = struct { } fn getSaveFilename(self: *const Self) ![]const u8 { - const title = correctTitle(safeTitle(self.title)); - return try std.mem.concat(self.alloc, u8, &[_][]const u8{ title, ".sav" }); + const title = asString(escape(self.title)); + const name = if (title.len != 0) title else "untitled"; + + return try std.mem.concat(self.alloc, u8, &[_][]const u8{ name, ".sav" }); } fn writeSaveToDisk(self: Self, path: []const u8) !void { @@ -411,7 +421,7 @@ const Eeprom = struct { const addr = @intCast(u10, self.writer.finish()); // TODO: Bit Verbose eh? - const value_buf = buf[@as(u13, addr) * 8..][0..8]; + const value_buf = buf[@as(u13, addr) * 8 ..][0..8]; const value = @as(u64, value_buf[7]) << 56 | @as(u64, value_buf[6]) << 48 | @as(u64, value_buf[5]) << 40 | @as(u64, value_buf[4]) << 32 | @as(u64, value_buf[3]) << 24 | @as(u64, value_buf[2]) << 16 | @as(u64, value_buf[1]) << 8 | @as(u64, value_buf[0]) << 0; self.reader.configure(value); @@ -423,7 +433,7 @@ const Eeprom = struct { const addr = @intCast(u6, self.writer.finish()); // TODO: Bit Verbose eh?, also duplicate code - const value_buf = buf[@as(u13, addr) * 8..][0..8]; + const value_buf = buf[@as(u13, addr) * 8 ..][0..8]; const value = @as(u64, value_buf[7]) << 56 | @as(u64, value_buf[6]) << 48 | @as(u64, value_buf[5]) << 40 | @as(u64, value_buf[4]) << 32 | @as(u64, value_buf[3]) << 24 | @as(u64, value_buf[2]) << 16 | @as(u64, value_buf[1]) << 8 | @as(u64, value_buf[0]) << 0; self.reader.configure(value); @@ -452,7 +462,7 @@ const Eeprom = struct { }, .WriteTransfer => { if (self.writer.len() == 64) { - std.mem.copy(u8, buf[self.addr * 8..][0..8], &intToBytes(u64, self.writer.finish())); + std.mem.copy(u8, buf[self.addr * 8 ..][0..8], &intToBytes(u64, self.writer.finish())); self.state = .RequestEnd; } }, diff --git a/src/main.zig b/src/main.zig index 5398851..3d17a3f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -29,7 +29,7 @@ const is_binary: bool = false; const log = std.log.scoped(.GUI); pub const log_level = if (builtin.mode != .Debug) .info else std.log.default_level; -const correctTitle = @import("util.zig").correctTitle; +const asString = @import("util.zig").asString; pub fn main() anyerror!void { // Allocator for Emulator + CLI @@ -106,7 +106,7 @@ pub fn main() anyerror!void { defer emu_thread.join(); var title_buf: [0x20]u8 = std.mem.zeroes([0x20]u8); - const window_title = try std.fmt.bufPrint(&title_buf, "ZBA | {s}", .{correctTitle(cpu.bus.pak.title)}); + const window_title = try std.fmt.bufPrint(&title_buf, "ZBA | {s}", .{asString(cpu.bus.pak.title)}); const window = createWindow(window_title, gba_width, gba_height); defer SDL.SDL_DestroyWindow(window); diff --git a/src/util.zig b/src/util.zig index 6a7352e..1c41edd 100644 --- a/src/util.zig +++ b/src/util.zig @@ -60,7 +60,7 @@ pub fn intToBytes(comptime T: type, value: anytype) [@sizeOf(T)]u8 { /// /// This function returns a slice of everything just before the first /// `\0` -pub fn correctTitle(title: [12]u8) []const u8 { +pub fn asString(title: [12]u8) []const u8 { var len = title.len; for (title) |char, i| { if (char == 0) { @@ -76,7 +76,7 @@ pub fn correctTitle(title: [12]u8) []const u8 { /// array consisting of ASCII that won't make any file system angry /// /// e.g. POKEPIN R/S to POKEPIN R_S -pub fn safeTitle(title: [12]u8) [12]u8 { +pub fn escape(title: [12]u8) [12]u8 { var result: [12]u8 = title; for (result) |*char| {