mirror of
https://github.com/thepigeongenerator/mcaselector-lite.git
synced 2025-12-18 11:35:46 +01:00
Compare commits
13 Commits
535e3e6a9c
...
76c992efdc
| Author | SHA1 | Date | |
|---|---|---|---|
| 76c992efdc | |||
| 28b98705f5 | |||
| 057b234251 | |||
| dd2f4c403c | |||
| dc3abf992b | |||
| 1e10fec9c6 | |||
| 41d944ac21 | |||
| faa93f4372 | |||
| e3c0afbb2f | |||
| 11c8748262 | |||
| 25fa078c98 | |||
| 023123e54f | |||
| b13739c782 |
@@ -99,10 +99,6 @@ IncludeIsMainSourceRegex: ''
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^<glad/gl\.h>'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: true
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
|
||||
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
restore-keys: ${{runner.os}}_${{runner.arch}}-lib/obj-
|
||||
|
||||
- run: make -Bj libs
|
||||
if: ${{steps.cache-deps.outputs.cache-hit}} != 'true'
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
|
||||
- run: make -j all
|
||||
- run: make -j test
|
||||
|
||||
1
Makefile
1
Makefile
@@ -12,6 +12,7 @@ CMAKE ?= cmake -G 'Unix Makefiles'
|
||||
CPPFLAGS ?=
|
||||
CFLAGS ?= -O2 -Wall -Wextra -Wpedantic -Wno-pointer-arith
|
||||
LDFLAGS ?= -flto
|
||||
CPPFLAGS += -DGLFW_INCLUDE_NONE
|
||||
CFLAGS += -std=gnu99
|
||||
|
||||
# add a few extra flags depending on whether
|
||||
|
||||
18
src/error.c
18
src/error.c
@@ -1,3 +1,5 @@
|
||||
/* Copyright (c) 2025 Quinn
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#include "error.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -13,35 +15,41 @@ static void error_log(FILE *restrict stream, const char *restrict pfx, uint ln,
|
||||
fprintf(stream, "'\n");
|
||||
}
|
||||
|
||||
void error_dbg(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
void error_debug(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
#ifndef NDEBUG
|
||||
#else
|
||||
char *env = getenv("DEBUG");
|
||||
if (env && env[0] != '1')
|
||||
return;
|
||||
#endif
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error_log(stdout, "\033[95mDBG\033[0m", ln, file, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void error_inf(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
void error_info(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error_log(stdout, "\033[94mINF\033[0m", ln, file, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void error_war(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
void error_warn(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error_log(stdout, "\033[93mWAR\033[0m", ln, file, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
void error_error(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error_log(stdout, "\033[91mERR\033[0m", ln, file, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
void error_fatal(uint ln, const char *restrict file, const char *restrict fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error_log(stdout, "\033[101mFAT\033[0m", ln, file, fmt, ap);
|
||||
|
||||
20
src/error.h
20
src/error.h
@@ -9,14 +9,14 @@
|
||||
#include "util/intdef.h"
|
||||
#include "util/macro.h"
|
||||
|
||||
void error_dbg(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_inf(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_war(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) NORET;
|
||||
void error_debug(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_info(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_warn(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_error(uint ln, const char *restrict file, const char *restrict fmt, ...);
|
||||
void error_fatal(uint ln, const char *restrict file, const char *restrict fmt, ...) NORET;
|
||||
|
||||
#define debug(...) error_dbg(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define info(...) error_inf(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define warn(...) error_war(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define error(...) error_err(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define fatal(...) error_fat(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define debug(...) error_debug(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define info(...) error_info(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define warn(...) error_warn(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define error(...) error_error(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
#define fatal(...) error_fatal(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
void key_callback(GLFWwindow *win, int key, int scancode, int action, int mods) {
|
||||
void input_callback(GLFWwindow *win, int key, int scancode, int action, int mods) {
|
||||
(void)win, (void)key, (void)scancode, (void)action, (void)mods; // make the compiler shut up as this is fine
|
||||
#ifndef NDEBUG
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
|
||||
@@ -4,4 +4,6 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
void key_callback(GLFWwindow *win, int key, int scancode, int action, int mods);
|
||||
/* Handles incoming key inputs for `win`.
|
||||
* Intended to be given as an argument to `glfwSetKeyCallback`. */
|
||||
void input_callback(GLFWwindow *win, int key, int scancode, int action, int mods);
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#include "render.h"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glad/gl.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../error.h"
|
||||
@@ -80,3 +79,12 @@ void render_update(GLFWwindow *win) {
|
||||
glBindVertexArray(vao);
|
||||
glDrawArrays(GL_POINTS, 0, VERTC);
|
||||
}
|
||||
|
||||
void render_free(void) {
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
glDeleteBuffers(1, &vbo);
|
||||
glDeleteProgram(pipe);
|
||||
vbo = 0;
|
||||
vao = 0;
|
||||
pipe = 0;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glad/gl.h>
|
||||
|
||||
int render_init(void);
|
||||
void render_update(GLFWwindow *win);
|
||||
void render_free(void);
|
||||
|
||||
@@ -17,7 +17,8 @@ extern const uint sh_vert_glsl_len;
|
||||
extern const uint sh_frag_glsl_len;
|
||||
extern const uint sh_geom_glsl_len;
|
||||
|
||||
/* compile a shader */
|
||||
/* Compiles a shader of `type` from `src` with `len` bytes.
|
||||
* Returns the integer for the shader. */
|
||||
static GLuint shader_compile(GLenum type, const char *src, size_t len) {
|
||||
int ilen = len;
|
||||
GLuint shader = glCreateShader(type);
|
||||
@@ -45,6 +46,7 @@ int shader_init(GLuint pipe) {
|
||||
glAttachShader(pipe, fs);
|
||||
glAttachShader(pipe, gs);
|
||||
|
||||
// mark shaders off for deletion
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
glDeleteShader(gs);
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Initialises the (embedded) shaders onto `pipe` */
|
||||
int shader_init(GLuint pipe);
|
||||
|
||||
@@ -2,49 +2,44 @@
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#include "window.h"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <assert.h>
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include "../error.h"
|
||||
#include "../util/intdef.h"
|
||||
#include "input.h"
|
||||
#include "render.h"
|
||||
|
||||
// macros for ease of access
|
||||
#define WIN_NAME "MCA Selector Lite"
|
||||
#define WIN_DEFAULT_WIDTH 640
|
||||
#define WIN_DEFAULT_HEIGHT 480
|
||||
|
||||
static GLFWwindow *win = NULL;
|
||||
static struct GLFWwindow *win = NULL;
|
||||
|
||||
/* Initialises the GLFW window with some defaults,
|
||||
* then proceed to activate OpenGL on it. */
|
||||
int window_init(void) {
|
||||
// initialise the window
|
||||
#ifndef NDEBUG
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
#endif
|
||||
|
||||
// initialize the window
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // sets the profile to "core", so old, deprecated functions are disabled.
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1);
|
||||
glfwWindowHint(GLFW_RED_BITS, 8);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, 8);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, 8);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 0);
|
||||
win = glfwCreateWindow(WIN_DEFAULT_WIDTH, WIN_DEFAULT_HEIGHT, WIN_NAME, NULL, NULL);
|
||||
/* NOTE: on my system; x86_64, GTX 1650 580.82.09-2, X11, i3, this causes one direct, 2 indirect memory leaks.
|
||||
* This is not my fault, and can safely be ignored. */
|
||||
win = glfwCreateWindow(640, 480, "MCA-Selector lite", NULL, NULL);
|
||||
if (!win) return 1;
|
||||
|
||||
// setup OpenGL for the window
|
||||
glfwMakeContextCurrent(win);
|
||||
if (!gladLoadGL(glfwGetProcAddress)) return 1;
|
||||
glfwSwapInterval(1); // wait 1 screen update for a redraw a.k.a. "vsync". (not really applicable in this case but eh)
|
||||
|
||||
// configure callbacks
|
||||
glfwSetKeyCallback(win, key_callback);
|
||||
glfwSetKeyCallback(win, input_callback);
|
||||
|
||||
// print the OpenGL version information
|
||||
debug(
|
||||
"version info:\n"
|
||||
"\tvendor: %s\n"
|
||||
@@ -55,20 +50,33 @@ int window_init(void) {
|
||||
glGetString(GL_RENDERER),
|
||||
glGetString(GL_VERSION),
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void window_loop(void) {
|
||||
assert(win != NULL);
|
||||
|
||||
assert(win);
|
||||
render_init();
|
||||
while (!glfwWindowShouldClose(win)) {
|
||||
glfwWaitEvents(); // wait till an update has been given
|
||||
glfwWaitEvents();
|
||||
|
||||
render_update(win);
|
||||
glfwSwapBuffers(win);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void window_close(void) {
|
||||
assert(win);
|
||||
glfwSetWindowShouldClose(win, 1);
|
||||
}
|
||||
|
||||
void window_free(void) {
|
||||
if (!win) {
|
||||
debug("window has already been freed.");
|
||||
return;
|
||||
}
|
||||
|
||||
glfwDestroyWindow(win);
|
||||
render_free();
|
||||
win = NULL;
|
||||
}
|
||||
|
||||
@@ -2,5 +2,18 @@
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#pragma once
|
||||
|
||||
int window_init(void); // initializes the global window, returns non-zero upon failure
|
||||
void window_loop(void); // performs the window updates
|
||||
/* Set up the window, enabling OpenGL, and
|
||||
* configuring the settings that are needed.
|
||||
* Returns `0` upon success, otherwise `1`. */
|
||||
int window_init(void);
|
||||
|
||||
/* Calls the update loop for the window.
|
||||
* This function does not exit until the window does. */
|
||||
void window_loop(void);
|
||||
|
||||
/* Requests the window to close (gracefully). */
|
||||
void window_close(void);
|
||||
|
||||
/* Cleans up all resources held by the window.
|
||||
* If the window is still open, it will be terminated. */
|
||||
void window_free(void);
|
||||
|
||||
39
src/main.c
39
src/main.c
@@ -1,50 +1,41 @@
|
||||
/* Copyright (c) 2025 Quinn
|
||||
* Licensed under the MIT Licence. See LICENSE for details */
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include <glad/gl.h>
|
||||
#undef GLAD_GL_IMPLEMENTATION
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glad/gl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "io/window.h"
|
||||
|
||||
|
||||
#define WIN_NAME "MCA Selector Lite"
|
||||
#define WIN_DEFAULT_WIDTH 640
|
||||
#define WIN_DEFAULT_HEIGHT 480
|
||||
|
||||
// callback for GLFW errors
|
||||
/* reroutes GLFW errors to our logging system. */
|
||||
static void error_callback(int err, const char *const msg) {
|
||||
fprintf(stderr, "\033[91mE: glfw returned (%i); \"%s\"\033[0m\n", err, msg);
|
||||
}
|
||||
|
||||
static inline int init(void) {
|
||||
glfwSetErrorCallback(error_callback);
|
||||
glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE); // disable joystick buttons
|
||||
|
||||
if (!glfwInit()) return 1; // initialize GLFW
|
||||
if (window_init()) return 1;
|
||||
|
||||
return 0;
|
||||
error("glfw returned (%i); \"%s\"", err, msg);
|
||||
}
|
||||
|
||||
static void quit(void) {
|
||||
window_free();
|
||||
|
||||
/* terminates GLFW; destroying any
|
||||
* remaining windows, or other resources held by GLFW. */
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
|
||||
/* Entry-point of the application. */
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc, (void)argv;
|
||||
printf("debug: [DBG], info: [INF], warning: [WAR], error: [ERR], fatal: [FAT]\n");
|
||||
atexit(quit);
|
||||
if (init()) fatal("failed to initialize!");
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE); // disable joystick buttons; since we won't need them
|
||||
if (!glfwInit() || window_init())
|
||||
fatal("failed to initialise!");
|
||||
|
||||
window_loop();
|
||||
quit();
|
||||
|
||||
// return success, since some architectures do not follow 0=success
|
||||
/* return success, since some architectures do not follow 0=success
|
||||
* This action will call `quit`. */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user