From: Randy McShandy Date: Sun, 19 May 2024 04:39:52 +0000 (-0500) Subject: Add loading screen for heighmap generation process that can smooth transition into... X-Git-Url: http://git.mcshandy.xyz/gitweb.cgi?a=commitdiff_plain;h=eba774acfdbbe5e3be06e9e71d94f97801a5de73;p=barrow_crawler Add loading screen for heighmap generation process that can smooth transition into the actual game, cruft around all that, big rework that needs lots of attention and cleanup --- diff --git a/src/main.c b/src/main.c index d60931d..407d277 100755 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include "structs.h" #include "render.h" @@ -13,24 +14,35 @@ void print_rlog(int logLevel, const char* text, va_list args) int main(int argc, char** argv) { - IVec2 grid_size = {.x = GRID_X * 1.5, .y = GRID_Y * 1.5}; - FVec2 **grid = NULL; - grid = (FVec2**)malloc(grid_size.x * sizeof(FVec2*)); - for (int n = 0; n < grid_size.x; n++) + +/* TODO: Clean this up and integrate into platform system. */ +#define ENABLE_BARROWGEN 1 +#if ENABLE_BARROWGEN + barrow.max_iterations *= 1; + IVec2 grid_size = {.x = GRID_X*1.5, .y = GRID_Y * 1.5}; + GeneratorArgs gargs = + { + .worker_count = 8, + .rd_opts = barrow, + .grid_size = grid_size, + .grid = (FVec2**)malloc(grid_size.x * sizeof(FVec2*)) + }; + + for (int n = 0; n < gargs.grid_size.x; n++) { - grid[n] = (FVec2*)malloc(grid_size.y * sizeof(FVec2)); + gargs.grid[n] = (FVec2*)malloc(gargs.grid_size.y * sizeof(FVec2)); } - barrow.max_iterations *= 1; -#define ENABLE_BARROWGEN 0 -#if ENABLE_BARROWGEN - generate_rd(8, barrow, grid, grid_size); + pthread_t generator_thread; + pthread_create(&generator_thread, NULL, generate_rd, (void*)&gargs); #else resource_generation_finished = 1; #endif /* ENABLE_BARROWGEN */ start_render_loop(); + pthread_join(generator_thread, NULL); + return 0; } diff --git a/src/platforms/platform_posix.c b/src/platforms/platform_posix.c index 72aa4e8..c089fe5 100644 --- a/src/platforms/platform_posix.c +++ b/src/platforms/platform_posix.c @@ -5,7 +5,6 @@ worker_arg warg; int waiting_workers; -int should_quit = 0; extern FVec2 ** grid; extern FVec2 ** grid_prime; @@ -53,10 +52,17 @@ void* iterator(void* _arg) grid = grid_prime; grid_prime = grid_temp; waiting_workers = 0; + resource_generation_progress = ((float)warg->iterations/(float)warg->max_iterations); } + pthread_mutex_unlock(&mutex); - pthread_barrier_wait(&barrier); + if (should_quit == 1) + { + return _arg; + } + + pthread_barrier_wait(&barrier); } // One last synchronization so boss thread doesn't die early @@ -99,6 +105,7 @@ int cleanup() pthread_join(threads[t], NULL); } + /* TODO: Actually this probably shouldn't be freeing resources allocated outside of the unit. */ free(grid); free(grid_prime); free(threads); diff --git a/src/render_raylib.c b/src/render_raylib.c index 58c8d30..01a7db0 100644 --- a/src/render_raylib.c +++ b/src/render_raylib.c @@ -1,5 +1,6 @@ #include #include +#include #define RAYMATH_IMPLEMENTATION #include @@ -58,8 +59,10 @@ Vector3 vec3_up = {0.0f, 1.0f, 0.0f}; Vector3 vec3_down = {0.0f, -1.0f, 0.0f}; typedef void(*renderfunc)(); +typedef void(*controlfunc)(); #define MAX_RENDERFUNCS 2U renderfunc renderfuncs[MAX_RENDERFUNCS]; +controlfunc controlfuncs[MAX_RENDERFUNCS]; /* Render the regular game mode. NOTE: Only call inside a Raylib BeginDrawing() block! @@ -79,6 +82,7 @@ void drawing_game_mode() EndShaderMode(); EndMode3D(); +#define DEBUG_GAME_INFO 1 #if DEBUG_GAME_INFO==1 Rectangle minimap_dest = {.width = 64.0f*img_export_scale.x, .height = 64.0f*img_export_scale.y, .x = 0.0f, .y = 0.0f}; Rectangle minimap_src = {.width = barrow_texture.width, .height = barrow_texture.height, .x = 0.0f, .y = 0.0f}; @@ -86,6 +90,7 @@ void drawing_game_mode() DrawTexturePro(floor_texture, minimap_src, minimap_dest, (Vector2){0.0f, 0.0f}, 0.0f, RAYWHITE); DrawFPS(fscreen_dims.x - 80, 10); DrawText(TextFormat("cam x %f\ncam y %f\ncam z %f", cam.position.x, cam.position.y, cam.position.z), 0, 128, 16, GREEN); + DrawText(TextFormat("tgt x %f\ntgt y %f\ntgt z %f", cam.target.x, cam.target.y, cam.target.z), 0, 128+64, 16, GREEN); DrawText(TextFormat("ray hit %d\nlength %f", player_collision.hit, player_collision.distance), 0, 256, 16, GREEN); #endif /* DEBUG_GAME_INFO */ } @@ -95,33 +100,34 @@ NOTE: Only call inside a Raylib BeginDrawing() block! */ void drawing_resource_wait_mode() { - static int ellipses_counter = 0; + static int status_phase = 0; + const char format_string[] = "%s\n\n%3.2f%%"; const char wait_string[] = "Generating resources..."; const int sector_speed = 2U; const int sector_segments = 16; const float sector_radius = 32.0f; - const Vector2 sector_center = {fscreen_dims.x/2.0f, 3*(fscreen_dims.y/4.0f)}; + const Vector2 sector_center = {fscreen_dims.x/2.0f, 4*(fscreen_dims.y/6.0f)}; - ellipses_counter+=sector_speed; + status_phase+=sector_speed; const int font_size = 32; const int text_width = MeasureText(wait_string, font_size); - ClearBackground(RAYWHITE); - DrawText(wait_string, (fscreen_dims.x/2.0f) - (text_width/2.0f), fscreen_dims.y/2.0f, font_size, BLACK); + ClearBackground(LIGHTGRAY); + DrawText(TextFormat(format_string, wait_string, 100 * resource_generation_progress), + (fscreen_dims.x/2.0f) - (text_width/2.0f), fscreen_dims.y/2.0f, font_size, BLACK); DrawCircleSector(sector_center, sector_radius, - (ellipses_counter % 360), - ((ellipses_counter % 360)*2), + (status_phase % 360), + ((status_phase % 360)*2), sector_segments, RED); DrawCircleSector(sector_center, sector_radius * 0.8f, - (ellipses_counter % 360), - ((ellipses_counter % 360)*2), - sector_segments, RAYWHITE); + (status_phase % 360), + ((status_phase % 360)*2), + sector_segments, LIGHTGRAY); } - -void process_inputs() +void control_game_mode() { Vector3 new_player_velocity = player_velocity; Vector3 new_player_rotation = player_rotation; @@ -156,20 +162,6 @@ void process_inputs() cam.target.y -= DEG2RAD * 20.0; } - if (IsKeyDown(KEY_R)) - { - new_player_velocity.z += 0.005f; - } - else if (IsKeyDown(KEY_F)) - { - new_player_velocity.z -= 0.005f; - } - - if (IsKeyDown(KEY_SPACE) || IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT)) - { - //new_player_velocity.x *= 2.0f; - } - /* Collision test */ /* Cast straight up */ player_collide_ray = (Ray){cam.position, vec3_up}; @@ -193,6 +185,10 @@ void process_inputs() while((key = GetKeyPressed())); } +void control_resource_wait_mode() +{ +} + void wait_initialize_shaders() { shader = LoadShader("./src/shaders/lighting.vs", "./src/shaders/lighting.fs"); @@ -263,9 +259,13 @@ void wait_initialize_resources() coffin_model.materials[0].shader = shader; } - /* Rendering handler setup */ - renderfuncs[0U] = drawing_resource_wait_mode; - renderfuncs[1U] = drawing_game_mode; + /* Mode handler setup */ + { + renderfuncs[0U] = drawing_resource_wait_mode; + renderfuncs[1U] = drawing_game_mode; + controlfuncs[0U] = control_resource_wait_mode; + controlfuncs[1U] = control_game_mode; + } } /* Values that are required to initialize Raylib. */ @@ -287,7 +287,7 @@ void initialize_renderer() cam.position.y -= 0.5f; cam.position.x = barrow_scale.x/2.0f; cam.position.z = (-barrow_scale.z/2.0f) - 4.0f; - cam.target = (Vector3){barrow_scale.x/2.0f, cam.position.y - 10.0f, cam.position.z/2.0f}; + cam.target = (Vector3){barrow_scale.x/2.0f, cam.position.y - 7.0f, cam.position.z/2.0f}; cam.up = (Vector3){0.0f, 1.0f, 0.0f}; cam.fovy = 90.0f; cam.projection = CAMERA_PERSPECTIVE; @@ -308,10 +308,9 @@ void start_render_loop() SetTargetFPS(target_fps); while (!WindowShouldClose()) { - player_collide_point = cam.position; player_collide_point.y -= 1.0f; - process_inputs(); + controlfuncs[resource_generation_finished](); Matrix mat_trans = MatrixTranslate(barrow_position.x, barrow_position.y, barrow_position.z); Matrix mat_rot = MatrixRotate(barrow_rotation_axis, DEG2RAD * barrow_rotation); @@ -332,6 +331,8 @@ void start_render_loop() player_rotation.x = Lerp(player_rotation.x, 0.0f, rotate_speed_decay); } + should_quit = 1; + UnloadImage(barrow_image); UnloadTexture(barrow_texture); UnloadShader(shader); diff --git a/src/structs.c b/src/structs.c index 648ff0a..0eadc4e 100644 --- a/src/structs.c +++ b/src/structs.c @@ -69,6 +69,8 @@ const Mat3 laplacian_kernel = } }; +int should_quit = 0; + const char chars[6] = {' ', ' ', ' ', '+', '#', '@'}; const int max_chars = sizeof(chars) / sizeof(chars[0]) - 1; @@ -77,5 +79,6 @@ const char* screen_title = "Barrow Crawler"; const int target_fps = 60; const IVec2 img_export_scale = {.x = 2, .y = 2}; +float resource_generation_progress = 0.0f; int resource_generation_finished = 0; diff --git a/src/structs.h b/src/structs.h index 990ea0a..b56696c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -4,6 +4,8 @@ #define GRID_X 128 #define GRID_Y GRID_X +#include + typedef enum { eSquare = 0, @@ -60,6 +62,16 @@ typedef struct int worker_id; } worker_arg; +typedef struct +{ + size_t worker_count; + RD_Opts rd_opts; + FVec2** grid; + IVec2 grid_size; +} GeneratorArgs; + +extern int should_quit; + extern RD_Opts barrow; extern RD_Opts puffer; extern RD_Opts worms; @@ -71,8 +83,10 @@ extern const char* screen_title; extern const int target_fps; extern const IVec2 img_export_scale; +extern float resource_generation_progress; extern int resource_generation_finished; -int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size); +//int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size); +void* generate_rd(void* args); #endif //__RD_STRUCTS__ diff --git a/src/utils.c b/src/utils.c index 1e4d8b7..daee66c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -172,32 +172,34 @@ int initialize(int worker_count, RD_Opts active_opt) return 0; } -int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size) +void* generate_rd(void* args) +//int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size) { - grid = grid_buffer; - grid_size = pgrid_size; + GeneratorArgs* garg = (GeneratorArgs*)args; + grid = garg->grid; + grid_size = garg->grid_size; - initialize(worker_count, active_opt); - start(worker_count, active_opt); + initialize(garg->worker_count, garg->rd_opts); + start(garg->worker_count, garg->rd_opts); while(!should_quit) {} printf("Opts: {\nIterations: %d\nTime delta: %f\nDiffA: %f\nDiffB: %f\nFeed: %f\nKill: %f\n\n}\n", active_opt.max_iterations, active_opt.delta_t, active_opt.diff_a, active_opt.diff_b, active_opt.feed, active_opt.kill); /* png for the heightmap */ - unsigned char barrow_mesh_buffer[pgrid_size.x][pgrid_size.y]; - unsigned char floor_mesh_buffer[pgrid_size.x][pgrid_size.y]; - unsigned char large_barrow_mesh_buffer[pgrid_size.x*img_export_scale.x][pgrid_size.y*img_export_scale.y]; - unsigned char large_floor_mesh_buffer[pgrid_size.x*img_export_scale.x][pgrid_size.y*img_export_scale.y]; + unsigned char barrow_mesh_buffer[grid_size.x][grid_size.y]; + unsigned char floor_mesh_buffer[grid_size.x][grid_size.y]; + unsigned char large_barrow_mesh_buffer[grid_size.x*img_export_scale.x][grid_size.y*img_export_scale.y]; + unsigned char large_floor_mesh_buffer[grid_size.x*img_export_scale.x][grid_size.y*img_export_scale.y]; /* png for albedo buffer */ - uint32_t albedo_buffer[pgrid_size.x][pgrid_size.y]; - uint32_t large_albedo_buffer[pgrid_size.x*img_export_scale.x][pgrid_size.y*img_export_scale.y]; + uint32_t albedo_buffer[grid_size.x][grid_size.y]; + uint32_t large_albedo_buffer[grid_size.x*img_export_scale.x][grid_size.y*img_export_scale.y]; - for (int x = 0; x < pgrid_size.x; x++) + for (int x = 0; x < grid_size.x; x++) { - for (int y = 0; y < pgrid_size.y; y++) + for (int y = 0; y < grid_size.y; y++) { - float a = round(-0.05f + grid_buffer[x][y].a); + float a = round(-0.05f + grid[x][y].a); barrow_mesh_buffer[x][y] = (uint8_t)(255.0f * a); floor_mesh_buffer[x][y] = barrow_mesh_buffer[x][y]; @@ -206,7 +208,7 @@ int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 /* ABGR */ /* Color everything stone */ /* If it's below some height threshold, color it dirt */ - a = grid_buffer[x][y].a; + a = grid[x][y].a; albedo_buffer[x][y] = 0xFF848484; if(a < 0.4) { @@ -219,30 +221,30 @@ int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 char floor_mesh_name[64] = {0}; char albedo_name[64] = {0}; char floor_albedo_name[64] = {0}; - sprintf(mesh_name, "./%s.png", active_opt.name); - sprintf(albedo_name, "./%s_albedo.png", active_opt.name); + sprintf(mesh_name, "./%s.png", garg->rd_opts.name); + sprintf(albedo_name, "./%s_albedo.png", garg->rd_opts.name); sprintf(floor_mesh_name, "./floor.png"); sprintf(floor_albedo_name, "./floor_albedo.png"); stbir_resize_uint8_linear( - (unsigned char*)barrow_mesh_buffer, pgrid_size.x, pgrid_size.y, sizeof(uint8_t) * pgrid_size.x, - (unsigned char*)large_barrow_mesh_buffer, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, sizeof(uint8_t) * pgrid_size.x * img_export_scale.x, + (unsigned char*)barrow_mesh_buffer, grid_size.x, grid_size.y, sizeof(uint8_t) * grid_size.x, + (unsigned char*)large_barrow_mesh_buffer, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, sizeof(uint8_t) * grid_size.x * img_export_scale.x, STBIR_1CHANNEL); stbir_resize_uint8_linear( - (unsigned char*)floor_mesh_buffer, pgrid_size.x, pgrid_size.y, sizeof(uint8_t) * pgrid_size.x, - (unsigned char*)large_floor_mesh_buffer, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, sizeof(uint8_t) * pgrid_size.x * img_export_scale.x, + (unsigned char*)floor_mesh_buffer, grid_size.x, grid_size.y, sizeof(uint8_t) * grid_size.x, + (unsigned char*)large_floor_mesh_buffer, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, sizeof(uint8_t) * grid_size.x * img_export_scale.x, STBIR_1CHANNEL); stbir_resize_uint8_linear( - (unsigned char*)albedo_buffer, pgrid_size.x, pgrid_size.y, sizeof(uint32_t) * pgrid_size.x, - (unsigned char*)large_albedo_buffer, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, sizeof(uint32_t) * pgrid_size.x * img_export_scale.x, + (unsigned char*)albedo_buffer, grid_size.x, grid_size.y, sizeof(uint32_t) * grid_size.x, + (unsigned char*)large_albedo_buffer, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, sizeof(uint32_t) * grid_size.x * img_export_scale.x, STBIR_RGBA); - stbi_write_png(mesh_name, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, 1, large_barrow_mesh_buffer, pgrid_size.x * sizeof(uint8_t)*img_export_scale.x); - stbi_write_png(albedo_name, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, 4, large_albedo_buffer, pgrid_size.x * sizeof(uint32_t)*img_export_scale.x); + stbi_write_png(mesh_name, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, 1, large_barrow_mesh_buffer, grid_size.x * sizeof(uint8_t)*img_export_scale.x); + stbi_write_png(albedo_name, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, 4, large_albedo_buffer, grid_size.x * sizeof(uint32_t)*img_export_scale.x); stbi_flip_vertically_on_write(1); - stbi_write_png(floor_mesh_name, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, 1, large_floor_mesh_buffer, pgrid_size.x * sizeof(uint8_t)*img_export_scale.x); - stbi_write_png(floor_albedo_name, pgrid_size.x*img_export_scale.x, pgrid_size.y*img_export_scale.y, 4, large_albedo_buffer, pgrid_size.x * sizeof(uint32_t)*img_export_scale.x); + stbi_write_png(floor_mesh_name, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, 1, large_floor_mesh_buffer, grid_size.x * sizeof(uint8_t)*img_export_scale.x); + stbi_write_png(floor_albedo_name, grid_size.x*img_export_scale.x, grid_size.y*img_export_scale.y, 4, large_albedo_buffer, grid_size.x * sizeof(uint32_t)*img_export_scale.x); cleanup(); resource_generation_finished = 1;