commit a5b87d33c4d3e21cd99f9c26cb74da0ae1c66cdc
parent bf648ab1d6ac4e21a955175413be894f6021d686
Author: Amin Mesbah <dev@aminmesbah.com>
Date:   Mon, 24 Jun 2019 17:52:14 -0700
Merge branch 'features/windows-initial-platform'
Diffstat:
4 files changed, 222 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
@@ -1,9 +1,9 @@
 *.out
 *.swp
-
 *.bc
 *.o
 
 out/*
+lib/glfw_windows/*
 
 tags
diff --git a/build.bat b/build.bat
@@ -0,0 +1,36 @@
+@echo off
+
+set CFLAGS= ^
+    -std=c99 ^
+    -nostdlib ^
+    -D_CRT_SECURE_NO_WARNINGS ^
+    -Ilib ^
+    -Ilib/glfw_windows/include ^
+    -Wall ^
+    -Wextra ^
+    -Wshadow ^
+    -Wswitch-enum ^
+    -Wno-unused-parameter ^
+    -Wno-missing-braces
+
+set LDFLAGS= ^
+    -luser32 ^
+    -lgdi32 ^
+    -lwinmm ^
+    -lopengl32 ^
+    -lshell32 ^
+    -llib/glfw_windows/lib-vc2019/glfw3.lib
+
+set RELCFLAGS= ^
+    -O2 ^
+    -Os
+
+IF NOT EXIST ".\out" mkdir ".\out"
+IF NOT EXIST ".\out\release" mkdir ".\out\release"
+
+clang ^
+    %CFLAGS% ^
+    %RELCFLAGS% ^
+    src\platform_windows.c ^
+    -o .\out\release\transparent-cube.exe ^
+    %LDFLAGS%
diff --git a/src/platform_windows.c b/src/platform_windows.c
@@ -0,0 +1,165 @@
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <glad/glad.h>
+#include <GLFW/glfw3.h>
+
+// LOL, Windef.h
+#undef near
+#undef far
+
+#include "game.c"
+#include "platform.h"
+#include "platform_windows.h"
+
+void error_callback(int error, const char* description);
+void framebuffer_size_callback(GLFWwindow* window, int width, int height);
+
+#ifdef GLAD_DEBUG
+void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...)
+{
+    printf("Calling: %s (%d arguments)\n", func_name, len_args);
+}
+#endif // GLAD_DEBUG
+
+
+int main(void)
+{
+    glfwSetErrorCallback(error_callback);
+
+    if (!glfwInit())
+    {
+        fprintf(stderr, "GLFW initialization failed\n");
+        return -1;
+    }
+
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
+    glfwWindowHint(GLFW_SAMPLES, 4);
+
+    GLFWwindow* window = glfwCreateWindow(PLATFORM_SCR_WIDTH, PLATFORM_SCR_HEIGHT, "Quaternion Demo", NULL, NULL);
+    if (!window)
+    {
+        fprintf(stderr, "GLFW window creation failed\n");
+        glfwTerminate();
+        return -1;
+    }
+    glfwMakeContextCurrent(window);
+    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+    glfwSwapInterval(1);
+
+    if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
+    {
+        fprintf(stderr, "glad initialization failed\n");
+        glfwDestroyWindow(window);
+        glfwTerminate();
+        return -1;
+    }
+
+#ifdef USE_TEST_SEED
+    srand((uint32_t)0);
+#else
+    srand((uint32_t)time(NULL));
+#endif // USE_TEST_SEED
+
+    struct GameState game_state = {0};
+    game_state.platform.platform_read_entire_file = &windows_read_entire_file;
+    game_state.platform.platform_print = &windows_print;
+    game_state.platform.platform_memory_free = &windows_memory_free;
+
+    game_init(&game_state, PLATFORM_SCR_WIDTH, PLATFORM_SCR_HEIGHT);
+
+    uint64_t lag = 0;
+    uint64_t previous_ms = (glfwGetTimerValue() * PLATFORM_SECOND) / glfwGetTimerFrequency();
+
+    while (!glfwWindowShouldClose(window))
+    {
+        uint64_t current_ms = (glfwGetTimerValue() * PLATFORM_SECOND) / glfwGetTimerFrequency();
+        uint64_t elapsed_ms = current_ms - previous_ms;
+        previous_ms = current_ms;
+        lag += elapsed_ms;
+        //printf("%" PRIu64 ", %" PRIu64 ", %f\n", elapsed_ms, lag, PLATFORM_MS_PER_UPDATE);
+
+        int32_t framebuffer_width = PLATFORM_SCR_WIDTH;
+        int32_t framebuffer_height = PLATFORM_SCR_HEIGHT;
+        glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
+
+        game_update_and_render(&game_state, lag/PLATFORM_SECOND, framebuffer_width, framebuffer_height);
+
+        glfwSwapBuffers(window);
+        glfwPollEvents();
+    }
+
+    game_cleanup(&game_state);
+
+    glfwDestroyWindow(window);
+    glfwTerminate();
+    return 0;
+}
+
+
+void error_callback(int error, const char* description)
+{
+    fprintf(stderr, "Error: %s\n", description);
+}
+
+
+void framebuffer_size_callback(GLFWwindow* window, int width, int height)
+{
+    glViewport(0, 0, width, height);
+}
+
+PLATFORM_MEMORY_FREE(windows_memory_free)
+{
+    free(ptr);
+}
+
+PLATFORM_PRINT(windows_print)
+{
+    va_list args;
+    va_start(args, format);
+    int num_chars_printed = vprintf(format, args);
+    va_end(args);
+    return num_chars_printed;
+}
+
+PLATFORM_READ_ENTIRE_FILE(windows_read_entire_file)
+{
+    FILE *handle = fopen(file_path, "rb");
+    char *buffer = NULL;
+
+    if (handle)
+    {
+        // get file size
+        fseek(handle, 0, SEEK_END);
+        u32 num_bytes_in_file = ftell(handle);
+        rewind(handle);
+
+        // TODO: replace malloc with own allocator so I stop having nightmares
+        buffer = (char*) malloc(sizeof(char) * (num_bytes_in_file + 1) );
+
+        u32 bytes_read = fread(buffer, sizeof(char), num_bytes_in_file, handle);
+        // IMPORTANT! fread() doesn't add the '\0'
+        buffer[num_bytes_in_file] = '\0';
+
+        if (num_bytes_in_file != bytes_read)
+        {
+            free(buffer);
+            buffer = NULL;
+        }
+
+        fclose(handle);
+    }
+    else
+    {
+        printf("Error: Couldn't open file at path: %s", file_path);
+        // TODO: handle errors here in a better way
+        exit(1);
+    }
+
+    return buffer;
+}
diff --git a/src/platform_windows.h b/src/platform_windows.h
@@ -0,0 +1,20 @@
+#ifndef PLATFORM_WINDOWS_H
+#define PLATFORM_WINDOWS_H
+
+#include <stdbool.h>
+#include <time.h>
+
+#define PLATFORM_SCR_WIDTH 600
+#define PLATFORM_SCR_HEIGHT 600
+
+#define PLATFORM_SECOND 1000.0f
+#define PLATFORM_FPS 60
+#define PLATFORM_MS_PER_FRAME (PLATFORM_SECOND / PLATFORM_FPS)
+#define PLATFORM_UPDATES_PER_SECOND 120
+#define PLATFORM_MS_PER_UPDATE (PLATFORM_SECOND / PLATFORM_UPDATES_PER_SECOND)
+
+PLATFORM_READ_ENTIRE_FILE(windows_read_entire_file);
+PLATFORM_PRINT(windows_print);
+PLATFORM_MEMORY_FREE(windows_memory_free);
+
+#endif // PLATFORM_WINDOWS_H