a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit 1c203dfe26f61410ad56d324c21f42e0d85d3994
parent 2f0e582c173fb59b35d0a99c330e0861a8435aa9
Author: amin <dev@aminmesbah.com>
Date:   Mon,  1 Jul 2019 06:26:50 +0000

Provide wasm link time dependencies

FossilOrigin-Name: 74240362b69c5596ae57887bd09bde548b29031a9d8ca3ff981be9a64df37869
Diffstat:
Msrc/am_math.h | 17+++++------------
Msrc/game.c | 10+++++++---
Msrc/game.h | 93+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/platform.h | 4++++
Msrc/platform_linux.c | 6++++++
Msrc/platform_linux.h | 1+
Msrc/platform_wasm.c | 6++++++
Msrc/platform_wasm.h | 1+
Msrc/platform_windows.c | 6++++++
Msrc/platform_windows.h | 1+
Msrc/shader.c | 28++++++++++++++--------------
Msrc/shader.h | 2+-
12 files changed, 108 insertions(+), 67 deletions(-)

diff --git a/src/am_math.h b/src/am_math.h @@ -38,27 +38,20 @@ internal inline f32 math_wrap(f32 n, f32 min, f32 max) } } -internal inline i32 math_floor(f32 x) +// TODO: Test this against floorf +internal inline f32 math_floor(f32 x) { - i32 result = floorf(x); + f32 result = (f32)((i32)x - (x < 0.0f)); return result; } +// TODO: Test this against ceilf internal inline i32 math_ceil(f32 x) { - i32 result = ceilf(x); + i32 result = -math_floor(-x); return result; } -internal inline f32 math_rand(f32 min, f32 max) -{ - assert(min < max); - f32 random = ((f32) rand()) / (f32) RAND_MAX; - f32 diff = max - min; - f32 r = random * diff; - return min + r; -} - internal inline bool math_f32_is_i32(f32 x) { bool result = ((i32)x) == x; diff --git a/src/game.c b/src/game.c @@ -174,9 +174,13 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer) struct PlatformApi platform = game_memory->platform; char *v_source = platform.platform_read_entire_file("shader/main_v.glsl"); char *f_source = platform.platform_read_entire_file("shader/main_f.glsl"); - struct Shader main_shader = shader_compile(v_source, f_source); - free(v_source); - free(f_source); + struct Shader main_shader = {0}; + if (!shader_compile(v_source, f_source, &main_shader)) + { + // TODO: handle error + } + platform.platform_memory_free(v_source); + platform.platform_memory_free(f_source); game_state->renderer.shader = main_shader; } } diff --git a/src/game.h b/src/game.h @@ -1,5 +1,3 @@ -#include <assert.h> - // NOTE(amin): On windows, even with clang and -std=c11, assert.h doesn't // define static_assert. #ifndef static_assert @@ -7,13 +5,68 @@ #endif #include <limits.h> -#include <math.h> #include <stdalign.h> #include <stdbool.h> +#include <stddef.h> #include <stdint.h> + +// TODO: only include this in the non-wasm builds +#include <math.h> + +#ifndef GAME_WEBGL + +#include <assert.h> #include <stdio.h> #include <stdlib.h> +#else +// TODO: organize this stuff + +#define assert(x) (void)0 + +int32_t printf(const char *format, ...) +{ + // lol + return 0; +} + +// looooooooooool +#define exit(status) (void)0 + +void *memset(void *s, int32_t c, size_t n) +{ + uint8_t *p = s; + while(n > 0) + { + *p = (uint8_t)c; + p++; + n--; + } + return s; +} + +// TODO: assert no overlap +void *memcpy(void *dst, const void *src, size_t n) +{ + uint8_t *destination = (uint8_t *)dst; + uint8_t *source = (uint8_t *)src; + + while (n--) { + *destination = *source; + destination++; + source++; + } + + return dst; +} + +// TODO: actually implement +void *memmove(void *dst, const void *src, size_t n) +{ + return memcpy(dst, src, n); +} +#endif // GAME_WEBGL + #ifdef GAME_WEBGL #include "webgl.h" #else @@ -80,37 +133,3 @@ struct GameState internal void game_init(struct GameMemory *game_memory, v2u framebuffer); internal void game_cleanup(struct GameMemory *game_memory); - -// TODO: organize this stuff -internal void *memset(void *s, int c, size_t n) -{ - u8 *p = s; - while(n > 0) - { - *p = (u8)c; - p++; - n--; - } - return s; -} - -// TODO: assert no overlap -internal void *memcpy(void *dst, const void *src, size_t n) -{ - u8 *destination = (u8 *)dst; - u8 *source = (u8 *)src; - - while (n--) { - *destination = *source; - destination++; - source++; - } - - return dst; -} - -// TODO: actually implement -internal void *memmove(void *dst, const void *src, size_t n) -{ - return memcpy(dst, src, n); -} diff --git a/src/platform.h b/src/platform.h @@ -8,9 +8,13 @@ #define PLATFORM_READ_ENTIRE_FILE(name) char *(name)(char *file_path) typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file_func); +#define PLATFORM_MEMORY_FREE(name) void (name)(void *ptr) +typedef PLATFORM_MEMORY_FREE(platform_memory_free_func); + struct PlatformApi { platform_read_entire_file_func* platform_read_entire_file; + platform_memory_free_func* platform_memory_free; }; struct GameMemory diff --git a/src/platform_linux.c b/src/platform_linux.c @@ -64,6 +64,7 @@ int main(void) .buffer_size = MEBIBYTES(64), .platform = { &linux_read_entire_file, + &linux_memory_free, }, }; // TODO: replace with mmap @@ -201,6 +202,11 @@ internal time_t file_get_modified_time(char *file_path) return mtime; } +PLATFORM_MEMORY_FREE(linux_memory_free) +{ + free(ptr); +} + internal PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file) { FILE *handle = fopen(file_path, "r"); diff --git a/src/platform_linux.h b/src/platform_linux.h @@ -5,6 +5,7 @@ internal void error_callback(int error, const char* description); internal void framebuffer_size_callback(GLFWwindow* window, int width, int height); internal void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); internal PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file); +PLATFORM_MEMORY_FREE(linux_memory_free); #ifdef PLATFORM_HOTLOAD_GAME_CODE #define PLATFORM_GAME_LIB_PATH "./out/release/game.so" diff --git a/src/platform_wasm.c b/src/platform_wasm.c @@ -37,6 +37,7 @@ bool init(void) .buffer_size = MEBIBYTES(64), .platform = { &wasm_read_entire_file, + &wasm_memory_free, }, .buffer = &__heap_base, }; @@ -63,6 +64,11 @@ void window_resize(int w, int h) glViewport(0, 0, g_width, g_height); } +PLATFORM_MEMORY_FREE(wasm_memory_free) +{ + // do nothing +} + PLATFORM_READ_ENTIRE_FILE(wasm_read_entire_file) { g_mem_buffer_i++; diff --git a/src/platform_wasm.h b/src/platform_wasm.h @@ -2,6 +2,7 @@ #define PLATFORM_SCR_HEIGHT 600 PLATFORM_READ_ENTIRE_FILE(wasm_read_entire_file); +PLATFORM_MEMORY_FREE(wasm_memory_free); // Functions implemented in the JS loader char *js_read_entire_file(i32 file_path, i32 name_len, char *file_data); diff --git a/src/platform_windows.c b/src/platform_windows.c @@ -65,6 +65,7 @@ int main(void) .buffer_size = MEBIBYTES(64), .platform = { &windows_read_entire_file, + &windows_memory_free, }, }; // TODO: replace with VirtualAlloc @@ -165,6 +166,11 @@ internal void key_callback(GLFWwindow *window, int key, int scancode, int action } } +PLATFORM_MEMORY_FREE(windows_memory_free) +{ + free(ptr); +} + internal PLATFORM_READ_ENTIRE_FILE(windows_read_entire_file) { FILE *handle = fopen(file_path, "rb"); diff --git a/src/platform_windows.h b/src/platform_windows.h @@ -5,6 +5,7 @@ internal void error_callback(int error, const char* description); internal void framebuffer_size_callback(GLFWwindow* window, int width, int height); internal void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); internal PLATFORM_READ_ENTIRE_FILE(windows_read_entire_file); +PLATFORM_MEMORY_FREE(windows_memory_free); #ifdef GLAD_DEBUG internal void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...); diff --git a/src/shader.c b/src/shader.c @@ -1,12 +1,14 @@ -internal struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source) +bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader) { + bool compilation_successful = true; GLint success; GLchar info_log[512]; if (!(vertex_shader_source && fragment_shader_source)) { printf("Error: One or more shader source files weren't loaded.\n"); - exit(1); + // TODO: handle errors here in a better way + compilation_successful = false; } else { @@ -19,7 +21,7 @@ internal struct Shader shader_compile(const GLchar *vertex_shader_source, const glGetShaderInfoLog(vertex_shader, 512, NULL, info_log); printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - exit(1); + compilation_successful = false; } GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); @@ -31,28 +33,26 @@ internal struct Shader shader_compile(const GLchar *vertex_shader_source, const glGetShaderInfoLog(fragment_shader, 512, NULL, info_log); printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - exit(1); + compilation_successful = false; } - struct Shader s; - s.program = glCreateProgram(); - glAttachShader(s.program, vertex_shader); - glAttachShader(s.program, fragment_shader); - glLinkProgram(s.program); - glGetProgramiv(s.program, GL_LINK_STATUS, &success); + compiled_shader->program = glCreateProgram(); + glAttachShader(compiled_shader->program, vertex_shader); + glAttachShader(compiled_shader->program, fragment_shader); + glLinkProgram(compiled_shader->program); + glGetProgramiv(compiled_shader->program, GL_LINK_STATUS, &success); if (!success) { - glGetShaderInfoLog(s.program, 512, NULL, info_log); + glGetShaderInfoLog(compiled_shader->program, 512, NULL, info_log); printf("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - exit(1); + compilation_successful = false; } glDeleteShader(fragment_shader); glDeleteShader(vertex_shader); - - return s; } + return compilation_successful; } diff --git a/src/shader.h b/src/shader.h @@ -3,7 +3,7 @@ struct Shader u32 program; }; -internal struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source); +internal bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader); internal void shader_use(struct Shader *s); internal void shader_setb(struct Shader *s, char *name, bool value); internal void shader_seti(struct Shader *s, char *name, int value);