snake

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | LICENSE

commit 7dd39317b814a1c4ecdd3495a08f46b1f367d4b6
parent c3c303252699a1fc422967c8ce1f98a0cafc71bb
Author: Samdal <samdal@protonmail.com>
Date:   Tue,  6 Jul 2021 14:26:21 +0200

organise files, fix a bug

Diffstat:
D.gitignore | 3---
A.gitmodules | 3+++
AREADME.org | 2++
Abin/App | 0
Dmain.c | 295-------------------------------------------------------------------------------
Aproc/html5/emcc.sh | 33+++++++++++++++++++++++++++++++++
Aproc/linux/gcc.sh | 27+++++++++++++++++++++++++++
Aproc/osx/gcc.sh | 39+++++++++++++++++++++++++++++++++++++++
Aproc/win/cl.bat | 35+++++++++++++++++++++++++++++++++++
Aproc/win/mingw.sh | 39+++++++++++++++++++++++++++++++++++++++
Ascreen.png | 0
Rfrag.glsl -> source/frag.glsl | 0
Asource/main.c | 292+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rvertex.glsl -> source/vertex.glsl | 0
Athird_party/include/gs | 1+
15 files changed, 471 insertions(+), 298 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +0,0 @@ -*.exe -*.out -*.o diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "third_party/include/gs"] + path = third_party/include/gs + url = https://github.com/MrFrenik/gunslinger diff --git a/README.org b/README.org @@ -0,0 +1,2 @@ +#+TITLE: gs_snake +[[./screen.png]] diff --git a/bin/App b/bin/App Binary files differ. diff --git a/main.c b/main.c @@ -1,295 +0,0 @@ -#define GS_IMPL -#include <gs/gs.h> - -// Vertex data -float v_data[] = { - -1.0f, -1.0f, 0.0f, 0.0f, // Top Left - 1.0f, -1.0f, 1.0f, 0.0f, // Top Right - -1.0f, 1.0f, 0.0f, 1.0f, // Bottom Left - 1.0f, 1.0f, 1.0f, 1.0f // Bottom Right -}; -// Index data for quad -uint32_t i_data[] = { - 0, 3, 2, // First Triangle - 0, 1, 3 // Second Triangle -}; - -gs_command_buffer_t cb = {0}; -gs_handle(gs_graphics_vertex_buffer_t) vbo = {0}; -gs_handle(gs_graphics_index_buffer_t) ibo = {0}; -gs_handle(gs_graphics_pipeline_t) pip = {0}; -gs_handle(gs_graphics_shader_t) shader = {0}; -gs_handle(gs_graphics_uniform_t) u_resolution = {0}; -gs_handle(gs_graphics_uniform_t) u_food = {0}; -gs_handle(gs_graphics_uniform_t) u_map = {0}; - -char map_names[32][256] = {0}; -uint32_t map_buffer[32] = {0}; - -// snake linked list -typedef struct snake { - gs_vec2 pos; - void* next; -} snake_t; -snake_t* tail = &(snake_t){0}; - -gs_vec2 food = {16.0f, 16.0f}; - -gs_vec2 prev_move = {0}; -gs_vec2 move = {0}; -uint32_t prev_move_time = 0; - -snake_t* eat_food(snake_t* head) -{ - // move food - map_buffer[(int)food.y] |= (1 << (int)food.x); - do { - food = (gs_vec2){rand() % 32, rand() % 32}; - } while (map_buffer[(int)food.y] & (1 << (int)food.x)); - - // Grow snake - head->next = (snake_t*)gs_malloc(sizeof(snake_t)); - gs_assert(head->next); - gs_vec2 pos = head->pos; - head = head->next; - head->pos = pos; - head->next = NULL; - return head; -} - -void free_snake() -{ - while (tail->next) { - snake_t* head = tail; - for (;;) { - snake_t* next = head->next; - if (!next->next) - break; - head = next; - } - gs_free(head->next); - head->next = NULL; - } -} - -void new_game() -{ - // reinitialise buffers - for (uint32_t i = 0; i < 32; i++) - map_buffer[i] = 0; - prev_move_time = gs_platform_elapsed_time() * 0.01f; - move = (gs_vec2){1.0f, 0.0f}; - prev_move = move; - free_snake(); - - // init tail piece - snake_t* body = tail; - body->pos = (gs_vec2){16.0f, 16.0f}; - - // place tail piece in map_buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); - - for (uint32_t i = 1; i <= 3; i++) { - // create snake piece - body->next = (snake_t*)gs_malloc(sizeof(snake_t)); - gs_assert(body->next); - body = body->next; - - // init snake piece - body->pos = (gs_vec2){16.0f + (float)i, 16.0f}; - body->next = NULL; - - // place snake piece in map_buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); - } - - // place food at random position - do { - food = (gs_vec2){rand() % 32, rand() % 32}; - } while (map_buffer[(int)food.y] & (1 << (int)food.x)); -} - -void move_head(snake_t* head) -{ - head->pos.x += move.x; - head->pos.y += move.y; - // wrap snake - if (head->pos.x > 31.0f) - head->pos.x = 0.0f; - else if (head->pos.x < 0.0f) - head->pos.x = 31.0f; - else if (head->pos.y > 31.0f) - head->pos.y = 0.0f; - else if (head->pos.y < 0.0f) - head->pos.y = 31.0f; -} -void move_snake() -{ - - snake_t* body = tail; - prev_move = move; - - // get head - while (body->next) - body = body->next; - - // if new pos is food - if (body->pos.x + move.x == food.x && body->pos.y + move.y == food.y) { - body = eat_food(body); - move_head(body); - } else { - // remove tail from buffer - body = tail; - map_buffer[(int)body->pos.y] &= ~(1 << (int)body->pos.x); - - // move each snake piece to the next ones position - while (body->next) { - snake_t* next = body->next; - body->pos = next->pos; - body = next; - } - - move_head(body); - - // check for collision - if (map_buffer[(int)body->pos.y] & (1 << (int)body->pos.x)) { - new_game(); - return; - } - } - // add head to buffer - map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); -} - -void init() -{ - // Construct new command buffer - cb = gs_command_buffer_new(); - - // Construct vertex buffer - vbo = gs_graphics_vertex_buffer_create(&(gs_graphics_vertex_buffer_desc_t) { - .data = v_data, - .size = sizeof(v_data) - }); - - // Construct index buffer - ibo = gs_graphics_index_buffer_create(&(gs_graphics_index_buffer_desc_t) { - .data = i_data, - .size = sizeof(i_data) - }); - - // shader sources - char* f_src = gs_platform_read_file_contents("frag.glsl", "r", NULL); - char* v_src = gs_platform_read_file_contents("vertex.glsl", "r", NULL); - - // Create shader - shader = gs_graphics_shader_create (&(gs_graphics_shader_desc_t) { - .sources = (gs_graphics_shader_source_desc_t[]){ - {.type = GS_GRAPHICS_SHADER_STAGE_VERTEX, .source = v_src}, - {.type = GS_GRAPHICS_SHADER_STAGE_FRAGMENT, .source = f_src} - }, - .size = 2 * sizeof(gs_graphics_shader_source_desc_t), - .name = "quad" - }); - - // Construct uniforms - - // Construct layout fields for sub elements of array - gs_graphics_uniform_layout_desc_t layout[32] = {0}; - for (uint32_t i = 0; i < 32; ++i) { - gs_snprintf(map_names[i], sizeof(map_names[i]), "[%d]", i); - layout[i].type = GS_GRAPHICS_UNIFORM_INT; - layout[i].fname = map_names[i]; - } - u_map = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { - .name = "u_map", - .layout = layout, - .layout_size = 32 * sizeof(gs_graphics_uniform_layout_desc_t) - }); - u_resolution = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { - .name = "u_resolution", - .layout = &(gs_graphics_uniform_layout_desc_t) { - .type = GS_GRAPHICS_UNIFORM_VEC2 - } - }); - u_food = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { - .name = "u_food", - .layout = &(gs_graphics_uniform_layout_desc_t) { - .type = GS_GRAPHICS_UNIFORM_VEC2 - } - }); - - // init pipeline - pip = gs_graphics_pipeline_create (&(gs_graphics_pipeline_desc_t) { - .raster = { - .shader = shader, - .index_buffer_element_size = sizeof(uint32_t) - }, - .layout = { - .attrs = (gs_graphics_vertex_attribute_desc_t[]){ - {.format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2, .name = "a_pos"}, - {.format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2, .name = "a_uv"} - }, - .size = 2 * sizeof(gs_graphics_vertex_attribute_desc_t) - } - }); - - // set random seed - srand((uint32_t)time(NULL)); - - // start game - new_game(); -} - -void update() -{ - // inputs - if (gs_platform_key_pressed(GS_KEYCODE_ESC)) gs_engine_quit(); - if (gs_platform_key_pressed(GS_KEYCODE_RIGHT) && prev_move.y != 0.0f) move = (gs_vec2){1.0f,0.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_LEFT) && prev_move.y != 0.0f) move = (gs_vec2){-1.0f,0.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_UP) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,1.0f}; - else if (gs_platform_key_pressed(GS_KEYCODE_DOWN) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,-1.0f}; - - // move snake every 0.2 seconds - uint32_t time_now = gs_platform_elapsed_time() * 0.01f; - if (time_now - prev_move_time >= 2) { - move_snake(); - prev_move_time = time_now; - } - - // set uniforms - gs_vec2 fbs = gs_platform_framebuffer_sizev(gs_platform_main_window()); - gs_graphics_bind_uniform_desc_t uniforms[] = { - (gs_graphics_bind_uniform_desc_t) {.uniform = u_map, .data = &map_buffer}, - (gs_graphics_bind_uniform_desc_t) {.uniform = u_resolution, .data = &fbs}, - (gs_graphics_bind_uniform_desc_t) {.uniform = u_food, .data = &food}, - }; - - // Bindings for all buffers: vertex, index, uniforms - gs_graphics_bind_desc_t binds = { - .vertex_buffers = {.desc = &(gs_graphics_bind_vertex_buffer_desc_t){.buffer = vbo}}, - .index_buffers = {.desc = &(gs_graphics_bind_index_buffer_desc_t){.buffer = ibo}}, - .uniforms = {.desc = uniforms, .size = sizeof(uniforms)} - }; - - /* Render */ - gs_graphics_begin_render_pass(&cb, GS_GRAPHICS_RENDER_PASS_DEFAULT); - gs_graphics_set_viewport(&cb, 0, 0, (int32_t)fbs.x, (int32_t)fbs.y); - gs_graphics_bind_pipeline(&cb, pip); - gs_graphics_apply_bindings(&cb, &binds); - gs_graphics_draw(&cb, &(gs_graphics_draw_desc_t){.start = 0, .count = 6}); - gs_graphics_end_render_pass(&cb); - - // Submit command buffer (syncs to GPU, MUST be done on main thread where you have your GPU context created) - gs_graphics_submit_command_buffer(&cb); -} - -gs_app_desc_t gs_main(int32_t argc, char** argv) -{ - return (gs_app_desc_t){ - .window_title = "Gunslinger Snake", - .init = init, - .update = update, - .shutdown = free_snake, - }; -} diff --git a/proc/html5/emcc.sh b/proc/html5/emcc.sh @@ -0,0 +1,33 @@ +#!bin/sh + +rm -rf bin +mkdir bin +cd bin + +proj_name=App +proj_root_dir=$(pwd)/../ + +flags=( + -w -s WASM=1 -s USE_WEBGL2=1 -s ASYNCIFY=1 -O1 +) + +# Include directories +inc=( + -I ../third_party/include/ # Gunslinger includes +) + +# Source files +src=( + ../source/*.c +) + +libs=( +) + +# Build +emcc ${inc[*]} ${src[*]} ${flags[*]} -o $proj_name.html + +cd .. + + + diff --git a/proc/linux/gcc.sh b/proc/linux/gcc.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +rm -rf bin +mkdir bin +cd bin + +proj_name=App +proj_root_dir=$(pwd)/../ + +flags=( + -std=gnu99 -Wl,--no-as-needed -ldl -lGL -lX11 -pthread -lXi +) + +# Include directories +inc=( + -I ../third_party/include/ +) + +# Source files +src=( + ../source/main.c +) + +# Build +gcc -O3 ${inc[*]} ${src[*]} ${flags[*]} -lm -o ${proj_name} + +cd .. diff --git a/proc/osx/gcc.sh b/proc/osx/gcc.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +rm -rf bin +mkdir bin +cd bin + +proj_name=App +proj_root_dir=$(pwd)/../ + +flags=( + -std=c99 -x objective-c -O0 -w +) + +# Include directories +inc=( + -I ../third_party/include/ +) + +# Source files +src=( + ../source/main.c +) + +fworks=( + -framework OpenGL + -framework CoreFoundation + -framework CoreVideo + -framework IOKit + -framework Cocoa + -framework Carbon +) + +# Build +gcc ${flags[*]} ${fworks[*]} ${inc[*]} ${src[*]} -o ${proj_name} + +cd .. + + + diff --git a/proc/win/cl.bat b/proc/win/cl.bat @@ -0,0 +1,35 @@ +@echo off +rmdir /Q /S bin +mkdir bin +pushd bin + +rem Name +set name=App + +rem Include directories +set inc=/I ..\third_party\include\ + +rem Source files +set src_main=..\source\*.c + +rem All source together +set src_all=%src_main% + +rem OS Libraries +set os_libs= opengl32.lib kernel32.lib user32.lib ^ +shell32.lib vcruntime.lib msvcrt.lib gdi32.lib Advapi32.lib + +rem Link options +set l_options=/EHsc /link /SUBSYSTEM:CONSOLE /NODEFAULTLIB:msvcrt.lib + +rem Compile Release +rem cl /MP /FS /Ox /W0 /Fe%name%.exe %src_all% %inc% ^ +rem /EHsc /link /SUBSYSTEM:CONSOLE /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:LIBCMT ^ +rem %os_libs% + +rem Compile Debug +cl /W2 /MP -Zi /DEBUG:FULL /Fe%name%.exe %src_all% %inc% ^ +/EHsc /link /SUBSYSTEM:CONSOLE /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:LIBCMT ^ +%os_libs% + +popd diff --git a/proc/win/mingw.sh b/proc/win/mingw.sh @@ -0,0 +1,39 @@ +#!bin/sh + +rm -rf bin +mkdir bin +cd bin + +proj_name=App +proj_root_dir=$(pwd)/../ + +flags=( + -std=gnu99 -w +) + +# Include directories +inc=( + -I ../third_party/include/ # Gunslinger includes +) + +# Source files +src=( + ../source/main.c +) + +libs=( + -lopengl32 + -lkernel32 + -luser32 + -lshell32 + -lgdi32 + -lAdvapi32 +) + +# Build +gcc -O0 ${inc[*]} ${src[*]} ${flags[*]} ${libs[*]} -lm -o ${proj_name} + +cd .. + + + diff --git a/screen.png b/screen.png Binary files differ. diff --git a/frag.glsl b/source/frag.glsl diff --git a/source/main.c b/source/main.c @@ -0,0 +1,292 @@ +#define GS_IMPL +#include <gs/gs.h> + +// Vertex data +float v_data[] = { + -1.0f, -1.0f, 0.0f, 0.0f, // Top Left + 1.0f, -1.0f, 1.0f, 0.0f, // Top Right + -1.0f, 1.0f, 0.0f, 1.0f, // Bottom Left + 1.0f, 1.0f, 1.0f, 1.0f // Bottom Right +}; +// Index data for quad +uint32_t i_data[] = { + 0, 3, 2, // First Triangle + 0, 1, 3 // Second Triangle +}; + +gs_command_buffer_t cb = {0}; +gs_handle(gs_graphics_vertex_buffer_t) vbo = {0}; +gs_handle(gs_graphics_index_buffer_t) ibo = {0}; +gs_handle(gs_graphics_pipeline_t) pip = {0}; +gs_handle(gs_graphics_shader_t) shader = {0}; +gs_handle(gs_graphics_uniform_t) u_resolution = {0}; +gs_handle(gs_graphics_uniform_t) u_food = {0}; +gs_handle(gs_graphics_uniform_t) u_map = {0}; + +char map_names[32][256] = {0}; +uint32_t map_buffer[32] = {0}; + +// snake linked list +typedef struct snake { + gs_vec2 pos; + void* next; +} snake_t; +snake_t* tail = &(snake_t){0}; + +gs_vec2 food = {16.0f, 16.0f}; + +gs_vec2 prev_move = {0}; +gs_vec2 move = {0}; +uint32_t prev_move_time = 0; + +snake_t* eat_food(snake_t* head) +{ + // move food + map_buffer[(int)food.y] |= (1 << (int)food.x); + do { + food = (gs_vec2){rand() % 32, rand() % 32}; + } while (map_buffer[(int)food.y] & (1 << (int)food.x)); + + // Grow snake + head->next = (snake_t*)gs_malloc(sizeof(snake_t)); + gs_assert(head->next); + gs_vec2 pos = head->pos; + head = head->next; + head->pos = pos; + head->next = NULL; + return head; +} + +void free_snake() +{ + while (tail->next) { + snake_t* head = tail; + for (;;) { + snake_t* next = head->next; + if (!next->next) + break; + head = next; + } + gs_free(head->next); + head->next = NULL; + } +} + +void new_game() +{ + // reinitialise buffers + for (uint32_t i = 0; i < 32; i++) + map_buffer[i] = 0; + prev_move_time = gs_platform_elapsed_time() * 0.01f; + move = (gs_vec2){1.0f, 0.0f}; + prev_move = move; + free_snake(); + + // init tail piece + snake_t* body = tail; + body->pos = (gs_vec2){16.0f, 16.0f}; + + // place tail piece in map_buffer + map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + + for (uint32_t i = 1; i <= 3; i++) { + // create snake piece + body->next = (snake_t*)gs_malloc(sizeof(snake_t)); + gs_assert(body->next); + body = body->next; + + // init snake piece + body->pos = (gs_vec2){16.0f + (float)i, 16.0f}; + body->next = NULL; + + // place snake piece in map_buffer + map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + } + + // place food at random position + do { + food = (gs_vec2){rand() % 32, rand() % 32}; + } while (map_buffer[(int)food.y] & (1 << (int)food.x)); +} + +void move_snake() +{ + prev_move = move; + snake_t* body = tail; + + // get new head pos + while (body->next) + body = body->next; + gs_vec2 new_pos = body->pos; + new_pos.x += move.x; + new_pos.y += move.y; + // wrap snake + if (new_pos.x > 31.0f) + new_pos.x = 0.0f; + else if (new_pos.x < 0.0f) + new_pos.x = 31.0f; + else if (new_pos.y > 31.0f) + new_pos.y = 0.0f; + else if (new_pos.y < 0.0f) + new_pos.y = 31.0f; + + // if new pos is food + if (new_pos.x == food.x && new_pos.y == food.y) { + body = eat_food(body); + body->pos = new_pos; + } else { + // remove tail from buffer + body = tail; + map_buffer[(int)body->pos.y] &= ~(1 << (int)body->pos.x); + + // move each snake piece to the next ones position + while (body->next) { + snake_t* next = body->next; + body->pos = next->pos; + body = next; + } + + body->pos = new_pos; + + // check for collision + if (map_buffer[(int)body->pos.y] & (1 << (int)body->pos.x)) { + new_game(); + return; + } + // add head to buffer + map_buffer[(int)body->pos.y] |= (1 << (int)body->pos.x); + } +} + +void init() +{ + // Construct new command buffer + cb = gs_command_buffer_new(); + + // Construct vertex buffer + vbo = gs_graphics_vertex_buffer_create(&(gs_graphics_vertex_buffer_desc_t) { + .data = v_data, + .size = sizeof(v_data) + }); + + // Construct index buffer + ibo = gs_graphics_index_buffer_create(&(gs_graphics_index_buffer_desc_t) { + .data = i_data, + .size = sizeof(i_data) + }); + + // shader sources + char* f_src = gs_platform_read_file_contents("./source/frag.glsl", "r", NULL); + char* v_src = gs_platform_read_file_contents("./source/vertex.glsl", "r", NULL); + + // Create shader + shader = gs_graphics_shader_create (&(gs_graphics_shader_desc_t) { + .sources = (gs_graphics_shader_source_desc_t[]){ + {.type = GS_GRAPHICS_SHADER_STAGE_VERTEX, .source = v_src}, + {.type = GS_GRAPHICS_SHADER_STAGE_FRAGMENT, .source = f_src} + }, + .size = 2 * sizeof(gs_graphics_shader_source_desc_t), + .name = "quad" + }); + + // Construct uniforms + + // Construct layout fields for sub elements of array + gs_graphics_uniform_layout_desc_t layout[32] = {0}; + for (uint32_t i = 0; i < 32; ++i) { + gs_snprintf(map_names[i], sizeof(map_names[i]), "[%d]", i); + layout[i].type = GS_GRAPHICS_UNIFORM_INT; + layout[i].fname = map_names[i]; + } + u_map = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { + .name = "u_map", + .layout = layout, + .layout_size = 32 * sizeof(gs_graphics_uniform_layout_desc_t) + }); + u_resolution = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { + .name = "u_resolution", + .layout = &(gs_graphics_uniform_layout_desc_t) { + .type = GS_GRAPHICS_UNIFORM_VEC2 + } + }); + u_food = gs_graphics_uniform_create(&(gs_graphics_uniform_desc_t) { + .name = "u_food", + .layout = &(gs_graphics_uniform_layout_desc_t) { + .type = GS_GRAPHICS_UNIFORM_VEC2 + } + }); + + // init pipeline + pip = gs_graphics_pipeline_create (&(gs_graphics_pipeline_desc_t) { + .raster = { + .shader = shader, + .index_buffer_element_size = sizeof(uint32_t) + }, + .layout = { + .attrs = (gs_graphics_vertex_attribute_desc_t[]){ + {.format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2, .name = "a_pos"}, + {.format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2, .name = "a_uv"} + }, + .size = 2 * sizeof(gs_graphics_vertex_attribute_desc_t) + } + }); + + // set random seed + srand((uint32_t)time(NULL)); + + // start game + new_game(); +} + +void update() +{ + // inputs + if (gs_platform_key_pressed(GS_KEYCODE_ESC)) gs_engine_quit(); + if (gs_platform_key_pressed(GS_KEYCODE_RIGHT) && prev_move.y != 0.0f) move = (gs_vec2){1.0f,0.0f}; + else if (gs_platform_key_pressed(GS_KEYCODE_LEFT) && prev_move.y != 0.0f) move = (gs_vec2){-1.0f,0.0f}; + else if (gs_platform_key_pressed(GS_KEYCODE_UP) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,1.0f}; + else if (gs_platform_key_pressed(GS_KEYCODE_DOWN) && prev_move.x != 0.0f) move = (gs_vec2){0.0f,-1.0f}; + + // move snake every 0.2 seconds + uint32_t time_now = gs_platform_elapsed_time() * 0.01f; + if (time_now - prev_move_time >= 2) { + move_snake(); + prev_move_time = time_now; + } + + // set uniforms + gs_vec2 fbs = gs_platform_framebuffer_sizev(gs_platform_main_window()); + gs_graphics_bind_uniform_desc_t uniforms[] = { + (gs_graphics_bind_uniform_desc_t) {.uniform = u_map, .data = &map_buffer}, + (gs_graphics_bind_uniform_desc_t) {.uniform = u_resolution, .data = &fbs}, + (gs_graphics_bind_uniform_desc_t) {.uniform = u_food, .data = &food}, + }; + + // Bindings for all buffers: vertex, index, uniforms + gs_graphics_bind_desc_t binds = { + .vertex_buffers = {.desc = &(gs_graphics_bind_vertex_buffer_desc_t){.buffer = vbo}}, + .index_buffers = {.desc = &(gs_graphics_bind_index_buffer_desc_t){.buffer = ibo}}, + .uniforms = {.desc = uniforms, .size = sizeof(uniforms)} + }; + + /* Render */ + gs_graphics_begin_render_pass(&cb, GS_GRAPHICS_RENDER_PASS_DEFAULT); + gs_graphics_set_viewport(&cb, 0, 0, (int32_t)fbs.x, (int32_t)fbs.y); + gs_graphics_bind_pipeline(&cb, pip); + gs_graphics_apply_bindings(&cb, &binds); + gs_graphics_draw(&cb, &(gs_graphics_draw_desc_t){.start = 0, .count = 6}); + gs_graphics_end_render_pass(&cb); + + // Submit command buffer (syncs to GPU, MUST be done on main thread where you have your GPU context created) + gs_graphics_submit_command_buffer(&cb); +} + +gs_app_desc_t gs_main(int32_t argc, char** argv) +{ + return (gs_app_desc_t){ + .window_title = "Gunslinger Snake", + .init = init, + .update = update, + .shutdown = free_snake, + }; +} diff --git a/vertex.glsl b/source/vertex.glsl diff --git a/third_party/include/gs b/third_party/include/gs @@ -0,0 +1 @@ +Subproject commit 6367f97e5aed0996d647766c9fcc92e7abf46a74