ona/src/main.zig

140 lines
4.2 KiB
Zig
Raw Normal View History

2022-09-22 23:03:25 +02:00
const ext = @cImport({
2022-08-10 15:52:16 +02:00
@cInclude("SDL2/SDL.h");
});
const errors = @import("./errors.zig");
const io = @import("./io.zig");
const stack = @import("./stack.zig");
2022-08-10 15:52:16 +02:00
const std = @import("std");
const Request = struct {
next: ?*Request = null,
frame: anyframe,
message: union(enum) {
close: struct {
2022-09-22 23:03:25 +02:00
file: *ext.SDL_RWops,
is_closed: *bool,
},
open_readable: struct {
uri: *const io.Uri,
2022-09-22 23:03:25 +02:00
file: ?*ext.SDL_RWops,
},
},
};
///
/// Entry point.
///
2022-08-10 15:52:16 +02:00
pub fn main() anyerror!void {
2022-09-22 23:03:25 +02:00
if (ext.SDL_Init(ext.SDL_INIT_EVERYTHING) != 0) {
ext.SDL_LogCritical(ext.SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize SDL2 runtime");
2022-08-10 15:52:16 +02:00
return error.InitFailure;
2022-08-10 15:52:16 +02:00
}
2022-09-22 23:03:25 +02:00
defer ext.SDL_Quit();
2022-08-10 15:52:16 +02:00
const pref_path = create_pref_path: {
2022-09-22 23:03:25 +02:00
const path = ext.SDL_GetPrefPath("ona", "ona") orelse {
ext.SDL_LogCritical(ext.SDL_LOG_CATEGORY_APPLICATION, "Failed to load user path");
return error.InitFailure;
};
break: create_pref_path path[0 .. std.mem.len(path)];
};
2022-09-22 23:03:25 +02:00
defer ext.SDL_free(pref_path.ptr);
const window = create_window: {
2022-09-22 23:03:25 +02:00
const pos = ext.SDL_WINDOWPOS_UNDEFINED;
2022-08-10 15:52:16 +02:00
var flags = @as(u32, 0);
2022-09-22 23:03:25 +02:00
break: create_window ext.SDL_CreateWindow("Ona", pos, pos, 640, 480, flags) orelse {
ext.SDL_LogCritical(ext.SDL_LOG_CATEGORY_APPLICATION, "Failed to load SDL2 window");
2022-08-10 15:52:16 +02:00
return error.InitFailure;
};
};
2022-08-10 15:52:16 +02:00
2022-09-22 23:03:25 +02:00
defer ext.SDL_DestroyWindow(window);
2022-08-10 15:52:16 +02:00
const renderer = create_renderer: {
var flags = @as(u32, 0);
2022-09-22 23:03:25 +02:00
break: create_renderer ext.SDL_CreateRenderer(window, -1, flags) orelse {
ext.SDL_LogCritical(ext.SDL_LOG_CATEGORY_APPLICATION, "Failed to load SDL2 renderer");
return error.InitFailure;
};
};
2022-09-22 23:03:25 +02:00
defer ext.SDL_DestroyRenderer(renderer);
var request_chain = @as(?*Request, null);
2022-08-10 15:52:16 +02:00
var is_running = true;
while (is_running) {
2022-09-22 23:03:25 +02:00
var event = std.mem.zeroes(ext.SDL_Event);
2022-08-10 15:52:16 +02:00
2022-09-22 23:03:25 +02:00
while (ext.SDL_PollEvent(&event) != 0) {
switch (event.type) {
2022-09-22 23:03:25 +02:00
ext.SDL_QUIT => is_running = false,
2022-08-10 15:52:16 +02:00
else => {},
}
}
2022-09-22 23:03:25 +02:00
if (ext.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255) != 0) {
ext.SDL_LogError(ext.SDL_LOG_CATEGORY_VIDEO, ext.SDL_GetError());
ext.SDL_ClearError();
}
2022-09-22 23:03:25 +02:00
if (ext.SDL_RenderClear(renderer) != 0) {
ext.SDL_LogError(ext.SDL_LOG_CATEGORY_VIDEO, ext.SDL_GetError());
ext.SDL_ClearError();
}
2022-09-22 23:03:25 +02:00
ext.SDL_RenderPresent(renderer);
while (request_chain) |request_head| {
const request = request_head;
request_chain = request_head.next;
switch (request.message) {
2022-09-22 23:03:25 +02:00
.close => |*close| close.is_closed.* = (ext.SDL_RWclose(close.file) == 0),
.open_readable => |*open_readable| {
if (open_readable.uri.isScheme("data")) {
2022-09-22 23:03:25 +02:00
var path = stack.Fixed(u8, 4096).init();
// These can never fail as the sum of the potential bytes written will
// always be less than 4096.
path.pushAll("./") catch unreachable;
std.debug.assert(open_readable.uri.writePath(path.asWriter()));
2022-09-22 23:03:25 +02:00
open_readable.file = ext.SDL_RWFromFile(&path.buffer, "r");
} else if (open_readable.uri.isScheme("user")) {
2022-09-22 23:03:25 +02:00
var path = stack.Fixed(u8, 4096).init();
const isOk = errors.isOk;
// Cannot guarantee that the sum of potential bytes written will always be
// less than path max.
if (isOk(stack.FinitePushError, path.pushAll(pref_path)) and
open_readable.uri.writePath(path.asWriter())) {
2022-09-22 23:03:25 +02:00
open_readable.file = ext.SDL_RWFromFile(&path.buffer, "r");
}
}
},
}
resume request.frame;
}
2022-09-22 23:03:25 +02:00
ext.SDL_Delay(1);
2022-08-10 15:52:16 +02:00
}
}