Add game_init_window, separate window and game hot reload
This commit is contained in:
parent
8d397f3941
commit
0390109ff4
94
src/game.zig
94
src/game.zig
@ -1,14 +1,62 @@
|
||||
const std = @import("std");
|
||||
const c = @import("c.zig");
|
||||
|
||||
pub const InitMemory = struct {
|
||||
global_allocator: std.mem.Allocator,
|
||||
window: *c.SDL_Window,
|
||||
context: ?*anyopaque,
|
||||
some_var: i32 = 0,
|
||||
};
|
||||
|
||||
pub const GameMemory = struct {
|
||||
global_allocator: std.mem.Allocator,
|
||||
counter: i32 = 0,
|
||||
};
|
||||
|
||||
var g_init: *InitMemory = undefined;
|
||||
var g_mem: *GameMemory = undefined;
|
||||
|
||||
fn game_init_window_err(global_allocator: std.mem.Allocator) !void {
|
||||
try sdl_try(c.SDL_Init(c.SDL_INIT_EVERYTHING));
|
||||
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_DOUBLEBUFFER, 1));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_MAJOR_VERSION, 4));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_MINOR_VERSION, 1));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_PROFILE_MASK, c.SDL_GL_CONTEXT_PROFILE_CORE));
|
||||
|
||||
const maybe_window = c.SDL_CreateWindow("Learn OpenGL with Zig!", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, 800, 600, c.SDL_WINDOW_SHOWN | c.SDL_WINDOW_OPENGL);
|
||||
if (maybe_window == null) {
|
||||
std.log.err("SDL Error: {s}", .{c.SDL_GetError()});
|
||||
return error.SDLWindowError;
|
||||
}
|
||||
const window = maybe_window.?;
|
||||
|
||||
const context = c.SDL_GL_CreateContext(window);
|
||||
|
||||
if (c.gladLoadGLLoader(c.SDL_GL_GetProcAddress) == 0) {
|
||||
return error.GladInitError;
|
||||
}
|
||||
|
||||
std.log.debug("OpenGL Version: {}.{}", .{ c.GLVersion.major, c.GLVersion.minor });
|
||||
|
||||
g_init = try global_allocator.create(InitMemory);
|
||||
g_init.* = .{
|
||||
.global_allocator = global_allocator,
|
||||
.window = window,
|
||||
.context = context,
|
||||
};
|
||||
}
|
||||
|
||||
export fn game_init_window(global_allocator: *std.mem.Allocator) void {
|
||||
std.log.debug("game_init_window\n", .{});
|
||||
game_init_window_err(global_allocator.*) catch |err| {
|
||||
std.log.err("Failed to init window {}\n", .{err});
|
||||
@panic("Failed to init window");
|
||||
};
|
||||
}
|
||||
|
||||
export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
std.log.debug("game_init\n", .{});
|
||||
g_mem = global_allocator.create(GameMemory) catch @panic("OOM");
|
||||
g_mem.* = .{
|
||||
.global_allocator = global_allocator.*,
|
||||
@ -28,29 +76,71 @@ export fn game_update() bool {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
c.SDL_WINDOWEVENT => {
|
||||
switch (event.window.type) {
|
||||
c.SDL_WINDOWEVENT_SIZE_CHANGED => {
|
||||
// var width = event.window.data1;
|
||||
// var height = event.window.data2;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
g_mem.counter += 1;
|
||||
|
||||
c.glClearColor(0.3, 0.6, 0.3, 1.0);
|
||||
c.glClear(c.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
c.SDL_GL_SwapWindow(g_init.window);
|
||||
c.SDL_Delay(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export fn game_shutdown() void {
|
||||
std.log.debug("game_shutdown\n", .{});
|
||||
g_mem.global_allocator.destroy(g_mem);
|
||||
}
|
||||
|
||||
export fn game_hot_reload(memory: *anyopaque) void {
|
||||
g_mem = @alignCast(@ptrCast(memory));
|
||||
export fn game_shutdown_window() void {
|
||||
std.log.debug("game_shutdown_window\n", .{});
|
||||
c.SDL_GL_DeleteContext(g_init.context);
|
||||
c.SDL_DestroyWindow(g_init.window);
|
||||
g_init.global_allocator.destroy(g_init);
|
||||
c.SDL_Quit();
|
||||
}
|
||||
|
||||
export fn game_hot_reload(init_memory: ?*anyopaque, gmemory: ?*anyopaque) void {
|
||||
std.log.debug("game_hot_reload {any} {any}\n", .{ init_memory, gmemory });
|
||||
if (init_memory) |init_mem| {
|
||||
g_init = @alignCast(@ptrCast(init_mem));
|
||||
}
|
||||
if (gmemory) |gmem| {
|
||||
g_mem = @alignCast(@ptrCast(gmem));
|
||||
}
|
||||
}
|
||||
|
||||
export fn game_memory() *anyopaque {
|
||||
return @ptrCast(g_mem);
|
||||
}
|
||||
|
||||
export fn game_init_memory() *anyopaque {
|
||||
return @ptrCast(g_init);
|
||||
}
|
||||
|
||||
export fn game_memory_size() usize {
|
||||
return @sizeOf(GameMemory);
|
||||
}
|
||||
|
||||
export fn game_init_memory_size() usize {
|
||||
return @sizeOf(InitMemory);
|
||||
}
|
||||
|
||||
fn sdl_try(result: c_int) !void {
|
||||
if (result < 0) {
|
||||
std.log.err("SDL Error: {s}", .{c.SDL_GetError()});
|
||||
return error.SDLError;
|
||||
}
|
||||
}
|
||||
|
88
src/main.zig
88
src/main.zig
@ -2,13 +2,6 @@ const std = @import("std");
|
||||
const c = @import("c.zig");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
fn sdl_try(result: c_int) !void {
|
||||
if (result < 0) {
|
||||
std.log.err("SDL Error: {s}", .{c.SDL_GetError()});
|
||||
return error.SDLError;
|
||||
}
|
||||
}
|
||||
|
||||
const game_lib_basename = "learnopengl";
|
||||
const game_lib_name: [:0]const u8 = builtin.target.libPrefix() ++ game_lib_basename ++ builtin.target.dynamicLibSuffix();
|
||||
|
||||
@ -23,31 +16,11 @@ pub fn main() !void {
|
||||
|
||||
const game_lib_path = try getGameLibPath(allocator);
|
||||
|
||||
try sdl_try(c.SDL_Init(c.SDL_INIT_EVERYTHING));
|
||||
defer c.SDL_Quit();
|
||||
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_DOUBLEBUFFER, 1));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_MAJOR_VERSION, 4));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_MINOR_VERSION, 1));
|
||||
try sdl_try(c.SDL_GL_SetAttribute(c.SDL_GL_CONTEXT_PROFILE_MASK, c.SDL_GL_CONTEXT_PROFILE_CORE));
|
||||
|
||||
const maybe_window = c.SDL_CreateWindow("Learn OpenGL with Zig!", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, 800, 600, c.SDL_WINDOW_SHOWN | c.SDL_WINDOW_OPENGL);
|
||||
if (maybe_window == null) {
|
||||
std.log.err("SDL Error: {s}", .{c.SDL_GetError()});
|
||||
return error.SDLWindowError;
|
||||
}
|
||||
const window = maybe_window.?;
|
||||
|
||||
const context = c.SDL_GL_CreateContext(window);
|
||||
defer c.SDL_GL_DeleteContext(context);
|
||||
|
||||
_ = c.gladLoadGLLoader(c.SDL_GL_GetProcAddress);
|
||||
|
||||
std.log.debug("OpenGL Version: {}.{}", .{ c.GLVersion.major, c.GLVersion.minor });
|
||||
|
||||
var modified = try getFileModifiedZ(game_lib_path);
|
||||
game_api = try loadGameAPI(allocator, game_lib_path);
|
||||
|
||||
game_api.game_init_window(&allocator);
|
||||
|
||||
game_api.game_init(&allocator);
|
||||
defer {
|
||||
game_api.game_shutdown();
|
||||
@ -65,25 +38,42 @@ pub fn main() !void {
|
||||
modified = new_modified;
|
||||
var new_game_api = try loadGameAPI(allocator, game_lib_path);
|
||||
|
||||
if (game_api.game_memory_size() == new_game_api.game_memory_size()) {
|
||||
std.log.debug("Hot reload with state!\n", .{});
|
||||
const game_memory = game_api.game_memory();
|
||||
game_api.deinit(allocator);
|
||||
new_game_api.game_hot_reload(game_memory);
|
||||
game_api = new_game_api;
|
||||
} else {
|
||||
std.log.debug("Hot reload with shutdown!\n", .{});
|
||||
game_api.game_shutdown();
|
||||
game_api.deinit(allocator);
|
||||
game_api = new_game_api;
|
||||
game_api.game_init(&allocator);
|
||||
var recreate_state = false;
|
||||
var recreate_window = false;
|
||||
|
||||
const game_init_memory = game_api.game_init_memory();
|
||||
const game_memory = game_api.game_memory();
|
||||
|
||||
if (game_api.game_memory_size() != new_game_api.game_memory_size()) {
|
||||
recreate_state = true;
|
||||
}
|
||||
if (game_api.game_init_memory_size() != new_game_api.game_init_memory_size()) {
|
||||
recreate_window = true;
|
||||
}
|
||||
|
||||
if (recreate_state) {
|
||||
game_api.game_shutdown();
|
||||
}
|
||||
if (recreate_window) {
|
||||
game_api.game_shutdown_window();
|
||||
}
|
||||
|
||||
if (recreate_window) {
|
||||
new_game_api.game_init_window(&allocator);
|
||||
} else {
|
||||
new_game_api.game_hot_reload(game_init_memory, null);
|
||||
}
|
||||
if (recreate_state) {
|
||||
new_game_api.game_init(&allocator);
|
||||
} else {
|
||||
new_game_api.game_hot_reload(null, game_memory);
|
||||
}
|
||||
|
||||
game_api.deinit(allocator);
|
||||
game_api = new_game_api;
|
||||
}
|
||||
|
||||
exit = !game_api.game_update();
|
||||
|
||||
c.SDL_GL_SwapWindow(window);
|
||||
c.SDL_Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,22 +118,30 @@ fn loadGameAPI(arena: std.mem.Allocator, game_lib_path: [:0]const u8) !GameAPI {
|
||||
}
|
||||
|
||||
const GameAPI = struct {
|
||||
game_init_window: *const fn (*std.mem.Allocator) callconv(.C) void,
|
||||
game_init: *const fn (*std.mem.Allocator) callconv(.C) void,
|
||||
game_update: *const fn () callconv(.C) bool,
|
||||
game_shutdown: *const fn () callconv(.C) void,
|
||||
game_shutdown_window: *const fn () callconv(.C) void,
|
||||
game_memory_size: *const fn () callconv(.C) usize,
|
||||
game_init_memory_size: *const fn () callconv(.C) usize,
|
||||
game_memory: *const fn () callconv(.C) *anyopaque,
|
||||
game_hot_reload: *const fn (*anyopaque) callconv(.C) void,
|
||||
game_init_memory: *const fn () callconv(.C) *anyopaque,
|
||||
game_hot_reload: *const fn (?*anyopaque, ?*anyopaque) callconv(.C) void,
|
||||
dll: ?*anyopaque,
|
||||
path: [:0]const u8,
|
||||
|
||||
pub fn init(dll: ?*anyopaque, path: [:0]const u8) !GameAPI {
|
||||
return GameAPI{
|
||||
.game_init_window = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_init_window") orelse return error.MissingGameInitWindow)),
|
||||
.game_init = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_init") orelse return error.MissingGameInit)),
|
||||
.game_update = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_update") orelse return error.MissingGameUpdate)),
|
||||
.game_shutdown = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_shutdown") orelse return error.MissingGameShutdown)),
|
||||
.game_shutdown_window = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_shutdown_window") orelse return error.MissingGameShutdownWindow)),
|
||||
.game_memory_size = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_memory_size") orelse return error.MissingGameMemorySize)),
|
||||
.game_init_memory_size = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_init_memory_size") orelse return error.MissingGameInitMemorySize)),
|
||||
.game_memory = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_memory") orelse return error.MissingGameMemory)),
|
||||
.game_init_memory = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_init_memory") orelse return error.MissingGameInitMemory)),
|
||||
.game_hot_reload = @alignCast(@ptrCast(c.SDL_LoadFunction(dll, "game_hot_reload") orelse return error.MissingGameHotReload)),
|
||||
.dll = dll,
|
||||
.path = path,
|
||||
|
Loading…
x
Reference in New Issue
Block a user