finally compiling and running, text still needs rework
This commit is contained in:
		| @@ -49,7 +49,11 @@ add_subdirectory(third-party/libxm SYSTEM) | |||||||
|  |  | ||||||
|  |  | ||||||
| if(LINUX) | if(LINUX) | ||||||
|         set(SYSTEM_SOURCE_FILES src/system/linux/elf.c) |         set(SYSTEM_SOURCE_FILES | ||||||
|  |                 src/system/linux/twn_elf.c | ||||||
|  |                 src/rendering/twn_gl_any_rendering.c | ||||||
|  |                 src/rendering/twn_gl_15_rendering.c | ||||||
|  |                 src/rendering/twn_gl_15_gpu_texture.c) | ||||||
| else() | else() | ||||||
|         set(SYSTEM_SOURCE_FILES) |         set(SYSTEM_SOURCE_FILES) | ||||||
| endif() | endif() | ||||||
| @@ -65,12 +69,17 @@ set(TWN_SOURCE_FILES | |||||||
|         src/twn_context.c include/twn_context.h |         src/twn_context.c include/twn_context.h | ||||||
|         src/twn_audio.c include/twn_audio.h |         src/twn_audio.c include/twn_audio.h | ||||||
|         src/twn_util.c include/twn_util.h |         src/twn_util.c include/twn_util.h | ||||||
|         src/twn_rendering.c include/twn_rendering.h |  | ||||||
|         src/twn_input.c include/twn_input.h |         src/twn_input.c include/twn_input.h | ||||||
|         src/twn_camera.c include/twn_camera.h |         src/twn_camera.c include/twn_camera.h | ||||||
|         src/twn_textures.c include/twn_textures.c |  | ||||||
|         src/twn_game_object.c |         src/twn_game_object.c | ||||||
|  |  | ||||||
|  |         src/twn_textures.c src/twn_textures_c.h | ||||||
|  |         src/rendering/twn_rendering.c src/rendering/twn_rendering_c.h | ||||||
|  |         src/rendering/twn_sprites.c | ||||||
|  |         src/rendering/twn_text.c | ||||||
|  |         src/rendering/twn_triangles.c | ||||||
|  |         src/rendering/twn_circles.c | ||||||
|  |  | ||||||
|         # for dynamic load based solution main is compiled in a separate target |         # for dynamic load based solution main is compiled in a separate target | ||||||
|         $<$<NOT:$<BOOL:${TWN_FEATURE_DYNLIB_GAME}>>:src/twn_main.c> |         $<$<NOT:$<BOOL:${TWN_FEATURE_DYNLIB_GAME}>>:src/twn_main.c> | ||||||
|  |  | ||||||
| @@ -199,7 +208,7 @@ function(include_deps target) | |||||||
|         target_include_directories(${target} SYSTEM PRIVATE ${THIRD_PARTY_INCLUDES}) |         target_include_directories(${target} SYSTEM PRIVATE ${THIRD_PARTY_INCLUDES}) | ||||||
|  |  | ||||||
|         # allow access to headers from any point in source tree |         # allow access to headers from any point in source tree | ||||||
|         target_include_directories(${target} PRIVATE ${TWN_ROOT_DIR}) |         target_include_directories(${target} PRIVATE ${TWN_ROOT_DIR} ${TWN_ROOT_DIR}/include) | ||||||
| endfunction() | endfunction() | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -308,6 +317,7 @@ give_options(${TWN_TARGET}) | |||||||
| include_deps(${TWN_TARGET}) | include_deps(${TWN_TARGET}) | ||||||
| link_deps(${TWN_TARGET}) | link_deps(${TWN_TARGET}) | ||||||
| target_link_libraries(${TWN_TARGET} PUBLIC twn_third_parties) | target_link_libraries(${TWN_TARGET} PUBLIC twn_third_parties) | ||||||
|  | target_include_directories(${TWN_TARGET} PRIVATE ${TWN_ROOT_DIR}/src) | ||||||
|  |  | ||||||
| # build the testgame if this cmake list is built directly | # build the testgame if this cmake list is built directly | ||||||
| if(${CMAKE_PROJECT_NAME} MATCHES townengine) | if(${CMAKE_PROJECT_NAME} MATCHES townengine) | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| #include "scenes/scene.h" | #include "scenes/scene.h" | ||||||
| #include "scenes/title.h" | #include "scenes/title.h" | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" | #include "twn_game_api.h" | ||||||
|  |  | ||||||
| #include <SDL_scancode.h> | #include <SDL_scancode.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| @@ -20,9 +20,6 @@ void game_tick(void) { | |||||||
|             state->scene = title_scene(state); |             state->scene = title_scene(state); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         input_add_action(&ctx.input, "debug_dump_atlases"); |  | ||||||
|         input_bind_action_scancode(&ctx.input, "debug_dump_atlases", SDL_SCANCODE_HOME); |  | ||||||
|  |  | ||||||
|         input_add_action(&ctx.input, "debug_toggle"); |         input_add_action(&ctx.input, "debug_toggle"); | ||||||
|         input_bind_action_scancode(&ctx.input, "debug_toggle", SDL_SCANCODE_BACKSPACE); |         input_bind_action_scancode(&ctx.input, "debug_toggle", SDL_SCANCODE_BACKSPACE); | ||||||
|  |  | ||||||
| @@ -53,10 +50,6 @@ void game_tick(void) { | |||||||
|  |  | ||||||
|     struct state *state = ctx.udata; |     struct state *state = ctx.udata; | ||||||
|  |  | ||||||
|     if (input_is_action_just_pressed(&ctx.input, "debug_dump_atlases")) { |  | ||||||
|         textures_dump_atlases(&ctx.texture_cache); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (input_is_action_just_pressed(&ctx.input, "debug_toggle")) { |     if (input_is_action_just_pressed(&ctx.input, "debug_toggle")) { | ||||||
|         ctx.debug = !ctx.debug; |         ctx.debug = !ctx.debug; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "player.h" | #include "player.h" | ||||||
| #include "world.h" | #include "world.h" | ||||||
| #include "townengine/game_api.h" |  | ||||||
|  | #include "twn_game_api.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #ifndef PLAYER_H | #ifndef PLAYER_H | ||||||
| #define PLAYER_H | #define PLAYER_H | ||||||
|  |  | ||||||
|  | #include "twn_game_api.h" | ||||||
| #include "townengine/game_api.h" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| struct world; | struct world; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| #include "title.h" | #include "title.h" | ||||||
| #include "scene.h" | #include "scene.h" | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" | #include "twn_game_api.h" | ||||||
|  |  | ||||||
| #define STB_PERLIN_IMPLEMENTATION | #define STB_PERLIN_IMPLEMENTATION | ||||||
| #include <stb_perlin.h> | #include <stb_perlin.h> | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #ifndef INGAME_H | #ifndef INGAME_H | ||||||
| #define INGAME_H | #define INGAME_H | ||||||
|  |  | ||||||
|  | #include "twn_game_api.h" | ||||||
| #include "townengine/game_api.h" |  | ||||||
|  |  | ||||||
| #include "../state.h" | #include "../state.h" | ||||||
| #include "scene.h" | #include "scene.h" | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| #include "../world.h" | #include "../world.h" | ||||||
| #include "../player.h" | #include "../player.h" | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" | #include "twn_game_api.h" | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| #ifndef TITLE_H | #ifndef TITLE_H | ||||||
| #define TITLE_H | #define TITLE_H | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" |  | ||||||
| #include "../state.h" | #include "../state.h" | ||||||
| #include "scene.h" | #include "scene.h" | ||||||
| #include "../player.h" | #include "../player.h" | ||||||
|   | |||||||
| @@ -2,8 +2,9 @@ | |||||||
| #define STATE_H | #define STATE_H | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" | #include "twn_game_api.h" | ||||||
|  |  | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
| struct state { | struct state { | ||||||
|     t_ctx *ctx; |     t_ctx *ctx; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "townengine/game_api.h" | #include "twn_game_api.h" | ||||||
|  |  | ||||||
| #include "world.h" | #include "world.h" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| #ifndef WORLD_H | #ifndef WORLD_H | ||||||
| #define WORLD_H | #define WORLD_H | ||||||
|  |  | ||||||
| #include "townengine/game_api.h" |  | ||||||
|  |  | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,6 +33,8 @@ typedef struct context { | |||||||
|     bool initialization_needed; |     bool initialization_needed; | ||||||
| } t_ctx; | } t_ctx; | ||||||
|  |  | ||||||
|  | #ifndef TWN_ENGINE_CONTEXT_C_H | ||||||
| TWN_API extern t_ctx ctx; | TWN_API extern t_ctx ctx; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| #ifndef TWN_OPTION_H | #ifndef TWN_OPTION_H | ||||||
| #define TWN_OPTION_H | #define TWN_OPTION_H | ||||||
| 
 | 
 | ||||||
| #include "twn_concatenate_c.h" | #include "twn_concatenate.h" | ||||||
| #include "twn_varargcount_c.h" | #include "twn_varargcount.h" | ||||||
| 
 | 
 | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| @@ -1,9 +1,9 @@ | |||||||
| #ifndef TWN_RENDERING_H | #ifndef TWN_RENDERING_H | ||||||
| #define TWN_RENDERING_H | #define TWN_RENDERING_H | ||||||
|  |  | ||||||
| #include "util.h" | #include "twn_util.h" | ||||||
| #include "macros/option.h" | #include "twn_option.h" | ||||||
| #include "camera.h" | #include "twn_camera.h" | ||||||
| #include "twn_engine_api.h" | #include "twn_engine_api.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "townengine/twn_game_object.h" | #include "twn_game_object_c.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
|  |  | ||||||
| #include <x-watcher.h> | #include <x-watcher.h> | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| @@ -56,7 +56,7 @@ static void load_game_object(void) { | |||||||
|  |  | ||||||
|     handle = new_handle; |     handle = new_handle; | ||||||
|  |  | ||||||
|     if (ctx.tick_count != 0) |     if (ctx.game.tick_count != 0) | ||||||
|         log_info("Game object was reloaded\n"); |         log_info("Game object was reloaded\n"); | ||||||
|  |  | ||||||
|     return; |     return; | ||||||
| @@ -83,7 +83,7 @@ static void watcher_callback(XWATCHER_FILE_EVENT event, | |||||||
|     switch(event) { |     switch(event) { | ||||||
|         case XWATCHER_FILE_MODIFIED: |         case XWATCHER_FILE_MODIFIED: | ||||||
|             SDL_LockMutex(lock); |             SDL_LockMutex(lock); | ||||||
|             last_tick_modified = ctx.tick_count; |             last_tick_modified = ctx.game.tick_count; | ||||||
|             loaded_after_modification = false; |             loaded_after_modification = false; | ||||||
|             SDL_UnlockMutex(lock); |             SDL_UnlockMutex(lock); | ||||||
|             break; |             break; | ||||||
| @@ -126,7 +126,7 @@ bool game_object_try_reloading(void) { | |||||||
|  |  | ||||||
|     /* only load the modified library after some time, as compilers make a lot of modifications */ |     /* only load the modified library after some time, as compilers make a lot of modifications */ | ||||||
|     SDL_LockMutex(lock); |     SDL_LockMutex(lock); | ||||||
|     if (ctx.tick_count - last_tick_modified > MODIFIED_TICKS_MERGED && |     if (ctx.game.tick_count - last_tick_modified > MODIFIED_TICKS_MERGED && | ||||||
|             !loaded_after_modification) { |             !loaded_after_modification) { | ||||||
|         load_game_object(); |         load_game_object(); | ||||||
|         loaded_after_modification = true; |         loaded_after_modification = true; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
|   | |||||||
| @@ -1,28 +1,68 @@ | |||||||
| static gpu_texture new_gl_texture(void) { | #include "twn_gpu_texture_c.h" | ||||||
|  | #include "twn_util.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps) { | ||||||
|     GLuint texture; |     GLuint texture; | ||||||
|     glGenTextures(1, &texture); |     glGenTextures(1, &texture); | ||||||
|     glBindTexture(GL_TEXTURE_2D, texture); |     glBindTexture(GL_TEXTURE_2D, texture); | ||||||
|  |  | ||||||
|  |     glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLboolean)generate_mipmaps); | ||||||
|  |  | ||||||
|  |     if (filter == TEXTURE_FILTER_NEAREAST) { | ||||||
|         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||||
|         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||||
|  |     } else if (filter == TEXTURE_FILTER_LINEAR) { | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | ||||||
|     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | ||||||
|     glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP,    GL_TRUE); |  | ||||||
|  |  | ||||||
| #if !defined(EMSCRIPTEN) | #if !defined(EMSCRIPTEN) | ||||||
|     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
|     return create_gpu_texture(TEXTURE_FILTER_NEAREST, true); |     return texture; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void delete_gpu_texture(gpu_texture texture) { | ||||||
|  |     glDeleteTextures(1, &texture); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void upload_gpu_texture(gpu_texture texture, void *pixels, int channels, int width, int height) { | ||||||
|  |     glBindTexture(GL_TEXTURE_2D, texture); | ||||||
|  |  | ||||||
|  |     int format_internal, format; | ||||||
|  |     if (channels == 4) { | ||||||
|  |         format_internal = GL_RGBA8; | ||||||
|  |         format = GL_RGBA; | ||||||
|  |     } else if (channels == 1) { | ||||||
|  |         format_internal = GL_ALPHA; | ||||||
|  |         format = GL_ALPHA; | ||||||
|  |     } else { | ||||||
|  |         CRY("upload_gpu_texture", "Unsupported channel count"); | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     glTexImage2D(GL_TEXTURE_2D, |     glTexImage2D(GL_TEXTURE_2D, | ||||||
|                  0, |                  0, | ||||||
|                  GL_RGBA8, |                  format_internal, | ||||||
|                  surface->w, |                  width, | ||||||
|                  surface->h, |                  height, | ||||||
|                  0, |                  0, | ||||||
|                  GL_RGBA, |                  format, | ||||||
|                  GL_UNSIGNED_BYTE, |                  GL_UNSIGNED_BYTE, | ||||||
|                  surface->pixels); |                  pixels); | ||||||
|  |  | ||||||
|  |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void bind_gpu_texture(gpu_texture texture) { | ||||||
|  |     glBindTexture(GL_TEXTURE_2D, texture); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| #include "twn_gl_15_rendering_c.h" |  | ||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
| #include "townengine/config.h" | #include "twn_config.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "twn_text_c.h" | #include "twn_text_c.h" | ||||||
|  |  | ||||||
| #include <glad/glad.h> | #include <glad/glad.h> | ||||||
| @@ -206,6 +205,7 @@ void use_texture_mode(enum texture_mode mode) { | |||||||
|  |  | ||||||
| vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes) { | vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes) { | ||||||
|     glBindBuffer(GL_ARRAY_BUFFER, buffer); |     glBindBuffer(GL_ARRAY_BUFFER, buffer); | ||||||
|  |     glBufferData(GL_ARRAY_BUFFER, bytes, NULL, GL_STREAM_DRAW); | ||||||
|     void *mapping = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); |     void *mapping = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); | ||||||
|     if (!mapping) |     if (!mapping) | ||||||
|         CRY("build_vertex_buffer", "Error mapping a vertex array buffer"); |         CRY("build_vertex_buffer", "Error mapping a vertex array buffer"); | ||||||
| @@ -231,17 +231,19 @@ bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     builder->mapping = (void *)((uintptr_t)builder->mapping + size); | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void finally_render_sprites(const struct primitive_2d primitives[], | void finally_render_sprites(const struct primitive_2d primitives[], | ||||||
|                             const struct sprite_batch batch, |                             const struct sprite_batch batch, | ||||||
|                             const vertex_buffer vertex_buffer) |                             const vertex_buffer buffer) | ||||||
| { | { | ||||||
|     /* TODO: maybe do, dunno */ |     /* TODO: maybe do, dunno */ | ||||||
|     // glBindBuffer(GL_VERTEX_ARRAY, vertex_buffer); |     // glBindBuffer(GL_VERTEX_ARRAY, vertex_buffer); | ||||||
|     (void)vertex_buffer; |     (void)buffer; | ||||||
|  |  | ||||||
|     GLsizei off; |     GLsizei off; | ||||||
|     GLsizei voff; |     GLsizei voff; | ||||||
| @@ -360,13 +362,13 @@ bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, | |||||||
|  |  | ||||||
| void finally_draw_uncolored_space_traingle_batch(const struct mesh_batch *batch, | void finally_draw_uncolored_space_traingle_batch(const struct mesh_batch *batch, | ||||||
|                                                  const t_texture_key texture_key, |                                                  const t_texture_key texture_key, | ||||||
|                                                  const vertex_buffer vertex_buffer) |                                                  const vertex_buffer buffer) | ||||||
| { | { | ||||||
|     const size_t primitives_len = arrlenu(batch->primitives); |     const size_t primitives_len = arrlenu(batch->primitives); | ||||||
|  |  | ||||||
|     textures_bind(&ctx.texture_cache, texture_key); |     textures_bind(&ctx.texture_cache, texture_key); | ||||||
|  |  | ||||||
|     glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); |     glBindBuffer(GL_ARRAY_BUFFER, buffer); | ||||||
|  |  | ||||||
|     /* vertex specification*/ |     /* vertex specification*/ | ||||||
|     glEnableClientState(GL_VERTEX_ARRAY); |     glEnableClientState(GL_VERTEX_ARRAY); | ||||||
| @@ -399,7 +401,9 @@ bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_dat | |||||||
|                                                 stbtt_aligned_quad quad) |                                                 stbtt_aligned_quad quad) | ||||||
| { | { | ||||||
|     (void)font_data; |     (void)font_data; | ||||||
|  |     (void)builder; | ||||||
|  |  | ||||||
|  |     /* TODO: use vertex arrays */ | ||||||
|     glTexCoord2f(quad.s0, quad.t0); |     glTexCoord2f(quad.s0, quad.t0); | ||||||
|     glVertex2f(quad.x0, quad.y0); |     glVertex2f(quad.x0, quad.y0); | ||||||
|     glTexCoord2f(quad.s1, quad.t0); |     glTexCoord2f(quad.s1, quad.t0); | ||||||
| @@ -408,6 +412,8 @@ bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_dat | |||||||
|     glVertex2f(quad.x1, quad.y1); |     glVertex2f(quad.x1, quad.y1); | ||||||
|     glTexCoord2f(quad.s0, quad.t1); |     glTexCoord2f(quad.s0, quad.t1); | ||||||
|     glVertex2f(quad.x0, quad.y1); |     glVertex2f(quad.x0, quad.y1); | ||||||
|  |  | ||||||
|  |     return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -416,6 +422,9 @@ void finally_draw_text(struct font_data const *font_data, | |||||||
|                        t_color color, |                        t_color color, | ||||||
|                        vertex_buffer buffer) |                        vertex_buffer buffer) | ||||||
| { | { | ||||||
|  |     (void)len; | ||||||
|  |     (void)buffer; | ||||||
|  |  | ||||||
|     use_texture_mode(TEXTURE_MODE_GHOSTLY); |     use_texture_mode(TEXTURE_MODE_GHOSTLY); | ||||||
|  |  | ||||||
|     glBindTexture(GL_TEXTURE_2D, font_data->texture); |     glBindTexture(GL_TEXTURE_2D, font_data->texture); | ||||||
|   | |||||||
| @@ -1,65 +0,0 @@ | |||||||
| #ifndef TWN_GL_15_RENDERING_H |  | ||||||
| #define TWN_GL_15_RENDERING_H |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * OpenGL 1.5 and any 2.0+ compatibility version render implementation. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include "twn_rendering_c.h" |  | ||||||
| #include "twn_gl_any_rendering_c.h" |  | ||||||
|  |  | ||||||
| #ifdef EMSCRIPTEN |  | ||||||
| #include <GLES2/gl2.h> |  | ||||||
| #else |  | ||||||
| #include <glad/glad.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <stb_truetype.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void render_circle(const struct circle_primitive *circle); |  | ||||||
|  |  | ||||||
| void render_rectangle(const struct rect_primitive *rectangle); |  | ||||||
|  |  | ||||||
| void use_space_pipeline(void); |  | ||||||
|  |  | ||||||
| void use_2d_pipeline(void); |  | ||||||
|  |  | ||||||
| void use_texture_mode(enum texture_mode mode); |  | ||||||
|  |  | ||||||
| /* uses present in 1.5 buffer mapping feature */ |  | ||||||
| vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes); |  | ||||||
|  |  | ||||||
| /* collects bytes for sending to the gpu until all is pushed, which is when false is returned */ |  | ||||||
| bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, |  | ||||||
|                                    void *bytes, |  | ||||||
|                                    size_t size); |  | ||||||
|  |  | ||||||
| void finally_render_sprites(struct primitive_2d const primitives[], |  | ||||||
|                             struct sprite_batch batch, |  | ||||||
|                             vertex_buffer buffer); |  | ||||||
|  |  | ||||||
| size_t get_sprite_payload_size(struct sprite_batch batch); |  | ||||||
|  |  | ||||||
| bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, |  | ||||||
|                                                   vertex_buffer_builder *builder, |  | ||||||
|                                                   t_fvec2 v0, t_fvec2 v1, t_fvec2 v2, t_fvec2 v3, |  | ||||||
|                                                   t_fvec2 uv0, t_fvec2 uv1, t_fvec2 uv2, t_fvec2 uv3, |  | ||||||
|                                                   t_color color); |  | ||||||
|  |  | ||||||
| void finally_draw_uncolored_space_traingle_batch(struct mesh_batch const *batch, |  | ||||||
|                                                  t_texture_key texture_key, |  | ||||||
|                                                  vertex_buffer buffer); |  | ||||||
|  |  | ||||||
| size_t get_text_payload_size(void); |  | ||||||
|  |  | ||||||
| bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_data, |  | ||||||
|                                                 vertex_buffer_builder *builder, |  | ||||||
|                                                 stbtt_aligned_quad quad); |  | ||||||
|  |  | ||||||
| void finally_draw_text(struct font_data const *font_data, |  | ||||||
|                        size_t len, |  | ||||||
|                        t_color color, |  | ||||||
|                        vertex_buffer buffer); |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| #include "twn_gl_any_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
|  |  | ||||||
| #ifdef EMSCRIPTEN | #ifdef EMSCRIPTEN | ||||||
| #include <GLES2/gl2.h> | #include <GLES2/gl2.h> | ||||||
| @@ -13,7 +13,6 @@ void setup_viewport(int x, int y, int width, int height) { | |||||||
|     glViewport(x, y, width, height); |     glViewport(x, y, width, height); | ||||||
| } | } | ||||||
|  |  | ||||||
| //////// VERTEX BUFFER //////// |  | ||||||
|  |  | ||||||
| vertex_buffer create_vertex_buffer(void) { | vertex_buffer create_vertex_buffer(void) { | ||||||
|     GLuint result; |     GLuint result; | ||||||
| @@ -32,8 +31,6 @@ void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes) { | |||||||
|     glBufferData(GL_ARRAY_BUFFER, bytes, data, GL_STREAM_DRAW); |     glBufferData(GL_ARRAY_BUFFER, bytes, data, GL_STREAM_DRAW); | ||||||
| } | } | ||||||
|  |  | ||||||
| //////// END OF VERTEX BUFFER //////// |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void bind_quad_element_buffer(void) { | void bind_quad_element_buffer(void) { | ||||||
|     static GLuint buffer = 0; |     static GLuint buffer = 0; | ||||||
|   | |||||||
| @@ -1,43 +0,0 @@ | |||||||
| #ifndef TWN_GL_ANY_RENDERING_H |  | ||||||
| #define TWN_GL_ANY_RENDERING_H |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Any OpenGL version base render methods. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifdef EMSCRIPTEN |  | ||||||
| #include <GLES2/gl2.h> |  | ||||||
| #else |  | ||||||
| #include <glad/glad.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <stdbool.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) |  | ||||||
|  |  | ||||||
| typedef GLuint vertex_buffer; |  | ||||||
|  |  | ||||||
| typedef struct vertex_buffer_builder { |  | ||||||
|     size_t bytes_left; |  | ||||||
|     void *mapping; |  | ||||||
| } vertex_buffer_builder; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| vertex_buffer create_vertex_buffer(void); |  | ||||||
|  |  | ||||||
| void delete_vertex_buffer(vertex_buffer buffer); |  | ||||||
|  |  | ||||||
| void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes); |  | ||||||
|  |  | ||||||
| void setup_viewport(int x, int y, int width, int height); |  | ||||||
|  |  | ||||||
| void bind_quad_element_buffer(void); |  | ||||||
|  |  | ||||||
| void clear_draw_buffer(void); |  | ||||||
|  |  | ||||||
| void swap_buffers(void); |  | ||||||
|  |  | ||||||
| void set_depth_range(double low, double high); |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -1,15 +1,8 @@ | |||||||
| #ifndef TWN_GPU_TEXTURE_H | #ifndef TWN_GPU_TEXTURE_C_H | ||||||
| #define TWN_GPU_TEXTURE_H | #define TWN_GPU_TEXTURE_C_H | ||||||
| 
 |  | ||||||
| #ifdef EMSCRIPTEN |  | ||||||
| #include <GLES2/gl2.h> |  | ||||||
| #else |  | ||||||
| #include <glad/glad.h> |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| typedef GLuint gpu_texture; | typedef GLuint gpu_texture; | ||||||
| 
 | 
 | ||||||
| enum texture_filter { | enum texture_filter { | ||||||
| @@ -17,12 +10,11 @@ enum texture_filter { | |||||||
|     TEXTURE_FILTER_LINEAR, |     TEXTURE_FILTER_LINEAR, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps); | gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps); | ||||||
| 
 | 
 | ||||||
| void delete_gpu_texture(gpu_texture texture); | void delete_gpu_texture(gpu_texture texture); | ||||||
| 
 | 
 | ||||||
| void specify_gpu_texture(gpu_texture texture, void *pixels, int channels, int width, int height); | void upload_gpu_texture(gpu_texture texture, void *pixels, int channels, int width, int height); | ||||||
| 
 | 
 | ||||||
| void bind_gpu_texture(gpu_texture texture); | void bind_gpu_texture(gpu_texture texture); | ||||||
| 
 | 
 | ||||||
| @@ -1,10 +1,7 @@ | |||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "townengine/twn_rendering.h" | #include "twn_rendering.h" | ||||||
| #include "townengine/textures/internal_api.h" | #include "twn_engine_context_c.h" | ||||||
| #include "townengine/context.h" | #include "twn_camera.h" | ||||||
| #include "townengine/camera.h" |  | ||||||
|  |  | ||||||
| #include "twn_rendering_platform.h" |  | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <stb_ds.h> | #include <stb_ds.h> | ||||||
| @@ -114,23 +111,23 @@ void render(void) { | |||||||
|     textures_update_atlas(&ctx.texture_cache); |     textures_update_atlas(&ctx.texture_cache); | ||||||
|  |  | ||||||
|     /* fit rendering context onto the resizable screen */ |     /* fit rendering context onto the resizable screen */ | ||||||
|     if (ctx.window_size_has_changed) { |     if (ctx.game.window_size_has_changed) { | ||||||
|         if ((float)ctx.window_w / (float)ctx.window_h > RENDER_BASE_RATIO) { |         if ((float)ctx.game.window_w / (float)ctx.game.window_h > RENDER_BASE_RATIO) { | ||||||
|             float ratio = (float)ctx.window_h / (float)RENDER_BASE_HEIGHT; |             float ratio = (float)ctx.game.window_h / (float)RENDER_BASE_HEIGHT; | ||||||
|             int w = (int)((float)RENDER_BASE_WIDTH * ratio); |             int w = (int)((float)RENDER_BASE_WIDTH * ratio); | ||||||
|             setup_viewport( |             setup_viewport( | ||||||
|                 ctx.window_w / 2 - w / 2, |                 ctx.game.window_w / 2 - w / 2, | ||||||
|                 0, |                 0, | ||||||
|                 w, |                 w, | ||||||
|                 ctx.window_h |                 ctx.game.window_h | ||||||
|             ); |             ); | ||||||
|         } else { |         } else { | ||||||
|             float ratio = (float)ctx.window_w / (float)RENDER_BASE_WIDTH; |             float ratio = (float)ctx.game.window_w / (float)RENDER_BASE_WIDTH; | ||||||
|             int h = (int)((float)RENDER_BASE_HEIGHT * ratio); |             int h = (int)((float)RENDER_BASE_HEIGHT * ratio); | ||||||
|             setup_viewport( |             setup_viewport( | ||||||
|                 0, |                 0, | ||||||
|                 ctx.window_h / 2 - h / 2, |                 ctx.game.window_h / 2 - h / 2, | ||||||
|                 ctx.window_w, |                 ctx.game.window_w, | ||||||
|                 h |                 h | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,17 +1,35 @@ | |||||||
| #ifndef RENDERING_INTERNAL_API_H | #ifndef TWN_RENDERING_C_H | ||||||
| #define RENDERING_INTERNAL_API_H | #define TWN_RENDERING_C_H | ||||||
|  |  | ||||||
| #include "townengine/textures/internal_api.h" | #include "twn_textures_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
| #include "townengine/macros/option.h" | #include "twn_option.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
|  | #include <stb_truetype.h> | ||||||
|  |  | ||||||
|  | #ifdef EMSCRIPTEN | ||||||
|  | #include <GLES2/gl2.h> | ||||||
|  | #else | ||||||
|  | #include <glad/glad.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
| extern t_matrix4 camera_projection_matrix; | extern t_matrix4 camera_projection_matrix; | ||||||
| extern t_matrix4 camera_look_at_matrix; | extern t_matrix4 camera_look_at_matrix; | ||||||
|  |  | ||||||
|  | #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef GLuint vertex_buffer; | ||||||
|  |  | ||||||
|  | typedef struct vertex_buffer_builder { | ||||||
|  |     size_t bytes_left; | ||||||
|  |     void *mapping; | ||||||
|  | } vertex_buffer_builder; | ||||||
|  |  | ||||||
|  |  | ||||||
| struct sprite_primitive { | struct sprite_primitive { | ||||||
|     t_frect rect; |     t_frect rect; | ||||||
|     t_color color; |     t_color color; | ||||||
| @@ -100,22 +118,13 @@ struct text_cache { | |||||||
|     struct font_data **data; |     struct font_data **data; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /* renders the background, then the primitives in all render queues */ | /* renders the background, then the primitives in all render queues */ | ||||||
| void render(void); | void render(void); | ||||||
|  |  | ||||||
| /* clears all render queues */ | /* clears all render queues */ | ||||||
| void render_queue_clear(void); | void render_queue_clear(void); | ||||||
|  |  | ||||||
| void push_circle(t_fvec2 position, float radius, t_color color); |  | ||||||
|  |  | ||||||
| void unfurl_triangle(const char *path, |  | ||||||
|                      t_fvec3 v0, |  | ||||||
|                      t_fvec3 v1, |  | ||||||
|                      t_fvec3 v2, |  | ||||||
|                      t_shvec2 uv0, |  | ||||||
|                      t_shvec2 uv1, |  | ||||||
|                      t_shvec2 uv2); |  | ||||||
|  |  | ||||||
| void create_circle_geometry(t_fvec2 position, | void create_circle_geometry(t_fvec2 position, | ||||||
|                             t_color color, |                             t_color color, | ||||||
|                             float radius, |                             float radius, | ||||||
| @@ -136,10 +145,77 @@ void render_sprites(const struct primitive_2d primitives[], | |||||||
| void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, | void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, | ||||||
|                                          t_texture_key texture_key); |                                          t_texture_key texture_key); | ||||||
|  |  | ||||||
|  | /* text */ | ||||||
|  |  | ||||||
| void render_text(const struct text_primitive *text); | void render_text(const struct text_primitive *text); | ||||||
|  |  | ||||||
| void text_cache_init(struct text_cache *cache); | void text_cache_init(struct text_cache *cache); | ||||||
|  |  | ||||||
| void text_cache_deinit(struct text_cache *cache); | void text_cache_deinit(struct text_cache *cache); | ||||||
|  |  | ||||||
|  | /* vertex buffer */ | ||||||
|  |  | ||||||
|  | vertex_buffer create_vertex_buffer(void); | ||||||
|  |  | ||||||
|  | void delete_vertex_buffer(vertex_buffer buffer); | ||||||
|  |  | ||||||
|  | void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes); | ||||||
|  |  | ||||||
|  | /* uses present in 1.5 buffer mapping feature */ | ||||||
|  | vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes); | ||||||
|  |  | ||||||
|  | /* collects bytes for sending to the gpu until all is pushed, which is when false is returned */ | ||||||
|  | bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, | ||||||
|  |                                    void *bytes, | ||||||
|  |                                    size_t size); | ||||||
|  |  | ||||||
|  | /* state */ | ||||||
|  |  | ||||||
|  | void setup_viewport(int x, int y, int width, int height); | ||||||
|  |  | ||||||
|  | void clear_draw_buffer(void); | ||||||
|  |  | ||||||
|  | void swap_buffers(void); | ||||||
|  |  | ||||||
|  | void set_depth_range(double low, double high); | ||||||
|  |  | ||||||
|  | void bind_quad_element_buffer(void); | ||||||
|  |  | ||||||
|  | void render_circle(const struct circle_primitive *circle); | ||||||
|  |  | ||||||
|  | void render_rectangle(const struct rect_primitive *rectangle); | ||||||
|  |  | ||||||
|  | void use_space_pipeline(void); | ||||||
|  |  | ||||||
|  | void use_2d_pipeline(void); | ||||||
|  |  | ||||||
|  | void use_texture_mode(enum texture_mode mode); | ||||||
|  |  | ||||||
|  | void finally_render_sprites(struct primitive_2d const primitives[], | ||||||
|  |                             struct sprite_batch batch, | ||||||
|  |                             vertex_buffer buffer); | ||||||
|  |  | ||||||
|  | size_t get_sprite_payload_size(struct sprite_batch batch); | ||||||
|  |  | ||||||
|  | bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, | ||||||
|  |                                                   vertex_buffer_builder *builder, | ||||||
|  |                                                   t_fvec2 v0, t_fvec2 v1, t_fvec2 v2, t_fvec2 v3, | ||||||
|  |                                                   t_fvec2 uv0, t_fvec2 uv1, t_fvec2 uv2, t_fvec2 uv3, | ||||||
|  |                                                   t_color color); | ||||||
|  |  | ||||||
|  | void finally_draw_uncolored_space_traingle_batch(struct mesh_batch const *batch, | ||||||
|  |                                                  t_texture_key texture_key, | ||||||
|  |                                                  vertex_buffer buffer); | ||||||
|  |  | ||||||
|  | size_t get_text_payload_size(void); | ||||||
|  |  | ||||||
|  | bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_data, | ||||||
|  |                                                 vertex_buffer_builder *builder, | ||||||
|  |                                                 stbtt_aligned_quad quad); | ||||||
|  |  | ||||||
|  | void finally_draw_text(struct font_data const *font_data, | ||||||
|  |                        size_t len, | ||||||
|  |                        t_color color, | ||||||
|  |                        vertex_buffer buffer); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,10 +0,0 @@ | |||||||
| #ifndef TWN_RENDERING_PLATFORM_H |  | ||||||
| #define TWN_RENDERING_PLATFORM_H |  | ||||||
|  |  | ||||||
| #ifdef EMSCRIPTEN |  | ||||||
| #include "twn_gl_es2_rendering_c.h" |  | ||||||
| #else |  | ||||||
| #include "twn_gl_15_rendering_c.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @@ -1,9 +1,8 @@ | |||||||
| #include "townengine/twn_rendering.h" | #include "twn_rendering.h" | ||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
| #include "townengine/textures/internal_api.h" | #include "twn_textures_c.h" | ||||||
| #include "twn_rendering_platform.h" |  | ||||||
|  |  | ||||||
| #include <stb_ds.h> | #include <stb_ds.h> | ||||||
|  |  | ||||||
| @@ -103,7 +102,7 @@ void render_sprites(const struct primitive_2d primitives[], | |||||||
|     if (vertex_array == 0) |     if (vertex_array == 0) | ||||||
|         vertex_array = create_vertex_buffer(); |         vertex_array = create_vertex_buffer(); | ||||||
|  |  | ||||||
|     use_sprite_blendmode(batch.mode); |     use_texture_mode(batch.mode); | ||||||
|  |  | ||||||
|     const t_frect dims = |     const t_frect dims = | ||||||
|         textures_get_dims(&ctx.texture_cache, primitives->sprite.texture_key); |         textures_get_dims(&ctx.texture_cache, primitives->sprite.texture_key); | ||||||
|   | |||||||
| @@ -1,10 +1,8 @@ | |||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_rendering.h" | ||||||
| #include "townengine/config.h" | #include "twn_util.h" | ||||||
| #include "townengine/context.h" | #include "twn_config.h" | ||||||
| #include "townengine/twn_rendering.h" | #include "twn_engine_context_c.h" | ||||||
|  |  | ||||||
| #include "twn_rendering_platform.h" |  | ||||||
|  |  | ||||||
| #include <stb_truetype.h> | #include <stb_truetype.h> | ||||||
|  |  | ||||||
| @@ -66,7 +64,7 @@ static struct font_data *text_load_font_data(const char *path, int height_px) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     font_data->texture = create_gpu_texture(TEXT_FONT_FILTERING, true); |     font_data->texture = create_gpu_texture(TEXT_FONT_FILTERING, true); | ||||||
|     specify_gpu_texture( |     upload_gpu_texture( | ||||||
|         font_data->texture, |         font_data->texture, | ||||||
|         bitmap, |         bitmap, | ||||||
|         1, |         1, | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
| #include "twn_rendering_platform.h" |  | ||||||
|  |  | ||||||
| #include <stb_truetype.h> | #include <stb_truetype.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| #include "twn_rendering_c.h" | #include "twn_rendering_c.h" | ||||||
| #include "twn_context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "twn_textures_c.h" | #include "twn_textures_c.h" | ||||||
| #include "twn_rendering_platform.h" |  | ||||||
|  |  | ||||||
| #include <stb_ds.h> | #include <stb_ds.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #include "townengine/audio/internal_api.h" | #include "twn_audio_c.h" | ||||||
| #include "townengine/config.h" | #include "twn_config.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <stb_ds.h> | #include <stb_ds.h> | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "twn_camera.h" | #include "twn_camera.h" | ||||||
| #include "twn_context.h" | #include "twn_engine_context_c.h" | ||||||
|  |  | ||||||
| #include <math.h> | #include <math.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
| #include "twn_engine_context_c.h" | #include "twn_engine_context_c.h" | ||||||
|  |  | ||||||
|  | /* internally there's only one context, but it gets type casted to game and engine variants based on which header is included */ | ||||||
|  | /* engine parts should never mix twn_engine_context_c.h with twn_context.h */ | ||||||
| t_engine_ctx ctx = {0}; | t_engine_ctx ctx = {0}; | ||||||
|   | |||||||
| @@ -1,9 +1,10 @@ | |||||||
| #ifndef TWN_ENGINE_CONTEXT_H | #ifndef TWN_ENGINE_CONTEXT_C_H | ||||||
| #define TWN_ENGINE_CONTEXT_H | #define TWN_ENGINE_CONTEXT_C_H | ||||||
|  |  | ||||||
| #include "twn_context.h" | #include "twn_context.h" | ||||||
| #include "textures/internal_api.h" | #include "twn_textures_c.h" | ||||||
| #include "twn_input.h" | #include "twn_input.h" | ||||||
|  | #include "rendering/twn_rendering_c.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
|  |  | ||||||
| @@ -12,7 +13,8 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct engine_context { | typedef struct engine_context { | ||||||
|     t_ctx game_context; |     /* user code facing context */ | ||||||
|  |     t_ctx game; | ||||||
|  |  | ||||||
|     /* the program's actual argc and argv */ |     /* the program's actual argc and argv */ | ||||||
|     int argc; |     int argc; | ||||||
| @@ -45,6 +47,6 @@ typedef struct engine_context { | |||||||
|     bool was_successful; |     bool was_successful; | ||||||
| } t_engine_ctx; | } t_engine_ctx; | ||||||
|  |  | ||||||
| extern t_engine_ctx ctx = ; | extern t_engine_ctx ctx; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #ifndef TWN_GAME_OBJECT_H | #ifndef TWN_GAME_OBJECT_C_H | ||||||
| #define TWN_GAME_OBJECT_H | #define TWN_GAME_OBJECT_C_H | ||||||
|  |  | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| #include "townengine/input/internal_api.h" | #include "twn_input_c.h" | ||||||
| #include "townengine/context.h" | #include "twn_util.h" | ||||||
| #include "townengine/util.h" |  | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <stb_ds.h> | #include <stb_ds.h> | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #ifndef INPUT_INTERNAL_API_H | #ifndef INPUT_INTERNAL_API_H | ||||||
| #define INPUT_INTERNAL_API_H | #define INPUT_INTERNAL_API_H | ||||||
|  |  | ||||||
| #include "townengine/input.h" | #include "twn_input.h" | ||||||
|  |  | ||||||
| void input_reset_state(struct input_state *input); | void input_reset_state(struct input_state *input); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| #include "twn_loop.h" | #include "twn_loop.h" | ||||||
| #include "townengine/context.h" | #include "twn_engine_context_c.h" | ||||||
| #include "townengine/rendering.h" | #include "twn_input_c.h" | ||||||
| #include "townengine/input/internal_api.h" | #include "twn_util.h" | ||||||
| #include "townengine/util.h" | #include "twn_game_object_c.h" | ||||||
| #include "townengine/twn_game_object.h" | #include "twn_audio_c.h" | ||||||
| #include "townengine/audio/internal_api.h" | #include "twn_textures_c.h" | ||||||
| #include "townengine/textures/internal_api.h" | #include "twn_rendering.h" | ||||||
| #include "townengine/rendering/internal_api.h" |  | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <physfs.h> | #include <physfs.h> | ||||||
| @@ -28,12 +27,12 @@ | |||||||
| static void poll_events(void) { | static void poll_events(void) { | ||||||
|     SDL_Event e; |     SDL_Event e; | ||||||
|  |  | ||||||
|     ctx.window_size_has_changed = false; |     ctx.game.window_size_has_changed = false; | ||||||
|  |  | ||||||
|     while (SDL_PollEvent(&e)) { |     while (SDL_PollEvent(&e)) { | ||||||
|         switch (e.type) { |         switch (e.type) { | ||||||
|         case SDL_QUIT: |         case SDL_QUIT: | ||||||
|             ctx.is_running = false; |             ctx.game.is_running = false; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case SDL_WINDOWEVENT: |         case SDL_WINDOWEVENT: | ||||||
| @@ -42,7 +41,7 @@ static void poll_events(void) { | |||||||
|  |  | ||||||
|             switch (e.window.event) { |             switch (e.window.event) { | ||||||
|             case SDL_WINDOWEVENT_SIZE_CHANGED: |             case SDL_WINDOWEVENT_SIZE_CHANGED: | ||||||
|                 ctx.window_size_has_changed = true; |                 ctx.game.window_size_has_changed = true; | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             default: |             default: | ||||||
| @@ -93,7 +92,7 @@ static void main_loop(void) { | |||||||
|     int64_t current_frame_time = SDL_GetPerformanceCounter(); |     int64_t current_frame_time = SDL_GetPerformanceCounter(); | ||||||
|     int64_t delta_time = current_frame_time - ctx.prev_frame_time; |     int64_t delta_time = current_frame_time - ctx.prev_frame_time; | ||||||
|     ctx.prev_frame_time = current_frame_time; |     ctx.prev_frame_time = current_frame_time; | ||||||
|     ctx.delta_time = delta_time; |     ctx.game.delta_time = delta_time; | ||||||
|  |  | ||||||
|     /* handle unexpected timer anomalies (overflow, extra slow frames, etc) */ |     /* handle unexpected timer anomalies (overflow, extra slow frames, etc) */ | ||||||
|     if (delta_time > ctx.desired_frametime * 8) { /* ignore extra-slow frames */ |     if (delta_time > ctx.desired_frametime * 8) { /* ignore extra-slow frames */ | ||||||
| @@ -159,28 +158,28 @@ static void main_loop(void) { | |||||||
|  |  | ||||||
|     /* finally, let's get to work */ |     /* finally, let's get to work */ | ||||||
|     int frames = 0; |     int frames = 0; | ||||||
|     while (ctx.frame_accumulator >= ctx.desired_frametime * ctx.update_multiplicity) { |     while (ctx.frame_accumulator >= ctx.desired_frametime * ctx.game.update_multiplicity) { | ||||||
|         frames += 1; |         frames += 1; | ||||||
|         for (size_t i = 0; i < ctx.update_multiplicity; ++i) { |         for (size_t i = 0; i < ctx.game.update_multiplicity; ++i) { | ||||||
|             /* TODO: disable rendering pushes on not-last ? */ |             /* TODO: disable rendering pushes on not-last ? */ | ||||||
|             render_queue_clear(); |             render_queue_clear(); | ||||||
|  |  | ||||||
|             poll_events(); |             poll_events(); | ||||||
|  |  | ||||||
|             if (ctx.window_size_has_changed) { |             if (ctx.game.window_size_has_changed) { | ||||||
|                 t_vec2 size; |                 t_vec2 size; | ||||||
|                 SDL_GetWindowSize(ctx.window, &size.x, &size.y); |                 SDL_GetWindowSize(ctx.window, &size.x, &size.y); | ||||||
|                 ctx.window_w = size.x; |                 ctx.game.window_w = size.x; | ||||||
|                 ctx.window_h = size.y; |                 ctx.game.window_h = size.y; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             input_state_update(&ctx.input); |             input_state_update(&ctx.game.input); | ||||||
|  |  | ||||||
|             game_object_tick(); |             game_object_tick(); | ||||||
|  |  | ||||||
|             ctx.frame_accumulator -= ctx.desired_frametime; |             ctx.frame_accumulator -= ctx.desired_frametime; | ||||||
|             ctx.tick_count = (ctx.tick_count % ULLONG_MAX) + 1; |             ctx.game.tick_count = (ctx.game.tick_count % ULLONG_MAX) + 1; | ||||||
|             ctx.initialization_needed = false; |             ctx.game.initialization_needed = false; | ||||||
|  |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -202,9 +201,9 @@ static bool initialize(void) { | |||||||
|     /* debug mode _defaults_ to being enabled on debug builds. */ |     /* debug mode _defaults_ to being enabled on debug builds. */ | ||||||
|     /* you should be able to enable it at runtime on any build */ |     /* you should be able to enable it at runtime on any build */ | ||||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||||
|     ctx.debug = true; |     ctx.game.debug = true; | ||||||
| #else | #else | ||||||
|     ctx.debug = false; |     ctx.game.debug = false; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef EMSCRIPTEN | #ifdef EMSCRIPTEN | ||||||
| @@ -215,7 +214,7 @@ static bool initialize(void) { | |||||||
|     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); |     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); | ||||||
|     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5); |     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5); | ||||||
|  |  | ||||||
|     if (ctx.debug) |     if (ctx.game.debug) | ||||||
|         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); |         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); | ||||||
|     else |     else | ||||||
|         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_NO_ERROR); |         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_NO_ERROR); | ||||||
| @@ -279,8 +278,8 @@ static bool initialize(void) { | |||||||
|  |  | ||||||
|     /* TODO: */ |     /* TODO: */ | ||||||
|     // SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h); |     // SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h); | ||||||
|     ctx.window_w = RENDER_BASE_WIDTH; |     ctx.game.window_w = RENDER_BASE_WIDTH; | ||||||
|     ctx.window_h = RENDER_BASE_HEIGHT; |     ctx.game.window_h = RENDER_BASE_HEIGHT; | ||||||
|  |  | ||||||
|     /* audio initialization */ |     /* audio initialization */ | ||||||
|     { |     { | ||||||
| @@ -312,11 +311,11 @@ static bool initialize(void) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|     /* you could change this at runtime if you wanted */ |     /* you could change this at runtime if you wanted */ | ||||||
|     ctx.update_multiplicity = 1; |     ctx.game.update_multiplicity = 1; | ||||||
|  |  | ||||||
| #ifndef EMSCRIPTEN | #ifndef EMSCRIPTEN | ||||||
|     /* hook up opengl debugging callback */ |     /* hook up opengl debugging callback */ | ||||||
|     if (ctx.debug) { |     if (ctx.game.debug) { | ||||||
|         glEnable(GL_DEBUG_OUTPUT); |         glEnable(GL_DEBUG_OUTPUT); | ||||||
|         glDebugMessageCallback(opengl_log, NULL); |         glDebugMessageCallback(opengl_log, NULL); | ||||||
|     } |     } | ||||||
| @@ -325,18 +324,18 @@ static bool initialize(void) { | |||||||
|     /* random seeding */ |     /* random seeding */ | ||||||
|     /* SDL_GetPerformanceCounter returns some platform-dependent number. */ |     /* SDL_GetPerformanceCounter returns some platform-dependent number. */ | ||||||
|     /* it should vary between game instances. i checked! random enough for me. */ |     /* it should vary between game instances. i checked! random enough for me. */ | ||||||
|     ctx.random_seed = SDL_GetPerformanceCounter(); |     ctx.game.random_seed = SDL_GetPerformanceCounter(); | ||||||
|     srand((unsigned int)ctx.random_seed); |     srand((unsigned int)ctx.game.random_seed); | ||||||
|     stbds_rand_seed(ctx.random_seed); |     stbds_rand_seed(ctx.game.random_seed); | ||||||
|  |  | ||||||
|     /* main loop machinery */ |     /* main loop machinery */ | ||||||
|     ctx.is_running = true; |     ctx.game.is_running = true; | ||||||
|     ctx.resync_flag = true; |     ctx.resync_flag = true; | ||||||
|     ctx.clocks_per_second = SDL_GetPerformanceFrequency(); |     ctx.clocks_per_second = SDL_GetPerformanceFrequency(); | ||||||
|     ctx.prev_frame_time = SDL_GetPerformanceCounter(); |     ctx.prev_frame_time = SDL_GetPerformanceCounter(); | ||||||
|     ctx.desired_frametime = ctx.clocks_per_second / TICKS_PER_SECOND; |     ctx.desired_frametime = ctx.clocks_per_second / TICKS_PER_SECOND; | ||||||
|     ctx.frame_accumulator = 0; |     ctx.frame_accumulator = 0; | ||||||
|     ctx.tick_count = 0; |     ctx.game.tick_count = 0; | ||||||
|  |  | ||||||
|     /* delta time averaging */ |     /* delta time averaging */ | ||||||
|     ctx.delta_averager_residual = 0; |     ctx.delta_averager_residual = 0; | ||||||
| @@ -353,7 +352,7 @@ static bool initialize(void) { | |||||||
|     text_cache_init(&ctx.text_cache); |     text_cache_init(&ctx.text_cache); | ||||||
|  |  | ||||||
|     /* input */ |     /* input */ | ||||||
|     input_state_init(&ctx.input); |     input_state_init(&ctx.game.input); | ||||||
|  |  | ||||||
|     /* scripting */ |     /* scripting */ | ||||||
|     /* |     /* | ||||||
| @@ -376,7 +375,7 @@ static void clean_up(void) { | |||||||
|     scripting_deinit(ctx); |     scripting_deinit(ctx); | ||||||
|     */ |     */ | ||||||
|  |  | ||||||
|     input_state_deinit(&ctx.input); |     input_state_deinit(&ctx.game.input); | ||||||
|  |  | ||||||
|     /* if you're gonna remove this, it's also being done in rendering.c */ |     /* if you're gonna remove this, it's also being done in rendering.c */ | ||||||
|     for (size_t i = 0; i < arrlenu(ctx.render_queue_2d); ++i) { |     for (size_t i = 0; i < arrlenu(ctx.render_queue_2d); ++i) { | ||||||
| @@ -395,7 +394,7 @@ static void clean_up(void) { | |||||||
|  |  | ||||||
|  |  | ||||||
| static void reset_state(void) { | static void reset_state(void) { | ||||||
|     input_reset_state(&ctx.input); |     input_reset_state(&ctx.game.input); | ||||||
|     textures_reset_state(); |     textures_reset_state(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -420,11 +419,11 @@ int enter_loop(int argc, char **argv) { | |||||||
|     game_object_load(); |     game_object_load(); | ||||||
|  |  | ||||||
|     ctx.was_successful = true; |     ctx.was_successful = true; | ||||||
|     ctx.initialization_needed = true; |     ctx.game.initialization_needed = true; | ||||||
|  |  | ||||||
|     while (ctx.is_running) { |     while (ctx.game.is_running) { | ||||||
|         if (game_object_try_reloading()) { |         if (game_object_try_reloading()) { | ||||||
|             ctx.initialization_needed = true; |             ctx.game.initialization_needed = true; | ||||||
|             reset_state(); |             reset_state(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| #include "townengine/textures/internal_api.h" | #include "twn_textures_c.h" | ||||||
| #include "townengine/config.h" | #include "twn_config.h" | ||||||
| #include "townengine/util.h" | #include "twn_util.h" | ||||||
| #include "townengine/context.h" |  | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <physfs.h> | #include <physfs.h> | ||||||
| @@ -123,7 +122,7 @@ static void add_new_atlas(struct texture_cache *cache) { | |||||||
| static void upload_texture_from_surface(gpu_texture texture, SDL_Surface *surface) { | static void upload_texture_from_surface(gpu_texture texture, SDL_Surface *surface) { | ||||||
|     SDL_LockSurface(surface); |     SDL_LockSurface(surface); | ||||||
|  |  | ||||||
|     specify_gpu_texture(texture, surface->pixels, surface->w, surface->h); |     upload_gpu_texture(texture, surface->pixels, 4, surface->w, surface->h); | ||||||
|  |  | ||||||
|     SDL_UnlockSurface(surface); |     SDL_UnlockSurface(surface); | ||||||
| } | } | ||||||
| @@ -404,7 +403,7 @@ void textures_update_atlas(struct texture_cache *cache) { | |||||||
| /* EXPERIMANTAL: LIKELY TO BE REMOVED! */ | /* EXPERIMANTAL: LIKELY TO BE REMOVED! */ | ||||||
| #if defined(__linux__) && !defined(HOT_RELOAD_SUPPORT) /* use rodata elf section for fast lookups of repeating textures */ | #if defined(__linux__) && !defined(HOT_RELOAD_SUPPORT) /* use rodata elf section for fast lookups of repeating textures */ | ||||||
|  |  | ||||||
| #include "townengine/system/linux/elf.h" | #include "system/linux/twn_elf.h" | ||||||
|  |  | ||||||
| static const char *rodata_start; | static const char *rodata_start; | ||||||
| static const char *rodata_stop; | static const char *rodata_stop; | ||||||
| @@ -528,8 +527,9 @@ void textures_bind_repeating(const struct texture_cache *cache, t_texture_key ke | |||||||
|  |  | ||||||
|             SDL_LockSurface(texture.data); |             SDL_LockSurface(texture.data); | ||||||
|  |  | ||||||
|             specify_gpu_texture(repeating_texture, |             upload_gpu_texture(repeating_texture, | ||||||
|                                texture.data->pixels, |                                texture.data->pixels, | ||||||
|  |                                4, | ||||||
|                                texture.data->w, |                                texture.data->w, | ||||||
|                                texture.data->h); |                                texture.data->h); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,16 +1,16 @@ | |||||||
| #ifndef TWN_TEXTURES_H | #ifndef TWN_TEXTURES_C_H | ||||||
| #define TWN_TEXTURES_H | #define TWN_TEXTURES_C_H | ||||||
|  |  | ||||||
| #include "twn_util.h" | #include "twn_util.h" | ||||||
| #include "twn_texture_modes.h" | #include "twn_texture_modes.h" | ||||||
| #include "twn_engine_api.h" | #include "rendering/twn_gpu_texture_c.h" | ||||||
| #include "twn_gpu_texture.h" |  | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <stb_rect_pack.h> | #include <stb_rect_pack.h> | ||||||
|  |  | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| struct texture { | struct texture { | ||||||
|     t_frect srcrect;            /* position in atlas */ |     t_frect srcrect;            /* position in atlas */ | ||||||
|     SDL_Surface *data;          /* original image data */ |     SDL_Surface *data;          /* original image data */ | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "twn_util.h" | #include "twn_util.h" | ||||||
| #include "twn_context.h" | #include "twn_engine_context_c.h" | ||||||
|  |  | ||||||
| #include <SDL2/SDL.h> | #include <SDL2/SDL.h> | ||||||
| #include <physfsrwops.h> | #include <physfsrwops.h> | ||||||
| @@ -218,11 +218,11 @@ void tick_timer(int *value) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void tick_ftimer(float *value) { | void tick_ftimer(float *value) { | ||||||
|     *value = MAX(*value - ((float)ctx.delta_time / (float)ctx.clocks_per_second), 0.0f); |     *value = MAX(*value - ((float)ctx.game.delta_time / (float)ctx.clocks_per_second), 0.0f); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool repeat_ftimer(float *value, float at) { | bool repeat_ftimer(float *value, float at) { | ||||||
|     *value -= (float)ctx.delta_time / (float)ctx.clocks_per_second; |     *value -= (float)ctx.game.delta_time / (float)ctx.clocks_per_second; | ||||||
|     if (*value < 0.0f) { |     if (*value < 0.0f) { | ||||||
|         *value += at; |         *value += at; | ||||||
|         return true; |         return true; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user