// Copyright (c) 2021 Dominic Msters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "glfwclient.h" static game_t *GAME_STATE; static GLFWwindow *window = NULL; int32_t main() { double time, newTime; game_t *game; input_t *input; float fDelta; // Attempt to init GLFW if(!glfwInit()) return 1; // Setup window hints glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false); // Create Window window = glfwCreateWindow( WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT, "", NULL, NULL ); if(!window) { glfwTerminate(); return 1; } // Load GLAD glfwMakeContextCurrent(window); glfwSwapInterval(0); gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); // Setup window listeners glfwSetWindowSizeCallback(window, &glfwOnResize); glfwSetKeyCallback(window, &glfwOnKey); glfwSetErrorCallback(&glfwOnError); glfwSetCursorPosCallback(window, &glfwOnCursor); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); // Prepare the game game = malloc(sizeof(game_t)); ASSERT_NOT_NULL(game); GAME_STATE = game; input = &game->engine.input; printf("Game is %zu bytes.\n", sizeof(game_t)); // Init the render resolution renderSetResolution(&game->engine.render, WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT ); // Init the game if(gameInit(game)) { // Bind initial keys inputBind(input, INPUT_NULL, glfwGetInputSourceForKey(GLFW_KEY_ESCAPE)); inputBind(input, INPUT_UP, glfwGetInputSourceForKey(GLFW_KEY_UP)); inputBind(input, INPUT_DOWN, glfwGetInputSourceForKey(GLFW_KEY_DOWN)); inputBind(input, INPUT_LEFT, glfwGetInputSourceForKey(GLFW_KEY_LEFT)); inputBind(input, INPUT_RIGHT, glfwGetInputSourceForKey(GLFW_KEY_RIGHT)); inputBind(input, INPUT_UP, glfwGetInputSourceForKey(GLFW_KEY_W)); inputBind(input, INPUT_DOWN, glfwGetInputSourceForKey(GLFW_KEY_S)); inputBind(input, INPUT_LEFT, glfwGetInputSourceForKey(GLFW_KEY_A)); inputBind(input, INPUT_RIGHT, glfwGetInputSourceForKey(GLFW_KEY_D)); inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_E)); inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_ENTER)); inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_SPACE)); // Bind the fake inputs inputBind(input, INPUT_MOUSE_X, GLFW_PLATFORM_INPUT_MOUSE_X); inputBind(input, INPUT_MOUSE_Y, GLFW_PLATFORM_INPUT_MOUSE_Y); // Set up some GLFW stuff glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetWindowTitle(window, game->engine.name); // Begin time. time = 0; // Main Render Loop while(!glfwWindowShouldClose(window)) { glfwPollEvents(); // Determine the delta. newTime = glfwGetTime(); fDelta = (float)(newTime - time); time = newTime; // Tick the engine. if(!gameUpdate(game, fDelta)) break; glfwSwapBuffers(window); sleep(0);//Fixes some weird high CPU bug, not actually necessary. } // Game has finished running, cleanup. gameDispose(game); } free(game); // Terminate the GLFW context. glfwSetWindowSizeCallback(window, NULL); glfwTerminate(); return 0; } void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) { ASSERT_NOT_NULL(window); ASSERT_GREATER_THAN(width, 0); ASSERT_GREATER_THAN(height, 0); renderSetResolution(&GAME_STATE->engine.render, (float)width, (float)height); } void glfwOnKey(GLFWwindow *window, int32_t key, int32_t scancode, int32_t action, int32_t mods ) { input_t *input; ASSERT_NOT_NULL(window); input = &GAME_STATE->engine.input; if(action == GLFW_PRESS) { inputStateSet(input, glfwGetInputSourceForKey(key), 1.0f); } else if(action == GLFW_RELEASE) { inputStateSet(input, glfwGetInputSourceForKey(key), 0.0f); } } void glfwOnError(int error, const char* description) { fputs(description, stderr); } void glfwOnCursor(GLFWwindow *window, double x, double y) { input_t *input; ASSERT_NOT_NULL(window); input = &GAME_STATE->engine.input; inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_X, (float)x); inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_Y, (float)y); } inputsource_t glfwGetInputSourceForKey(int32_t key) { return (inputsource_t)(( key <= GLFW_KEY_GRAVE_ACCENT ? key - GLFW_KEY_SPACE : key <= GLFW_KEY_MENU ? key - GLFW_KEY_ESCAPE + GLFW_KEY_GRAVE_ACCENT : key ) % INPUT_SOURCE_COUNT); } void glfwClientSetTitle(char *name) { ASSERT_NOT_NULL(window); glfwSetWindowTitle(window, name); }