// Main function // Copyright (C) 2021 Nguyễn Gia Phong // // This file is part of Black Shades. // // Black Shades is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Black Shades is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Black Shades. If not, see . pub const c = @cImport({ @cInclude("Game.h"); @cInclude("Constants.h"); }); const Loca = @import("loca").Loca; const al = @import("zeal"); const allocator = std.heap.c_allocator; const configuration = @import("config.zig"); const free = std.c.free; const gf = @import("gfz"); const gl = @import("zgl"); const misc = @import("misc.zig"); const std = @import("std"); var game: *c.Game = undefined; fn resizeWindow(window: ?*gf.Window.Impl, width: c_int, height: c_int) callconv(.C) void { c.resizeWindow(game, width, height); } fn handleKey(window: ?*gf.Window.Impl, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void { c.handleKey(game, key, action, mods); } fn look(window: ?*gf.Window.Impl, xpos: f64, ypos: f64) callconv(.C) void { c.look(game, xpos, ypos); } fn click(window: ?*gf.Window.Impl, button: c_int, action: c_int, mods: c_int) callconv(.C) void { c.click(game, button, action, mods); } pub fn main() !void { const loca = try Loca.init(allocator, .{}); defer loca.deinit(); const config = try configuration.parse(loca.user_config); defer free(config.levels.ptr); try gf.init(); defer gf.deinit() catch unreachable; const window = try gf.Window.create(config.width, config.height, "Black Shades", .{}, .{}); try window.makeCurrent(); game = c.makeGame(@bitCast(c.Config, config)).?; try window.setSizeCallback(resizeWindow); try gf.swapInterval(@boolToInt(config.vsync)); c.initGl(game); if (try gf.rawMouseMotionSupported()) try window.setInputMode(.raw_mouse_motion, true); try window.setCursorPosCallback(look); try window.setInputMode(.sticky_mouse_buttons, true); try window.setMouseButtonCallback(click); try window.setInputMode(.sticky_keys, true); try window.setKeyCallback(handleKey); const device = try al.Device.init(null); defer device.deinit() catch unreachable; const context = try al.Context.init(device, &.{}); defer context.deinit() catch unreachable; try context.makeCurrent(); c.initGame(game); defer c.closeGame(game); while (!try window.shouldClose()) { c.eventLoop(game); try window.swapBuffers(); try gf.pollEvents(); } }