commit 030149422c5773d463d7dacdaf1a6693ea082f9f
parent 0ee369e1bb7805ef2016beda31cff725ed3b611f
Author: Samdal <samdal@protonmail.com>
Date: Wed, 13 Oct 2021 21:03:44 +0200
dynamic array and tilemap, tilemap work, cleanup
Diffstat:
4 files changed, 436 insertions(+), 208 deletions(-)
diff --git a/.clang_complete b/.clang_complete
@@ -0,0 +1 @@
+-DHS_IMPL
diff --git a/hs_graphics.h b/hs_graphics.h
@@ -1,29 +1,39 @@
#ifndef HS_GRAPHICS_H_
#define HS_GRAPHICS_H_
-#include "external/glad/glad.h"
-#include "external/glfw/glfw3.h"
+#include <assert.h>
+#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
-#include <assert.h>
+#include <stdint.h>
#include <stdio.h>
+#ifdef WIN32
+#define OEMRESOURCE
+#include <windows.h>
+#endif
+
+#include "hs_math.h"
+#include "hs_data.h"
+#include "hs_util.h"
+
+#define STBI_NO_SIMD
+
#ifndef NO_STBI
#define STB_IMAGE_IMPLEMENTATION
#include "external/stb_image.h"
#endif
-#ifdef WIN32
-#define OEMRESOURCE
-#include <windows.h>
-#endif
+#include "external/glad/glad.h"
+#include "external/glfw/glfw3.h"
#ifdef HS_SFD
#include "external/sfd/src/sfd.c"
#endif
-#include "hs_math.h"
-#include "hs_data.h"
+#ifdef HS_NUKLEAR
+#include "hs_nuklear.h"
+#endif
#define hs_key_init(glfw_key) &(hs_key){.key = glfw_key}
@@ -57,7 +67,9 @@ typedef struct {
vec2 pos, tex;
} hs_tex_corner;
-typedef hs_tex_corner hs_tex_square[6];
+typedef struct {
+ hs_tex_corner c[6];
+} hs_tex_square;
typedef struct {
uint32_t width, height, tileset_width, tileset_height;
@@ -67,19 +79,22 @@ typedef struct {
hs_tex_square* vertices;
} hs_tilemap;
+typedef struct {
+ uint32_t tileset_width, tileset_height;
+ float tile_width, tile_height;
+ hs_shader_program sp;
+ hs_tex tex;
+ hs_dynarr vertices;
+} hs_dyn_tilemap;
+
// this is how anders tale rooms are stored
-// --IMPORTANT: LAYERS MUST BE AT LEAST 1 :IMPORTANT--
+// --LAYERS MUST BE AT LEAST 1--
typedef struct {
uint16_t width, height, layers;
uint8_t* data;
} hs_aroom;
typedef struct {
- uint32_t size, position_offset;
- uint8_t* data;
-} hs_byte_buffer;
-
-typedef struct {
uint32_t width, height;
GLFWwindow* window;
} hs_game_data;
@@ -139,59 +154,67 @@ typedef struct {
int previous_state;
} hs_key;
+/* Keys */
+extern enum hs_key_state hs_get_key_toggle(const hs_game_data gd, hs_key* key);
+extern enum hs_key_state hs_get_mouse_toggle(const hs_game_data gd, hs_key* key);
+extern enum hs_key_state hs_get_key_held(const hs_game_data gd, const int key);
+extern enum hs_key_state hs_get_mouse_held(const hs_game_data gd, const int key);
+
+/* MISC */
extern void hs_close(const hs_game_data gd);
+extern float hs_delta();
+extern void hs_sp_use(const hs_shader_program sp);
extern int32_t hs_window_up(const hs_game_data gd);
-extern enum hs_key_state hs_get_key_toggle(const hs_game_data gd, hs_key* key);
-extern enum hs_key_state hs_get_key_held(const hs_game_data gd, const int key);
-extern enum hs_key_state hs_get_mouse_toggle(const hs_game_data gd, hs_key* key);
-extern enum hs_key_state hs_get_mouse_held(const hs_game_data gd, const int key);
extern void hs_clear(const float r, const float g, const float b, const float a, const GLbitfield mask);
-extern void hs_vattrib_enable(const uint32_t index, const uint32_t size,
- const GLenum type, const uint32_t stride, const size_t pointer);
+extern void hs_avg_frametime_print(const float delta, const float interval);
+extern void hs_avg_fps_print(const float delta, const float interval);
+extern void hs_fps_callback_init(const hs_game_data gd, void(*mouse_callback)(GLFWwindow*, double xpos, double ypos));
+
+/* Vertex Buffer */
+extern uint32_t hs_vao_create(const uint32_t count);
+extern uint32_t hs_vbo_create(const float *vbuff, const uint32_t buffsize,
+ const GLenum usage, const uint32_t count);
+extern uint32_t hs_ebo_create(const uint32_t *ibuff, const uint32_t buffsize,
+ const GLenum usage, const uint32_t count);
+extern hs_vobj hs_vobj_create(const float *vbuff, const uint32_t vbuffsize,
+ const uint32_t *ibuff, const uint32_t ibuffsize,
+ const GLenum usage, const uint32_t count);
+extern void hs_vobj_free(hs_vobj vobj);
+extern void hs_vattrib_enable(const uint32_t index, const uint32_t size, const GLenum type,
+ const uint32_t stride, const size_t pointer);
extern void hs_vattrib_enable_float(const uint32_t index, const uint32_t size,
const uint32_t stride, const size_t pointer);
+
+/* Shader program */
+extern hs_shader_program hs_shader_program_create(const uint32_t sp, hs_vobj vobj);
+extern uint32_t hs_shader_create(const char *src, const GLenum shader_type);
+extern uint32_t hs_sp_create(const uint32_t v_shader, const uint32_t f_shader);
+extern void hs_sp_delete(hs_shader_program sp);
+extern uint32_t hs_sp_texture_transform_create();
+extern uint32_t hs_sp_create_from_src(const char *v_src, const char *f_src);
+extern uint32_t hs_sp_create_from_file(const char *v_file, const char *f_file);
+
+/* Uniforms */
extern uint32_t hs_uniform_create(const uint32_t program, const char* name);
-extern hs_coord hs_uniform_coord_create(const uint32_t program,
- const char* model, const char* view, const char* proj);
+extern hs_coord hs_uniform_coord_create(const uint32_t program, const char* model, const char* view, const char* proj);
extern void hs_uniform_mat4_set(const uint32_t u_mat, const mat4 mat);
extern void hs_uniform_sp_mat4_set(const uint32_t program, const uint32_t u_mat, const mat4 mat);
extern void hs_uniform_vec2_set(const uint32_t u_vec, const vec2 vec);
extern void hs_uniform_sp_vec2_set(const uint32_t program, const uint32_t u_vec, const vec2 vec);
-
-// time since previous call of hs_delta
-extern float hs_delta();
-extern void hs_sp_use(const hs_shader_program sp);
-
-extern unsigned char* hs_file_read(const char *file_path);
-extern hs_byte_buffer hs_byte_buffer_from_file(const char* file_path);
-extern hs_aroom hs_aroom_from_file(const char* file_path);
-extern void hs_aroom_write_to_file(const char* file_path, const hs_aroom aroom);
-extern uint32_t hs_shader_create(const char *src, const GLenum shader_type);
-extern uint32_t hs_sp_create(const uint32_t v_shader, const uint32_t f_shader);
-extern uint32_t hs_sp_texture_transform_create();
-extern uint32_t hs_sp_create_from_src(const char *v_src, const char *f_src);
-extern uint32_t hs_sp_create_from_file(const char *v_file, const char *f_file);
-extern uint32_t hs_fbo_color_create(const uint32_t width, const uint32_t height, uint32_t* tex);
-extern void hs_fbo_draw_to_screen(const uint32_t fbo, const uint32_t src_w, const uint32_t src_h,
- const uint32_t dst_x, const uint32_t dst_y, const uint32_t dst_w, const uint32_t dst_h);
-extern void hs_sp_delete(hs_shader_program sp);
-extern void hs_avg_frametime_print(const float delta, const float interval);
-extern void hs_avg_fps_print(const float delta, const float interval);
-extern hs_shader_program hs_shader_program_create(const uint32_t sp, hs_vobj vobj);
-
extern void hs_tex_uniform_set(const hs_tex tex, const uint32_t val);
extern void hs_tex2d_activate(const uint32_t texture_object, const GLenum texindex);
#ifndef NO_STBI
-extern uint32_t hs_tex2d_create(const char *filename, const GLenum format,
- const GLenum wrap, const GLenum filter);
+extern uint32_t hs_tex2d_create(const char *filename, const GLenum format, const GLenum wrap, const GLenum filter);
extern uint32_t hs_tex2d_create_pixel(const char *filename, const GLenum format);
-extern uint32_t hs_tex2d_create_size_info_pixel(const char *filename, const GLenum format,
- int* width, int* height);
-extern uint32_t hs_tex2d_create_size_info(const char *filename, const GLenum format,
- const GLenum wrap, const GLenum filter,
- int* width, int* height);
+extern uint32_t hs_tex2d_create_size_info(const char *filename, const GLenum format, const GLenum wrap, const GLenum filter, int* width, int* height);
+extern uint32_t hs_tex2d_create_size_info_pixel(const char *filename, const GLenum format, int* width, int* height);
#endif
+/* FBO */
+extern uint32_t hs_fbo_color_create(const uint32_t width, const uint32_t height, uint32_t* tex);
+extern void hs_fbo_draw_to_screen(const uint32_t fbo, const uint32_t src_w, const uint32_t src_h,
+ const uint32_t dst_x, const uint32_t dst_y, const uint32_t dst_w, const uint32_t dst_h);
+
/* hs_aabb2 */
extern vec2 hs_aabb2_center(const hs_aabb2 rect);
extern vec2 hs_aabb2_size(const hs_aabb2 rect);
@@ -209,24 +232,29 @@ extern uint32_t hs_rect2_is_inside(const hs_rect2 r1, const hs_rect2 r2, float*
extern void hs_entity2_force_inside_rects(hs_rect2* e, hs_rect2* rects, const uint32_t rectc);
extern void hs_entity2_collide(hs_rect2* r1, const hs_rect2* r2);
-/* Camera stuff */
+/* Camera */
extern hs_camera hs_init_fps_camera();
-extern void hs_camera_move_front(hs_camera* camera, const float scale);
-extern void hs_camera_move_right(hs_camera* camera, const float scale);
-extern void hs_camera_move_frontv(const hs_camera camera, vec3* new_pos);
-extern void hs_camera_move_backv(const hs_camera camera, vec3* new_pos);
-extern void hs_camera_move_rightv(const hs_camera camera, vec3* new_pos);
-extern void hs_camera_move_leftv(const hs_camera camera, vec3* new_pos);
-extern void hs_camera_look_at(mat4 view, const hs_camera camera);
-extern vec2 hs_pos_to_offset(const float xpos, const float ypos, const float sens);
-extern void hs_camera_update_front(hs_camera* camera);
+extern void hs_camera_move_front(hs_camera* camera, const float scale);
+extern void hs_camera_move_right(hs_camera* camera, const float scale);
+extern void hs_camera_move_frontv(const hs_camera camera, vec3* new_pos);
+extern void hs_camera_move_backv(const hs_camera camera, vec3* new_pos);
+extern void hs_camera_move_rightv(const hs_camera camera, vec3* new_pos);
+extern void hs_camera_move_leftv(const hs_camera camera, vec3* new_pos);
+extern void hs_camera_look_at(mat4 view, const hs_camera camera);
+extern vec2 hs_pos_to_offset(const float xpos, const float ypos, const float sens);
+extern void hs_camera_update_front(hs_camera* camera);
#define HS_CAMERA2_SMOOTH_DEFAULT {.zoom = 1.0f}
extern void hs_camera2_smooth_view(mat4 view, const hs_camera2_smooth cam);
extern void hs_camera2_smooth_move_to_goal(hs_camera2_smooth* cam, const float scale);
extern vec2 hs_px_coord_to_global(const vec2 cam_offset, const vec2 scale, const hs_aabb2 res, const vec2 px);
-/* Tilemap stuff */
+/* Tilemap */
+extern hs_aroom hs_aroom_from_file(const char* file_path);
+extern void hs_aroom_write_to_file(const char* file_path, const hs_aroom aroom);
+extern void hs_tex_square_set_pos(hs_tex_square* square, const hs_aabb2 pos);
+extern void hs_tex_square_set_tex(hs_tex_square* square, hs_aabb2 tex);
+
extern void hs_tilemap_set(hs_tilemap* tilemap, const uint32_t vertex, uint32_t tile);
extern void hs_tilemap_setall(hs_tilemap* tilemap, const uint32_t tile);
extern void hs_tilemap_set_xy(hs_tilemap* tilemap, const uint32_t x, const uint32_t y, uint32_t tile);
@@ -242,30 +270,23 @@ extern void hs_aroom_set_tilemap(const hs_aroom aroom, hs_tilemap* tilemap,
extern void hs_aroom_set_tilemap_offsetv(const hs_aroom aroom, hs_tilemap* tilemap, const uint16_t layer, const vec2i offset);
extern vec2 hs_tilemap_pos_to_global(const hs_tilemap tilemap, vec2i pos);
-/* Sprite stuff */
+extern uint32_t hs_dyn_tilemap_sizeof(const hs_dyn_tilemap tilemap);
+extern void hs_dyn_tilemap_init(hs_dyn_tilemap* tilemap, size_t size);
+extern void hs_dyn_tilemap_clear(hs_dyn_tilemap* tilemap);
+extern void hs_dyn_tilemap_free(hs_dyn_tilemap* tilemap);
+extern void hs_dyn_tilemap_push(hs_dyn_tilemap* tilemap, const vec2i pos, uint32_t tile);
+extern void hs_aroom_push_dyn_tilemap(const hs_aroom aroom, hs_dyn_tilemap* tilemap, const uint16_t layer, const vec2i offset);
+extern void hs_dyn_tilemap_update_vbo(const hs_dyn_tilemap tilemap);
+extern void hs_dyn_tilemap_draw(const hs_dyn_tilemap tilemap);
+extern vec2 hs_dyn_tilemap_pos_to_global(const hs_dyn_tilemap tilemap, vec2i pos);
+
+/* Entity */
extern hs_shader_program hs_sp_sprite_create(const float width, const float height, const float screen_size);
-extern void hs_sprite_draw_current();
+extern void hs_sprite_draw_current();
extern hs_entity2 hs_entity2_create(hs_entity2_hot* hot, hs_shader_program sp, hs_tex tex);
-extern uint32_t hs_vao_create(const uint32_t count);
-extern uint32_t hs_vbo_create(const float *vbuff, const uint32_t buffsize,
- const GLenum usage, const uint32_t count);
-extern uint32_t hs_ebo_create(const uint32_t *ibuff, const uint32_t buffsize,
- const GLenum usage, const uint32_t count);
-extern hs_vobj hs_vobj_create(const float *vbuff, const uint32_t vbuffsize,
- const uint32_t *ibuff, const uint32_t ibuffsize,
- const GLenum usage, const uint32_t count);
-// Expects vobj to be heap allocated
-extern void hs_vobj_free(hs_vobj vobj);
-extern void hs_fps_callback_init(const hs_game_data gd, void(*mouse_callback)(GLFWwindow*, double xpos, double ypos));
-
-#ifdef HS_NUKLEAR
-#include "hs_nuklear.h"
-#endif
-
#ifdef HS_IMPL
-
static uint32_t hs_default_missing_tex = 0;
#define GLAD_IMPL
@@ -423,57 +444,6 @@ hs_sp_use(const hs_shader_program sp)
if (sp.vobj.ebo) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sp.vobj.ebo);
}
-unsigned char*
-hs_file_read(const char *file_path)
-{
- FILE *file = fopen(file_path, "r");
- if (!file) {
- fprintf(stderr, "---error reading file \"%s\"---\n", file_path);
- assert(file);
- }
-
- fseek(file, 0L, SEEK_END);
- uint32_t readsize = ftell(file);
- rewind(file);
-
- unsigned char* buffer = malloc(readsize);
- assert(buffer);
-
- fread(buffer, 1, readsize, file);
- buffer[readsize] = '\0';
-
- fclose(file);
- return buffer;
-}
-
-inline hs_byte_buffer
-hs_byte_buffer_from_file(const char* file_path)
-{
- /* same as hs_file_read, just need the "readsize" information */
- FILE *file = fopen(file_path, "r");
- if (!file) {
- fprintf(stderr, "---error reading file \"%s\"---\n", file_path);
- assert(file);
- }
-
- fseek(file, 0L, SEEK_END);
- uint32_t readsize = ftell(file);
- rewind(file);
-
- unsigned char* buffer = malloc(readsize);
- assert(buffer);
-
- fread(buffer, 1, readsize, file);
- buffer[readsize] = '\0';
-
- fclose(file);
-
- return (hs_byte_buffer){
- .size = readsize,
- .data = buffer,
- };
-}
-
hs_aroom
hs_aroom_from_file(const char* file_path)
{
@@ -578,8 +548,8 @@ hs_sp_create_from_src(const char *v_src, const char *f_src)
uint32_t
hs_sp_create_from_file(const char *v_file, const char *f_file)
{
- unsigned char *v_src = hs_file_read(v_file);
- unsigned char *f_src = hs_file_read(f_file);
+ char* v_src = hs_file_read_null_term(v_file);
+ char* f_src = hs_file_read_null_term(f_file);
uint32_t sp = hs_sp_create_from_src(v_src, f_src);
@@ -753,7 +723,7 @@ hs_tex2d_create_size_info(const char *filename, const GLenum format,
return tex;
}
-#endif
+#endif // NO_STBI
inline hs_camera
hs_init_fps_camera()
@@ -911,14 +881,13 @@ hs_entity2_collide(hs_rect2* r1, const hs_rect2* r2)
{
const vec2 distance = vec2_add(r1->half_size, r2->half_size);
vec2 diff = vec2_sub(r1->pos, r2->pos);
+
+ if (fabs(diff.x) >= distance.x || fabs(diff.y) >= distance.y) return;
+
if (diff.x == 0) diff.x = random_float_negative() * 0.00000001;
if (diff.y == 0) diff.y = random_float_negative() * 0.00000001;
-
const vec2 diffabs = {fabs(diff.x), fabs(diff.y)};
- if (diffabs.x >= distance.x || diffabs.y >= distance.y) return;
-
-
const float extra = 1.0001;
if (diffabs.x > diffabs.y) {
@@ -1034,48 +1003,82 @@ hs_camera2_smooth_view(mat4 view, const hs_camera2_smooth cam)
mat4_translate(view, (vec3){-cam.curr.x, -cam.curr.y, 0.0f});
}
-void
-hs_tilemap_set(hs_tilemap* tilemap, const uint32_t vertex, uint32_t tile)
+inline void
+hs_tex_square_set_pos(hs_tex_square* square, const hs_aabb2 pos)
{
- // make tiles start at 0 instead of 1
- tile++;
+ // triangle one
+ square->c[0].pos.x = pos.bl.x;
+ square->c[0].pos.y = pos.bl.y;
- float width = 1.0f/tilemap->tileset_width;
- float height = 1.0f/tilemap->tileset_height;
- float xpos = width * (tile % tilemap->tileset_width);
- if (xpos == 0.0f) xpos = 1.0f;
- float ypos = height * ceilf((float)tile / (float)tilemap->tileset_width);
+ square->c[1].pos.x = pos.tr.x;
+ square->c[1].pos.y = pos.bl.y;
+ square->c[2].pos.x = pos.tr.x;
+ square->c[2].pos.y = pos.tr.y;
+
+ // triangle two
+ square->c[3].pos.x = pos.tr.x;
+ square->c[3].pos.y = pos.tr.y;
+
+ square->c[4].pos.x = pos.bl.x;
+ square->c[4].pos.y = pos.tr.y;
+
+ square->c[5].pos.x = pos.bl.x;
+ square->c[5].pos.y = pos.bl.y;
+}
+
+void
+hs_tex_square_set_tex(hs_tex_square* square, hs_aabb2 tex)
+{
// crop it slightly, this makes the tiles next to the selected tile not accidentaly appear
- xpos -= 0.001f;
- ypos -= 0.001f;
- width -= 0.001f;
- height -= 0.001f;
+ tex.bl.x += 0.001f;
+ tex.bl.y += 0.001f;
+ tex.bl.x -= 0.001f;
+ tex.tr.y -= 0.001f;
// bottom left
- tilemap->vertices[vertex][0].tex.x = xpos - width;
- tilemap->vertices[vertex][0].tex.y = ypos - height;
+ square->c[0].tex.x = tex.bl.x;
+ square->c[0].tex.y = tex.bl.y;
// bottom right
- tilemap->vertices[vertex][1].tex.x = xpos;
- tilemap->vertices[vertex][1].tex.y = ypos - height;
+ square->c[1].tex.x = tex.tr.x;
+ square->c[1].tex.y = tex.bl.y;
// top right
- tilemap->vertices[vertex][2].tex.x = xpos;
- tilemap->vertices[vertex][2].tex.y = ypos;
+ square->c[2].tex.x = tex.tr.x;
+ square->c[2].tex.y = tex.tr.y;
// top right
- tilemap->vertices[vertex][3].tex.x = xpos;
- tilemap->vertices[vertex][3].tex.y = ypos;
+ square->c[3].tex.x = tex.tr.x;
+ square->c[3].tex.y = tex.tr.y;
// top left
- tilemap->vertices[vertex][4].tex.x = xpos - width;
- tilemap->vertices[vertex][4].tex.y = ypos;
+ square->c[4].tex.x = tex.bl.x;
+ square->c[4].tex.y = tex.tr.y;
// bottom left
- tilemap->vertices[vertex][5].tex.x = xpos - width;
- tilemap->vertices[vertex][5].tex.y = ypos - height;
+ square->c[5].tex.x = tex.bl.x;
+ square->c[5].tex.y = tex.bl.y;
+}
+inline void
+hs_tilemap_set(hs_tilemap* tilemap, const uint32_t vertex, uint32_t tile)
+{
+ // make tiles start at 0 instead of 1
+ tile++;
+
+ const float width = 1.0f/tilemap->tileset_width;
+ const float height = 1.0f/tilemap->tileset_height;
+ const float ypos = height * ceilf((float)tile / (float)tilemap->tileset_width);
+ float xpos = width * (tile % tilemap->tileset_width);
+ if (xpos == 0.0f) xpos = 1.0f;
+
+ hs_aabb2 tex = {
+ .bl = (vec2){xpos - width, ypos - height},
+ .tr = (vec2){xpos, ypos},
+ };
+
+ hs_tex_square_set_tex(&tilemap->vertices[vertex], tex);
}
void
@@ -1120,36 +1123,17 @@ hs_tilemap_init(hs_tilemap* tilemap, const uint32_t default_tex)
const float offset_x_default = -(float)tilemap->width * tilemap->tile_width + tilemap->tile_width;
vec2 offset = {offset_x_default, -(float)tilemap->height * tilemap->tile_height + tilemap->tile_height};
uint32_t vertex = 0;
+ hs_aabb2 square;
for (uint32_t y = 0; y < tilemap->height; y++) {
- const float bottom = offset.y + tilemap->tile_height;
- const float top = offset.y - tilemap->tile_height;
+ square.tr.y = offset.y + tilemap->tile_height;
+ square.bl.y = offset.y - tilemap->tile_height;
for (uint32_t x = 0; x < tilemap->width; x++) {
- const float right = offset.x + tilemap->tile_width;
- const float left = offset.x - tilemap->tile_width;
-
- // triangle one
- tilemap->vertices[vertex][0].pos.x = left;
- tilemap->vertices[vertex][0].pos.y = bottom;
+ square.tr.x = offset.x + tilemap->tile_width;
+ square.bl.x = offset.x - tilemap->tile_width;
- tilemap->vertices[vertex][1].pos.x = right;
- tilemap->vertices[vertex][1].pos.y = bottom;
-
- tilemap->vertices[vertex][2].pos.x = right;
- tilemap->vertices[vertex][2].pos.y = top;
-
- // triangle two
- tilemap->vertices[vertex][3].pos.x = right;
- tilemap->vertices[vertex][3].pos.y = top;
-
- tilemap->vertices[vertex][4].pos.x = left;
- tilemap->vertices[vertex][4].pos.y = top;
-
- tilemap->vertices[vertex][5].pos.x = left;
- tilemap->vertices[vertex][5].pos.y = bottom;
-
- // set texture data
+ hs_tex_square_set_pos(&tilemap->vertices[vertex], square);
hs_tilemap_set(tilemap, vertex, default_tex);
offset.x += tilemap->tile_width * 2.0f;
@@ -1174,7 +1158,6 @@ hs_tilemap_init(hs_tilemap* tilemap, const uint32_t default_tex)
} else {
hs_tilemap_update_vbo(*tilemap);
}
-
}
inline void
@@ -1261,9 +1244,127 @@ hs_aroom_set_tilemap_offsetv(const hs_aroom aroom, hs_tilemap* tilemap, const ui
vec2
hs_tilemap_pos_to_global(const hs_tilemap tilemap, vec2i pos)
{
- assert(tilemap.vertices);
- const uint32_t v = pos.y * tilemap.width + pos.x;
- return vec2_add(tilemap.vertices[v][0].pos, vec2_sub(tilemap.vertices[v][4].pos, tilemap.vertices[v][0].pos));
+ return (vec2) {
+ .x = (float)pos.x * 2.0f * tilemap.tile_width - (float)tilemap.width * tilemap.tile_width,
+ .y = (float)pos.y * 2.0f * tilemap.tile_height - (float)tilemap.height * tilemap.tile_height,
+ };
+}
+
+uint32_t
+hs_dyn_tilemap_sizeof(const hs_dyn_tilemap tilemap)
+{
+ return sizeof(hs_tex_square) * tilemap.vertices.len;
+}
+
+void
+hs_dyn_tilemap_init(hs_dyn_tilemap* tilemap, size_t size)
+{
+ if (tilemap->tile_height <= 0.0f) tilemap->tile_height = 0.1f;
+ if (tilemap->tile_width <= 0.0f) tilemap->tile_width = 0.1f;
+ if (tilemap->tileset_height == 0) tilemap->tileset_height = 1;
+ if (tilemap->tileset_width == 0) tilemap->tileset_width = 1;
+ if (tilemap->tex == 0) tilemap->tex = hs_default_missing_tex;
+ if (size == 0) size = 10000;
+
+ tilemap->vertices = hs_dynarr_init(hs_tex_square, size);
+
+ hs_vobj vobj = hs_vobj_create(castf(tilemap->vertices.data), hs_dyn_tilemap_sizeof(*tilemap), 0, 0, GL_DYNAMIC_DRAW, 1);
+ tilemap->sp = hs_shader_program_create(hs_sp_texture_transform_create(), vobj);
+
+ hs_tex_uniform_set(hs_uniform_create(tilemap->sp.p, "u_tex"), 0);
+ tilemap->sp.coord = hs_uniform_coord_create(tilemap->sp.p, "u_model", "u_view", "u_proj");
+ hs_uniform_mat4_set(tilemap->sp.coord.proj, (mat4)MAT4_IDENTITY);
+
+ hs_vattrib_enable_float(0, 2, 4, 0);
+ hs_vattrib_enable_float(1, 2, 4, 2);
+}
+
+inline void
+hs_dyn_tilemap_clear(hs_dyn_tilemap* tilemap)
+{
+ hs_dynarr_clear(tilemap->vertices);
+}
+
+inline void
+hs_dyn_tilemap_free(hs_dyn_tilemap* tilemap)
+{
+ hs_dynarr_free(tilemap->vertices);
+ hs_sp_delete(tilemap->sp);
+ glDeleteTextures(1, &tilemap->tex);
+}
+
+void
+hs_dyn_tilemap_push(hs_dyn_tilemap* tilemap, const vec2i pos, uint32_t tile)
+{
+ hs_tex_square new_tile;
+
+ // make tiles start at 0 instead of 1
+ tile++;
+
+ const float width = 1.0f/tilemap->tileset_width;
+ const float height = 1.0f/tilemap->tileset_height;
+ const float ypos = height * ceilf((float)tile / (float)tilemap->tileset_width);
+ float xpos = width * (tile % tilemap->tileset_width);
+ if (xpos == 0.0f) xpos = 1.0f;
+
+ hs_aabb2 tex = {
+ .bl = (vec2){xpos - width, ypos - height},
+ .tr = (vec2){xpos, ypos},
+ };
+ hs_tex_square_set_tex(&new_tile, tex);
+
+ vec2 offset = hs_dyn_tilemap_pos_to_global(*tilemap, pos);
+ hs_aabb2 square_pos;
+ square_pos.bl.x = offset.x - tilemap->tile_width;
+ square_pos.bl.y = offset.y - tilemap->tile_height;
+ square_pos.tr.x = offset.x + tilemap->tile_width;
+ square_pos.tr.y = offset.y + tilemap->tile_height;
+ hs_tex_square_set_pos(&new_tile, square_pos);
+
+ hs_dynarr_push(tilemap->vertices, hs_tex_square, new_tile);
+}
+
+void
+hs_dyn_tilemap_update_vbo(const hs_dyn_tilemap tilemap)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, tilemap.sp.vobj.vbo);
+ glBufferData(GL_ARRAY_BUFFER, hs_dyn_tilemap_sizeof(tilemap), castf(tilemap.vertices.data), GL_DYNAMIC_DRAW);
+}
+
+inline void
+hs_dyn_tilemap_draw(const hs_dyn_tilemap tilemap)
+{
+ hs_sp_use(tilemap.sp);
+ glDrawArrays(GL_TRIANGLES, 0, 6 * tilemap.vertices.len);
+}
+
+void
+hs_aroom_push_dyn_tilemap(const hs_aroom aroom, hs_dyn_tilemap* tilemap, const uint16_t layer, const vec2i offset)
+{
+ vec2i pos;
+ if (layer > 1) {
+ const uint32_t layer_offset = (aroom.width * aroom.height * layer) - (aroom.width * aroom.height);
+ uint32_t i = 0;
+ for(uint32_t x = offset.x; x < aroom.width; x++)
+ for(uint32_t y = offset.y; y < aroom.height; y++)
+ hs_dyn_tilemap_push(tilemap, (vec2i){x + offset.x, y + offset.y},
+ aroom.data[layer_offset + i++]);
+ } else {
+ uint32_t i = 0;
+ for(uint32_t x = 0; x < aroom.width; x++)
+ for(uint32_t y = 0; y < aroom.height; y++)
+ hs_dyn_tilemap_push(tilemap, (vec2i){x + offset.x, y + offset.y},
+ aroom.data[i++]);
+ }
+}
+
+vec2
+hs_dyn_tilemap_pos_to_global(const hs_dyn_tilemap tilemap, vec2i pos)
+{
+ return (vec2) {
+ .x = (float)pos.x * 2.0f * tilemap.tile_width,
+ .y = (float)pos.y * 2.0f * tilemap.tile_height,
+ };
}
inline hs_shader_program
@@ -1369,7 +1470,7 @@ enum hs_init_flags {
HS_DEPTH_TESTING = 1 << 3,
};
-inline static hs_game_data
+inline static void
hs_init(hs_game_data* gd, const char *name, void(*framebuffer_size_callback)(GLFWwindow*, int, int), const uint32_t flags)
{
glfwInit();
@@ -1400,21 +1501,16 @@ hs_init(hs_game_data* gd, const char *name, void(*framebuffer_size_callback)(GLF
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, hs_default_missing_tex_data);
glGenerateMipmap(GL_TEXTURE_2D);
}
-#endif
+#endif // NO_STBI
+
+ if (flags & HS_WIREFRAME_MODE) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ if (flags & HS_NO_VSYNC) hs_disable_vsync();
+ if (flags & HS_DEPTH_TESTING) glEnable(GL_DEPTH_TEST);
if (flags & HS_BLEND_MODE) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- if (flags & HS_WIREFRAME_MODE) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- }
- if (flags & HS_NO_VSYNC) {
- hs_disable_vsync();
- }
- if (flags & HS_DEPTH_TESTING) {
- glEnable(GL_DEPTH_TEST);
- }
if (framebuffer_size_callback) {
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
int width, height;
diff --git a/hs_nuklear.h b/hs_nuklear.h
@@ -19,8 +19,11 @@ extern struct nk_image hs_nk_image_load(const char *filename);
extern struct nk_image hs_nk_image_load_size_info(const char *filename, int* width, int* height);
#endif // NO_STBI
-
#ifdef HS_IMPL
+#define HS_NUKLEAR_IMPL
+#endif //HS_IMPL
+
+#ifdef HS_NUKLEAR_IMPL
#ifndef NO_STBI
inline struct nk_image
@@ -36,7 +39,7 @@ hs_nk_image_load_size_info(const char *filename, int* width, int* height)
}
#endif // NO_STBI
-#endif // HS_IMPL
+#endif // HS_NUKLEAR_IMPL
#define HS_NUKLEAR_H_
#endif // HS_NUKLEAR_H_
diff --git a/hs_util.h b/hs_util.h
@@ -0,0 +1,128 @@
+#ifndef HS_UTIL_H_
+#define HS_UTIL_H_
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+typedef struct {
+ size_t cap, len;
+ void* data;
+} hs_dynarr;
+
+#define hs_dynarr_init(_type, _cap) _hs_dynarr_init_sz(sizeof(_type), _cap)
+#define hs_dynarr_zero(_arr, _type) memset(_arr.data, 0, sizeof(_type) * _arr.cap)
+#define hs_dynarr_data(_arr, _type) ((_type*)_arr.data)
+#define hs_dynarr_idx(_arr, _type, _index) hs_dynarr_data(_arr, _type)[_index]
+
+#define hs_dynarr_resize(_arr, _type, _size) _hs_dynarr_resize(&_arr, sizeof(_type), _size)
+#define hs_dynarr_clear(_arr) _arr.len = 0
+#define hs_dynarr_free(_arr) \
+ free(_arr.data); \
+ _arr = (hs_dynarr){0}
+
+#define hs_dynarr_pop(_arr) if(_arr.len > 0) _arr.len--
+#define hs_dynarr_push(_arr, _type, _value) \
+ if (++_arr.len >= _arr.cap) \
+ _hs_dynarr_resize(&_arr, sizeof(_type), _arr.cap * 2); \
+ hs_dynarr_idx(_arr, _type, _arr.len - 1) = _value
+
+#define hs_dynarr_front(_arr, _type) hs_dynarr_idx(_arr, _type, _arr.len - 1)
+#define hs_dynarr_back(_arr, _type) hs_dynarr_idx(_arr, _type, 0)
+
+static inline hs_dynarr
+_hs_dynarr_init_sz(size_t type_size, const size_t capacity)
+{
+ void* data = malloc(type_size * capacity);
+ assert(data);
+
+ return (hs_dynarr){
+ .cap = capacity,
+ .data = data,
+ };
+}
+
+static inline void
+_hs_dynarr_resize(hs_dynarr* dynarr, const size_t type_size, const size_t new_cap)
+{
+ if (new_cap > dynarr->cap) {
+ void* new_data = malloc(type_size * new_cap);
+ assert(new_data);
+
+ memcpy(new_data, dynarr->data, dynarr->cap * type_size);
+ free(dynarr->data);
+ dynarr->data = new_data;
+ }
+ dynarr->cap = new_cap;
+}
+
+extern void hs_memsetv(void* restrict dst, const size_t num, void* restrict src, const size_t sz);
+
+extern char* hs_file_read_null_term(const char *file_path);
+extern uint8_t* hs_file_read(const char *file_path);
+
+#ifdef HS_IMPL
+#define HS_UTIL_IMPL
+#endif // HS_IMPL
+
+#ifdef HS_UTIL_IMPL
+
+void
+hs_memsetv(void* restrict dst, const size_t num, void* restrict src, const size_t sz)
+{
+ const size_t dst_end = (size_t)dst + num * sz;
+ for(; (size_t)dst < dst_end; dst += sz)
+ memcpy(dst, src, sz);
+}
+
+char*
+hs_file_read_null_term(const char *file_path)
+{
+ FILE *file = fopen(file_path, "r");
+ if (!file) {
+ fprintf(stderr, "---error reading file \"%s\"---\n", file_path);
+ assert(file);
+ }
+
+ fseek(file, 0L, SEEK_END);
+ uint32_t readsize = ftell(file);
+ rewind(file);
+
+ char* buffer = malloc(readsize + 1);
+ assert(buffer);
+
+ fread(buffer, 1, readsize, file);
+ buffer[readsize] = '\0';
+
+ fclose(file);
+ return buffer;
+}
+
+uint8_t*
+hs_file_read_(const char *file_path)
+{
+ FILE *file = fopen(file_path, "r");
+ if (!file) {
+ fprintf(stderr, "---error reading file \"%s\"---\n", file_path);
+ assert(file);
+ }
+
+ fseek(file, 0L, SEEK_END);
+ uint32_t readsize = ftell(file);
+ rewind(file);
+
+ uint8_t* buffer = malloc(readsize);
+ assert(buffer);
+
+ fread(buffer, 1, readsize, file);
+
+ fclose(file);
+ return buffer;
+}
+
+#undef HS_UTIL_IMPL
+#endif // HS_UTIL_IMPL
+
+#endif // HS_UTIL_H_