X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=66a3eba09c6987d391f27df522135e8022294ede;hb=2f9157326993b3e6098468cd310dd20d75205645;hp=4817bdf9a2a20004f7795879f8f96c918fe4b910;hpb=a6d22d2e369a955e85d03b1159d4ac02b103ea43;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index 4817bdf..66a3eba 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(); @@ -336,22 +346,20 @@ static int map_load( const char *str ) // Tile initialization // row[ cx ] .. etc + struct cell *cell = &row[ cx ]; if( *c == '+' || *c == '-' ) { struct cell_terminal term = { .id = cx + world.h*world.w }; arrpush( world.io, term ); - row[ cx ++ ].state = *c == '+'? FLAG_INPUT: FLAG_OUTPUT; + cell->state = *c == '+'? FLAG_INPUT: FLAG_OUTPUT; reg_end ++; } - else if( *c == '#' ) - { - row[ cx ++ ].state = FLAG_WALL; - } - else - { - row[ cx ++ ].state = 0x00; - } + else if( *c == '#' ) cell->state = FLAG_WALL; + else if( *c == '*' ) cell->state = FLAG_CANAL; + else cell->state = 0x00; + + cx ++; } c ++; @@ -374,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; } @@ -428,26 +438,103 @@ 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], "w" ); - 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 int console_changelevel( int argc, char const *argv[] ) +{ + if( argc >= 1 ) + { + // Save current level + if( console_save_map( 0, NULL ) ) + if( console_load_map( argc, argv ) ) + return 1; + } + else + { + vg_error( "Missing argument \n" ); + } + + return 0; } void vg_start(void) { vg_function_push( (struct vg_cmd){ - .name = "save_map", + .name = "map_write", .function = console_save_map }); + + vg_function_push( (struct vg_cmd){ + .name = "map_load", + .function = console_load_map + }); + + vg_function_push( (struct vg_cmd){ + .name = "changelevel", + .function = console_changelevel + }); // Quad mesh { @@ -456,11 +543,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) ); @@ -521,11 +605,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 ); @@ -711,7 +797,7 @@ void vg_update(void) if( changelvl != curlevel ) { - map_load( level_pack[ changelvl ] ); + console_changelevel( 1, level_pack + changelvl ); curlevel = changelvl; // TEMP!!! code dupe @@ -1296,6 +1382,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 ++ ) @@ -1304,12 +1395,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 ++ ) @@ -1351,8 +1437,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)