2022-10-12 21:40:38 +00:00
|
|
|
const std = @import("std");
|
|
|
|
const toml = @import("toml");
|
|
|
|
|
|
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
|
2022-10-17 20:38:41 +00:00
|
|
|
const log = std.log.scoped(.Config);
|
2022-10-12 21:40:38 +00:00
|
|
|
var state: Config = .{};
|
|
|
|
|
|
|
|
const Config = struct {
|
|
|
|
host: Host = .{},
|
|
|
|
guest: Guest = .{},
|
|
|
|
debug: Debug = .{},
|
|
|
|
|
|
|
|
/// Settings related to the Computer the Emulator is being run on
|
|
|
|
const Host = struct {
|
|
|
|
/// Using Nearest-Neighbor, multiply the resolution of the GBA Window
|
|
|
|
win_scale: i64 = 3,
|
|
|
|
/// Enable Vsync
|
|
|
|
///
|
|
|
|
/// Note: This does not affect whether Emulation is synced to 59Hz
|
|
|
|
vsync: bool = true,
|
2022-10-13 03:54:15 +00:00
|
|
|
/// Mute ZBA
|
|
|
|
mute: bool = false,
|
2022-10-12 21:40:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Settings realted to the emulation itself
|
|
|
|
const Guest = struct {
|
|
|
|
/// Whether Emulation thread to sync to Audio Callbacks
|
|
|
|
audio_sync: bool = true,
|
|
|
|
/// Whether Emulation thread should sync to 59Hz
|
|
|
|
video_sync: bool = true,
|
|
|
|
/// Whether RTC I/O should always be enabled
|
|
|
|
force_rtc: bool = false,
|
2022-10-17 20:31:07 +00:00
|
|
|
/// Skip BIOS
|
|
|
|
skip_bios: bool = false,
|
2022-10-12 21:40:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Settings related to debugging ZBA
|
|
|
|
const Debug = struct {
|
|
|
|
/// Enable CPU Trace logs
|
|
|
|
cpu_trace: bool = false,
|
2022-10-13 03:46:18 +00:00
|
|
|
/// If false and ZBA is built in debug mode, ZBA will panic on unhandled I/O
|
2022-10-12 21:40:38 +00:00
|
|
|
unhandled_io: bool = true,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
pub fn config() *const Config {
|
|
|
|
return &state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a config file and then loads it into the global state
|
2022-11-03 12:45:57 +00:00
|
|
|
pub fn load(allocator: Allocator, file_path: []const u8) !void {
|
|
|
|
var config_file = try std.fs.cwd().openFile(file_path, .{});
|
2022-10-12 21:40:38 +00:00
|
|
|
defer config_file.close();
|
|
|
|
|
2022-11-03 12:45:57 +00:00
|
|
|
log.info("loaded from {s}", .{file_path});
|
2022-10-17 20:38:41 +00:00
|
|
|
|
2022-10-12 21:40:38 +00:00
|
|
|
const contents = try config_file.readToEndAlloc(allocator, try config_file.getEndPos());
|
|
|
|
defer allocator.free(contents);
|
|
|
|
|
|
|
|
const table = try toml.parseContents(allocator, contents, null);
|
|
|
|
defer table.deinit();
|
|
|
|
|
|
|
|
// TODO: Report unknown config options
|
|
|
|
|
|
|
|
if (table.keys.get("Host")) |host| {
|
|
|
|
if (host.Table.keys.get("win_scale")) |scale| state.host.win_scale = scale.Integer;
|
|
|
|
if (host.Table.keys.get("vsync")) |vsync| state.host.vsync = vsync.Boolean;
|
2022-10-13 03:54:15 +00:00
|
|
|
if (host.Table.keys.get("mute")) |mute| state.host.mute = mute.Boolean;
|
2022-10-12 21:40:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (table.keys.get("Guest")) |guest| {
|
|
|
|
if (guest.Table.keys.get("audio_sync")) |sync| state.guest.audio_sync = sync.Boolean;
|
|
|
|
if (guest.Table.keys.get("video_sync")) |sync| state.guest.video_sync = sync.Boolean;
|
|
|
|
if (guest.Table.keys.get("force_rtc")) |forced| state.guest.force_rtc = forced.Boolean;
|
2022-10-17 20:31:07 +00:00
|
|
|
if (guest.Table.keys.get("skip_bios")) |skip| state.guest.skip_bios = skip.Boolean;
|
2022-10-12 21:40:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (table.keys.get("Debug")) |debug| {
|
|
|
|
if (debug.Table.keys.get("cpu_trace")) |trace| state.debug.cpu_trace = trace.Boolean;
|
|
|
|
if (debug.Table.keys.get("unhandled_io")) |unhandled| state.debug.unhandled_io = unhandled.Boolean;
|
|
|
|
}
|
|
|
|
}
|