score save to disk
authorhgn <hgodden00@gmail.com>
Mon, 15 Nov 2021 12:17:09 +0000 (12:17 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 15 Nov 2021 12:17:09 +0000 (12:17 +0000)
fishladder.c
maps/impossible.map [new file with mode: 0644]
maps/level2.map [new file with mode: 0644]
maps/level3.map [new file with mode: 0644]
maps/level4.map [new file with mode: 0644]
maps/level5.map [new file with mode: 0644]
vg/vg_io.h

index 0abe4b52946b9490dfa3f85bd8c53291a9020136..e3669a45e66f1cb46c0a9172fabc856ef9e7c638 100644 (file)
@@ -9,81 +9,75 @@ const char *level_pack_1[] = {
        "level1", 
        "level2", 
        "level3", 
-       "level4"
+       "level4",
+       "level5"
 };
 
-const char *level_pack[] = 
+#pragma pack(push,1)
+struct career_state
 {
-       // Level 0
-       "#########;\n"
-       "###-#####;acac\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "#####+###;acac\n"
-       "#########;\n",
-       
-       // Level 1
-       "#########;\n"
-       "##-###-##;b,b\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "##     ##;\n"
-       "####+####;bb\n"
-       "#########;\n",
-       
-       // Level 2
-       "###########;\n"
-       "#####-#####;bbbbb\n"
-       "##       ##;\n"
-       "##      ###;\n"
-       "##  #    ##;\n"
-       "##       ##;\n"
-       "###+##+####;bbb,bb\n"
-       "###########;\n",
-       
-       // Level 3
-       "#############;\n"
-       "###-#####-###;a,aaa\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "######+######;aaaa\n"
-       "#############;\n",
-       
-       // Level 4
-       "#############;\n"
-       "###-#####-###;aaa,aa\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "##         ##;\n"
-       "###+#####+###;aa,aaa\n"
-       "#############;\n",
-       
-       // Level 5
-       "###############;\n"
-       "####-##########;abcb\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##           ##;\n"
-       "##########+####;bcba\n"
-       "###############;\n"
-};
+       u32 version;
+
+       struct career_level
+       {
+               u32 score;
+               u32 time;
+               u32 completed;
+       }
+       levels[ vg_list_size( level_pack_1 ) ]; 
+}
+career = { .version = 1 };
+#pragma pack(pop)
+
+static void career_serialize(void)
+{
+       vg_asset_write( "sav/game.sav", &career, sizeof( struct career_state ) );
+}
+
+static void career_load(void)
+{
+       i64 sz;
+       struct career_state *cr = vg_asset_read_s( "sav/game.sav", &sz );
+       
+       memset( (void*)career.levels, 0, vg_list_size(level_pack_1) * sizeof(struct career_level) );
+       
+       if( cr )
+       {
+               if( sz > sizeof( struct career_state ) )
+                       vg_warn( "This save file is too big! Some levels will be lost\n" );
+               
+               if( sz <= offsetof( struct career_state, levels ) )
+               {
+                       vg_error( "This save file is too small to have a header\n" );
+                       free( cr );
+                       return;
+               }
+               
+               u32 const size_header = offsetof(struct career_state, levels);
+               u32 const size_levels = sizeof(struct career_state)-size_header;
+               u32 const size_levels_input = sz - size_header;
+               
+               memcpy( (void*)career.levels, (void*)cr->levels, size_levels );
+               
+               if( sz < sizeof( struct career_state ) )
+               {
+                       memset( ((void*)career.levels) + size_levels_input, 0, size_levels-size_levels_input );
+               }
+               
+               free( cr );
+               vg_success( "Loaded save file... Info:\n" );
+               
+               for( int i = 0; i < vg_list_size( career.levels ); i ++ )
+               {
+                       struct career_level *lvl = &career.levels[i];
+                       vg_info( "Score: %u, Time: %u, Completed: %u\n", lvl->score, lvl->time, lvl->completed );
+               }
+       }
+       else
+       {
+               vg_info( "No save file... Using blank one\n" );
+       }
+}
 
 m3x3f m_projection;
 m3x3f m_view;
@@ -234,6 +228,8 @@ struct world
        int num_fishes;
        
        char map_name[128];
+       struct career_level *ptr_career_level;
+       
 } world = {};
 
 static void map_free(void)
@@ -487,6 +483,19 @@ static int console_load_map( int argc, char const *argv[] )
                {
                        map_load( text_source, argv[0] );
                        free( text_source );
+                       
+                       // Update career link
+                       world.ptr_career_level = NULL;
+                       
+                       for( int i = 0; i < vg_list_size( level_pack_1 ); i ++ )
+                       {
+                               if( !strcmp( level_pack_1[i], argv[0] ) )
+                               {
+                                       world.ptr_career_level = career.levels + i;
+                                       break;
+                               }
+                       }
+                       
                        return 1;
                }
                else
@@ -523,7 +532,7 @@ static int console_changelevel( int argc, char const *argv[] )
                // Save current level
                if( console_save_map( 0, NULL ) )
                        if( console_load_map( argc, argv ) )
-                       {
+                       {                               
                                simulation_stop();
                                return 1;
                        }
@@ -622,12 +631,15 @@ void vg_start(void)
        
        resource_load_main();
        
+       // Restore gamestate
+       career_load();
        console_load_map( 1, level_pack_1 );
 }
 
 void vg_free(void)
 {
        console_save_map( 0, NULL );
+       career_serialize();
 
        resource_free_main();
 
@@ -807,11 +819,6 @@ float const curve_7_linear_section = 0.1562f;
 
 void vg_update(void)
 {
-       static int curlevel = 0;
-       int changelvl = curlevel;
-       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 ++; }
-       
        // Fit within screen
 
        float r1 = (float)vg_window_y / (float)vg_window_x,
@@ -908,6 +915,8 @@ void vg_update(void)
                                }
                        }
                        
+                       int alive_count = 0;
+                       
                        // Update fish positions
                        for( int i = 0; i < world.num_fishes; i ++ )
                        {
@@ -1006,6 +1015,9 @@ void vg_update(void)
                                                cell_entry->state |= FLAG_FLIP_ROTATING;
                                        }
                                }
+                               
+                               if( fish->alive )
+                                       alive_count ++;
                        }
                        
                        // Check for collisions
@@ -1060,10 +1072,61 @@ void vg_update(void)
                                                
                                                if( !can_spawn )
                                                        world.num_fishes--;
+                                               else
+                                                       alive_count ++;
                                        }
                                }
                        }
                        
+                       if( alive_count == 0 )
+                       {
+                               if( world.ptr_career_level )
+                               {
+                                       world.ptr_career_level->completed = 1;
+                               
+                                       for( int i = 0; i < arrlen( world.io ); i ++ )
+                                       {
+                                               struct cell_terminal *term = &world.io[ i ];
+                                               int is_input = world.data[ term->id ].state & FLAG_INPUT;
+                                               
+                                               if( !is_input )
+                                               {
+                                                       if( term->recv_count == arrlen( term->conditions ) )
+                                                       {
+                                                               for( int j = 0; j < arrlen( term->conditions ); j ++ )
+                                                               {
+                                                                       if( term->recv[j] != term->conditions[j] )
+                                                                       {
+                                                                               world.ptr_career_level->completed = 0;
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               world.ptr_career_level->completed = 0;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       
+                                       if( world.ptr_career_level->completed )
+                                       {
+                                               vg_success( "Level passed!\n" );
+                                               
+                                               world.ptr_career_level->score = 9;
+                                               world.ptr_career_level->time = world.sim_frame;
+                                       }
+                                       else
+                                       {
+                                               vg_error( "Level failed :(\n" );
+                                       }
+                               }
+                               
+                               simulation_stop(); // TODO: Async?
+                               break;
+                       }
+                       
                        world.sim_frame ++;
                }
                
@@ -1475,6 +1538,7 @@ void vg_render(void)
                        }
                }
        }
+       else mouse_ui_space[1] = INFINITY;
 
        glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f, 0.39f, 0.45f, 1.0f );
 
diff --git a/maps/impossible.map b/maps/impossible.map
new file mode 100644 (file)
index 0000000..94fa39d
--- /dev/null
@@ -0,0 +1,13 @@
+###############;
+####-##-##-####;a,a,a
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+#######+#######;aaa
+###############;
diff --git a/maps/level2.map b/maps/level2.map
new file mode 100644 (file)
index 0000000..46cc4e7
--- /dev/null
@@ -0,0 +1,8 @@
+###########;
+#####-#####;bbbbb
+##       ##;
+##      ###;
+##  #    ##;
+##       ##;
+###+##+####;bbb,bb
+###########;
diff --git a/maps/level3.map b/maps/level3.map
new file mode 100644 (file)
index 0000000..9c548b3
--- /dev/null
@@ -0,0 +1,10 @@
+#############;
+###-#####-###;a,aaa
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+######+######;aaaa
+#############;
diff --git a/maps/level4.map b/maps/level4.map
new file mode 100644 (file)
index 0000000..3fa19dc
--- /dev/null
@@ -0,0 +1,10 @@
+#############;
+###-#####-###;aaa,aa
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+###+#####+###;aa,aaa
+#############;
diff --git a/maps/level5.map b/maps/level5.map
new file mode 100644 (file)
index 0000000..0614be6
--- /dev/null
@@ -0,0 +1,13 @@
+###############;
+####-##########;abcb
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##########+####;bcba
+###############;
index d037dd2a1aff2649872da5679767156a7e293c17..afd134f45a05a76d72d0a69ee7a5076a2eeecd93 100644 (file)
@@ -123,3 +123,18 @@ static char *vg_textasset_read( const char *name )
        i64 size;
        return vg_disk_load_text( name, &size );
 }
+
+static int vg_asset_write( const char *path, void *data, i64 size )
+{
+       FILE *f = fopen( path, "wb" );
+       if( f )
+       {
+               fwrite( data, size, 1, f );
+               fclose( f );
+               return 1;
+       }
+       else
+       {
+               return 0;
+       }
+}