chore(main): report errors slightly better
This commit is contained in:
parent
2474daa3ae
commit
b133880064
54
src/main.zig
54
src/main.zig
|
@ -30,29 +30,33 @@ pub fn main() anyerror!void {
|
||||||
// Main Allocator for ZBA
|
// Main Allocator for ZBA
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
defer std.debug.assert(!gpa.deinit());
|
defer std.debug.assert(!gpa.deinit());
|
||||||
|
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
// TODO: Make Error message not Linux Specific
|
// Determine the Data Directory (stores saves, config file, etc.)
|
||||||
const data_path = try known_folders.getPath(allocator, .data) orelse exit("Unable to Determine XDG Data Path", .{});
|
const data_path = blk: {
|
||||||
|
const result = known_folders.getPath(allocator, .data);
|
||||||
|
const option = result catch |e| exitln("interrupted while attempting to find a data directory: {}", .{e});
|
||||||
|
break :blk option orelse exitln("no valid data directory could be found", .{});
|
||||||
|
};
|
||||||
defer allocator.free(data_path);
|
defer allocator.free(data_path);
|
||||||
|
|
||||||
const config_path = try configFilePath(allocator, data_path);
|
// Parse CLI
|
||||||
defer allocator.free(config_path);
|
const result = clap.parse(clap.Help, ¶ms, clap.parsers.default, .{}) catch |e| exitln("failed to parse cli: {}", .{e});
|
||||||
|
|
||||||
const save_path = try savePath(allocator, data_path);
|
|
||||||
defer allocator.free(save_path);
|
|
||||||
|
|
||||||
try config.load(allocator, config_path);
|
|
||||||
|
|
||||||
// Handle CLI Input
|
|
||||||
const result = try clap.parse(clap.Help, ¶ms, clap.parsers.default, .{});
|
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
|
|
||||||
const paths = try handleArguments(allocator, data_path, &result);
|
// TODO: Move config file to XDG Config directory?
|
||||||
|
const config_path = configFilePath(allocator, data_path) catch |e| exitln("failed to determine the config file path for ZBA: {}", .{e});
|
||||||
|
defer allocator.free(config_path);
|
||||||
|
|
||||||
|
config.load(allocator, config_path) catch |e| exitln("failed to read config file: {}", .{e});
|
||||||
|
|
||||||
|
const paths = handleArguments(allocator, data_path, &result) catch |e| exitln("failed to handle cli arguments: {}", .{e});
|
||||||
defer if (paths.save) |path| allocator.free(path);
|
defer if (paths.save) |path| allocator.free(path);
|
||||||
|
|
||||||
const cpu_trace = config.config().debug.cpu_trace;
|
const log_file = if (config.config().debug.cpu_trace) blk: {
|
||||||
const log_file: ?std.fs.File = if (cpu_trace) try std.fs.cwd().createFile("zba.log", .{}) else null;
|
break :blk std.fs.cwd().createFile("zba.log", .{}) catch |e| exitln("failed to create trace log file: {}", .{e});
|
||||||
|
} else null;
|
||||||
defer if (log_file) |file| file.close();
|
defer if (log_file) |file| file.close();
|
||||||
|
|
||||||
// TODO: Take Emulator Init Code out of main.zig
|
// TODO: Take Emulator Init Code out of main.zig
|
||||||
|
@ -62,7 +66,7 @@ pub fn main() anyerror!void {
|
||||||
var bus: Bus = undefined;
|
var bus: Bus = undefined;
|
||||||
var cpu = Arm7tdmi.init(&scheduler, &bus, log_file);
|
var cpu = Arm7tdmi.init(&scheduler, &bus, log_file);
|
||||||
|
|
||||||
try bus.init(allocator, &scheduler, &cpu, paths);
|
bus.init(allocator, &scheduler, &cpu, paths) catch |e| exitln("failed to init zba bus: {}", .{e});
|
||||||
defer bus.deinit();
|
defer bus.deinit();
|
||||||
|
|
||||||
if (config.config().guest.skip_bios or result.args.skip or paths.bios == null) {
|
if (config.config().guest.skip_bios or result.args.skip or paths.bios == null) {
|
||||||
|
@ -72,7 +76,7 @@ pub fn main() anyerror!void {
|
||||||
var gui = Gui.init(&bus.pak.title, &bus.apu, width, height);
|
var gui = Gui.init(&bus.pak.title, &bus.apu, width, height);
|
||||||
defer gui.deinit();
|
defer gui.deinit();
|
||||||
|
|
||||||
try gui.run(&cpu, &scheduler);
|
gui.run(&cpu, &scheduler) catch |e| exitln("failed to run gui thread: {}", .{e});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) !FilePaths {
|
pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) !FilePaths {
|
||||||
|
@ -80,12 +84,12 @@ pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *con
|
||||||
log.info("ROM path: {s}", .{rom_path});
|
log.info("ROM path: {s}", .{rom_path});
|
||||||
|
|
||||||
const bios_path = result.args.bios;
|
const bios_path = result.args.bios;
|
||||||
if (bios_path) |path| log.info("BIOS path: {s}", .{path}) else log.info("No BIOS provided", .{});
|
if (bios_path) |path| log.info("BIOS path: {s}", .{path}) else log.warn("No BIOS provided", .{});
|
||||||
|
|
||||||
const save_path = try savePath(allocator, data_path);
|
const save_path = try savePath(allocator, data_path);
|
||||||
log.info("Save path: {s}", .{save_path});
|
log.info("Save path: {s}", .{save_path});
|
||||||
|
|
||||||
return FilePaths{
|
return .{
|
||||||
.rom = rom_path,
|
.rom = rom_path,
|
||||||
.bios = bios_path,
|
.bios = bios_path,
|
||||||
.save = save_path,
|
.save = save_path,
|
||||||
|
@ -94,13 +98,16 @@ pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *con
|
||||||
|
|
||||||
fn configFilePath(allocator: Allocator, data_path: []const u8) ![]const u8 {
|
fn configFilePath(allocator: Allocator, data_path: []const u8) ![]const u8 {
|
||||||
const path = try std.fs.path.join(allocator, &[_][]const u8{ data_path, "zba", "config.toml" });
|
const path = try std.fs.path.join(allocator, &[_][]const u8{ data_path, "zba", "config.toml" });
|
||||||
|
errdefer allocator.free(path);
|
||||||
|
|
||||||
// We try to create the file exclusively, meaning that we err out if the file already exists.
|
// We try to create the file exclusively, meaning that we err out if the file already exists.
|
||||||
// All we care about is a file being there so we can just ignore that error in particular and
|
// All we care about is a file being there so we can just ignore that error in particular and
|
||||||
// continue down the happy pathj
|
// continue down the happy pathj
|
||||||
std.fs.accessAbsolute(path, .{}) catch {
|
std.fs.accessAbsolute(path, .{}) catch {
|
||||||
const file_handle = try std.fs.createFileAbsolute(path, .{});
|
const file_handle = try std.fs.createFileAbsolute(path, .{});
|
||||||
file_handle.close();
|
defer file_handle.close();
|
||||||
|
|
||||||
|
// TODO: Write Default valeus to config file
|
||||||
};
|
};
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
@ -120,13 +127,14 @@ fn savePath(allocator: Allocator, data_path: []const u8) ![]const u8 {
|
||||||
fn romPath(result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) []const u8 {
|
fn romPath(result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) []const u8 {
|
||||||
return switch (result.positionals.len) {
|
return switch (result.positionals.len) {
|
||||||
1 => result.positionals[0],
|
1 => result.positionals[0],
|
||||||
0 => exit("ZBA requires a path to a GamePak ROM\n", .{}),
|
0 => exitln("ZBA requires a path to a GamePak ROM", .{}),
|
||||||
else => exit("ZBA received too many positional arguments. \n", .{}),
|
else => exitln("ZBA received too many positional arguments.", .{}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit(comptime format: []const u8, args: anytype) noreturn {
|
fn exitln(comptime format: []const u8, args: anytype) noreturn {
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
stderr.print(format, args) catch {}; // Just exit already...
|
stderr.print(format, args) catch {}; // Just exit already...
|
||||||
|
stderr.writeByte('\n') catch {};
|
||||||
std.os.exit(1);
|
std.os.exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue