X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=0abe4b52946b9490dfa3f85bd8c53291a9020136;hb=3a55f20f6b627db61294523f7bf34344514e7166;hp=09bcf43e605f77f8ec421d7087c300aaaec073ee;hpb=155f3c26eb39c89057d52d72b45898819edfe640;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index 09bcf43..0abe4b5 100644 --- a/fishladder.c +++ b/fishladder.c @@ -4,6 +4,14 @@ #include "vg/vg.h" #include "fishladder_resources.h" +const char *level_pack_1[] = { + "level0", + "level1", + "level2", + "level3", + "level4" +}; + const char *level_pack[] = { // Level 0 @@ -224,6 +232,8 @@ struct world fishes[16]; int num_fishes; + + char map_name[128]; } world = {}; static void map_free(void) @@ -241,7 +251,7 @@ static void map_free(void) } static void map_reclassify( v2i start, v2i end, int update_texbuffer ); -static int map_load( const char *str ) +static int map_load( const char *str, const char *name ) { map_free(); @@ -372,7 +382,9 @@ static int map_load( const char *str ) } map_reclassify( NULL, NULL, 1 ); - vg_success( "Map loaded! (%u:%u)\n", world.w, world.h ); + vg_success( "Map '%s' loaded! (%u:%u)\n", name, world.w, world.h ); + + strncpy( world.map_name, name, vg_list_size( world.map_name )-1 ); return 1; } @@ -426,31 +438,102 @@ int main( int argc, char *argv[] ) vg_init( argc, argv, "Fish (Marbles Computer) Ladder Simulator 2022 | N,M: change level | SPACE: Test | LeftClick: Toggle tile" ); } -static void console_save_map( int argc, char *argv[] ) +static int console_save_map( int argc, char const *argv[] ) +{ + char map_path[ 256 ]; + + strcpy( map_path, "sav/" ); + strcat( map_path, world.map_name ); + strcat( map_path, ".map" ); + + FILE *test_writer = fopen( map_path, "wb" ); + if( test_writer ) + { + map_serialize( test_writer ); + + fclose( test_writer ); + return 1; + } + else + { + vg_error( "Unable to open stream for writing\n" ); + return 0; + } +} + +static int console_load_map( int argc, char const *argv[] ) { + char map_path[ 256 ]; + if( argc >= 1 ) { - FILE *test_writer = fopen( argv[0], "wb" ); - if( test_writer ) + // try from saves + strcpy( map_path, "sav/" ); + strcat( map_path, argv[0] ); + strcat( map_path, ".map" ); + + char *text_source = vg_textasset_read( map_path ); + + if( !text_source ) { - map_serialize( test_writer ); + strcpy( map_path, "maps/" ); + strcat( map_path, argv[0] ); + strcat( map_path, ".map" ); - fclose( test_writer ); + text_source = vg_textasset_read( map_path ); + } + + if( text_source ) + { + map_load( text_source, argv[0] ); + free( text_source ); + return 1; + } + else + { + vg_error( "Missing maps '%s'\n", argv[0] ); + return 0; } } + else + { + vg_error( "Missing argument \n" ); + return 0; + } +} + +static void simulation_stop(void) +{ + world.simulating = 0; + world.num_fishes = 0; + world.sim_frame = 0; + + for( int i = 0; i < arrlen( world.io ); i ++ ) + world.io[i].recv_count = 0; + + sfx_system_fadeout( &audio_system_balls_rolling, 44100 ); + + vg_info( "Stopping simulation!\n" ); } -static void console_load_map( int argc, char *argv[] ) +static int console_changelevel( int argc, char const *argv[] ) { if( argc >= 1 ) { - char *text_source = vg_textasset_read( argv[0] ); - - if( text_source ) - map_load( text_source ); - - free( text_source ); + // Save current level + if( console_save_map( 0, NULL ) ) + if( console_load_map( argc, argv ) ) + { + simulation_stop(); + return 1; + } } + else + { + vg_error( "Missing argument \n" ); + } + + return 0; } void vg_start(void) @@ -464,6 +547,11 @@ void vg_start(void) .name = "map_load", .function = console_load_map }); + + vg_function_push( (struct vg_cmd){ + .name = "changelevel", + .function = console_changelevel + }); // Quad mesh { @@ -472,11 +560,8 @@ void vg_start(void) 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, - 0.48f, 0.48f, 0.5f, 0.52f, 0.52f, 0.52f, // Static dot - 0.375f, 0.25f, 0.5f, 0.75f, 0.625f, 0.25f, // Downwards pointing arrow - 0.25f, 0.625f, 0.75f, 0.5f, 0.25f, 0.375f, // Left - 0.625f, 0.75f, 0.5f, 0.25f, 0.375f, 0.75f, // up - 0.75f, 0.375f, 0.25f, 0.5f, 0.75f, 0.625f + 0.0f, 0.0f, 0.0f, 1.0f, 4.0f, 1.0f, + 0.0f, 0.0f, 4.0f, 1.0f, 4.0f, 0.0f }; init_mesh( &world.tile, quad_mesh, vg_list_size(quad_mesh) ); @@ -537,11 +622,13 @@ void vg_start(void) resource_load_main(); - map_load( level_pack[ 0 ] ); + console_load_map( 1, level_pack_1 ); } void vg_free(void) { + console_save_map( 0, NULL ); + resource_free_main(); glDeleteTextures( 1, &world.background_data ); @@ -725,22 +812,6 @@ void vg_update(void) if( vg_get_button_down( "prev" ) ) { if( curlevel > 0 ) changelvl --; } else if( vg_get_button_down( "next" ) ) { if( curlevel < vg_list_size( level_pack )-1 ) changelvl ++; } - if( changelvl != curlevel ) - { - map_load( level_pack[ changelvl ] ); - curlevel = changelvl; - - // TEMP!!! code dupe - world.simulating = 0; - world.num_fishes = 0; - world.sim_frame = 0; - - for( int i = 0; i < arrlen( world.io ); i ++ ) - world.io[i].recv_count = 0; - - vg_info( "Stopping simulation!\n" ); - } - // Fit within screen float r1 = (float)vg_window_y / (float)vg_window_x, @@ -796,16 +867,7 @@ void vg_update(void) { if( world.simulating ) { - world.simulating = 0; - world.num_fishes = 0; - world.sim_frame = 0; - - for( int i = 0; i < arrlen( world.io ); i ++ ) - world.io[i].recv_count = 0; - - vg_info( "Stopping simulation!\n" ); - - sfx_system_fadeout( &audio_system_balls_rolling, 44100 ); + simulation_stop(); } else { @@ -1312,6 +1374,11 @@ void vg_render(void) SHADER_USE( shader_tile_colour ); glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); use_mesh( &world.circle ); + + int const filled_start = 0; + int const filled_count = 32; + int const empty_start = 32; + int const empty_count = 32*2; // Draw i/o arrays for( int i = 0; i < arrlen( world.io ); i ++ ) @@ -1320,12 +1387,7 @@ void vg_render(void) int posx = term->id % world.w; int posy = (term->id - posx)/world.w; int is_input = world.data[ term->id ].state & FLAG_INPUT; - - int const filled_start = 0; - int const filled_count = 32; - int const empty_start = 32; - int const empty_count = 32*2; - + v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f }; for( int j = 0; j < arrlen( term->conditions ); j ++ ) @@ -1367,8 +1429,73 @@ void vg_render(void) { glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.0f, 0.0f, 0.0f, 1.0f ); glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), -0.5f + cosf( vg_time * 4.0f ) * 0.2f, sinf( vg_time * 4.0f ) * 0.2f + (float)world.h * 0.5f, 0.05f ); - draw_mesh( 0, 32 ); + draw_mesh( filled_start, filled_count ); + } + + // Level selection UI + float ratio = ((float)vg_window_x/(float)vg_window_y); + + m3x3f ui_view = M3X3_IDENTITY; + m3x3_scale( ui_view, (v3f){ 1.0f, -ratio, 1.0f } ); + glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)ui_view ); + + // Calculate mouse in UIsp + v3f mouse_ui_space = { ((float)vg_mouse[0] / (float)(vg_window_x)) * 2.0f - 1.0f, + (((float)vg_mouse[1] / (float)(vg_window_y)) * 2.0f - 1.0f)*(1.0f/ratio), 0.0125f }; + + // Get selected level + const float selection_scale = 0.05f; + int const level_count = vg_list_size( level_pack_1 ); + int level_select = -1; + + if( mouse_ui_space[0] <= -0.8f ) + { + float levels_range = (float)level_count*selection_scale*0.6f; + float level_offset = ((mouse_ui_space[1] + levels_range) / levels_range) * 0.5f * (float)level_count; + level_select = floorf( level_offset ); + + // Draw selector + if( level_select >= 0 && level_select < vg_list_size( level_pack_1 ) ) + { + glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.369768f, 0.3654f, 0.42f, 1.0f ); + + use_mesh( &world.tile ); + glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), + -1.0f, + (-(float)level_count + (float)level_select * 2.0f ) * selection_scale * 0.6f, + selection_scale + ); + draw_mesh( 2, 2 ); + + use_mesh( &world.circle ); + + if( vg_get_button_down( "primary" ) ) + { + console_changelevel( 1, level_pack_1 + level_select ); + } + } } + + glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f, 0.39f, 0.45f, 1.0f ); + + // Draw levels + for( int i = 0; i < level_count; i ++ ) + { + v3f level_ui_space = { + -0.97f, + (-(float)level_count + (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f, + selection_scale * 0.5f + }; + + float scale = vg_clampf( 1.0f - fabsf(level_ui_space[1] - mouse_ui_space[1]) * 2.0f, 0.9f, 1.0f ); + level_ui_space[2] *= scale; + + glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, level_ui_space ); + draw_mesh( empty_start, empty_count ); + } + + glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, mouse_ui_space ); + draw_mesh( empty_start, empty_count ); } void vg_ui(void)