added stuff
authorhgn <hgodden00@gmail.com>
Tue, 7 Dec 2021 15:21:07 +0000 (15:21 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 7 Dec 2021 15:21:07 +0000 (15:21 +0000)
fishladder.c
fishladder_resources.h
maps/cmp_t01.map [new file with mode: 0644]
maps/cmp_t02.map [new file with mode: 0644]
maps/cmp_t03.map [new file with mode: 0644]
maps/cmp_t04.map [new file with mode: 0644]
maps/level0.map [deleted file]
maps/level1.map [deleted file]
maps/level2.map [deleted file]
vg/vg_ui.h

index ecd46814f29908b149143f235d1a52547aa1d331..19e3fb42b54f681bfa913e4a45201686ae55dc0f 100644 (file)
@@ -48,91 +48,6 @@ const char *level_pack_1[] = {
        "thirds"
 };
 
        "thirds"
 };
 
-#pragma pack(push,1)
-struct dcareer_state
-{
-       u32 version;
-       i32 total_unlocked;
-       
-       u32 reserved[14];
-
-       struct dlevel_state
-       {
-               i32 score;
-               i32 reserved[3];
-       }
-       levels[ NUM_CAMPAIGN_LEVELS ];  
-};
-#pragma pack(pop)
-
-static void career_serialize(void)
-{
-       struct dcareer_state encoded;
-       encoded.version = 2;
-       encoded.total_unlocked = career_local.total_unlocked;
-
-       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
-       {
-               struct serializable_set *set = &career_serializable[i];
-               
-               for( int j = 0; j < set->count; j ++ )
-               {
-                       struct cmp_level *lvl = &set->pack[j];
-                       struct dlevel_state *dest = &encoded.levels[lvl->serial_id];
-                       
-                       dest->score = lvl->completed_score;
-                       dest->reserved[0] = 0;
-                       dest->reserved[1] = 0;
-                       dest->reserved[2] = 0;
-               }
-       }
-
-       vg_asset_write( "sav/game.sv2", &encoded, sizeof( struct dcareer_state ) );
-}
-
-static void career_load(void)
-{
-       i64 sz;
-       struct dcareer_state encoded;
-       memset( (void*)&encoded, 0, sizeof( struct dcareer_state ) );
-       
-       // Load and copy data into encoded
-       void *cr = vg_asset_read_s( "sav/game.sv2", &sz );
-       
-       if( cr )
-       {
-               if( sz > sizeof( struct dcareer_state ) )
-                       vg_warn( "This save file is too big! Some levels will be lost\n" );
-               
-               if( sz <= offsetof( struct dcareer_state, levels ) )
-               {
-                       vg_warn( "This save file is too small to have a header. Creating a blank one\n" );
-                       free( cr );
-                       return;
-               }
-               
-               memcpy( (void*)&encoded, cr, VG_MIN( sizeof( struct dcareer_state ), sz ) );
-               free( cr );
-       }
-       else
-               vg_info( "No save file... Using blank one\n" );
-               
-       // Decode everything from dstate
-       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
-       {
-               struct serializable_set *set = &career_serializable[i];
-               
-               for( int j = 0; j < set->count; j ++ )
-               {
-                       struct cmp_level *lvl = &set->pack[j];
-                       struct dlevel_state *src = &encoded.levels[lvl->serial_id];
-                       
-                       lvl->completed_score = src->score;
-                       // ...
-               }
-       }
-}
-
 m3x3f m_projection;
 m3x3f m_view;
 m3x3f m_mdl;
 m3x3f m_projection;
 m3x3f m_view;
 m3x3f m_mdl;
@@ -381,7 +296,7 @@ struct world
        u32 score;
        u32 completed;
        u32 time;
        u32 score;
        u32 completed;
        u32 time;
-} world = {};
+} world;
 
 void leaderboard_set_score( struct cmp_level *cmp_level, u32 score );
 
 
 void leaderboard_set_score( struct cmp_level *cmp_level, u32 score );
 
@@ -978,6 +893,148 @@ static int console_changelevel( int argc, char const *argv[] )
        return 0;
 }
 
        return 0;
 }
 
+#pragma pack(push,1)
+struct dcareer_state
+{
+       u32 version;
+       i32 in_map;
+       
+       u32 reserved[14];
+
+       struct dlevel_state
+       {
+               i32 score;
+               i32 unlocked;
+               i32 reserved[2];
+       }
+       levels[ NUM_CAMPAIGN_LEVELS ];  
+};
+#pragma pack(pop)
+
+static void career_serialize(void)
+{
+       struct dcareer_state encoded;
+       encoded.version = 2;
+       encoded.in_map = world.pCmpLevel? world.pCmpLevel->serial_id: -1;
+       
+       memset( encoded.reserved, 0, sizeof( encoded.reserved ) );
+
+       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
+       {
+               struct serializable_set *set = &career_serializable[i];
+               
+               for( int j = 0; j < set->count; j ++ )
+               {
+                       struct cmp_level *lvl = &set->pack[j];
+                       struct dlevel_state *dest = &encoded.levels[lvl->serial_id];
+                       
+                       dest->score = lvl->completed_score;
+                       dest->unlocked = lvl->unlocked;
+                       dest->reserved[0] = 0;
+                       dest->reserved[1] = 0;
+               }
+       }
+
+       vg_asset_write( "sav/game.sv2", &encoded, sizeof( struct dcareer_state ) );
+}
+
+static void career_unlock_level( struct cmp_level *lvl );
+static void career_unlock_level( struct cmp_level *lvl )
+{
+       lvl->unlocked = 1;
+       
+       if( lvl->linked )
+               career_unlock_level( lvl->linked );
+}
+
+static void career_pass_level( struct cmp_level *lvl, int score, int upload )
+{
+       if( score > 0 )
+       {
+               if( score < lvl->completed_score || lvl->completed_score == 0 )
+               {
+                       if( !lvl->is_tutorial && upload )
+                               leaderboard_set_score( lvl, score );
+                       
+                       lvl->completed_score = score;
+               }
+               
+               if( lvl->unlock ) career_unlock_level( lvl->unlock );
+       }
+}
+
+static void career_reset_level( struct cmp_level *lvl )
+{
+       lvl->unlocked = 0;
+       lvl->completed_score = 0;
+}
+
+static void career_load(void)
+{
+       i64 sz;
+       struct dcareer_state encoded;
+
+       // Blank save state
+       memset( (void*)&encoded, 0, sizeof( struct dcareer_state ) );   
+       encoded.in_map = -1;
+       encoded.levels[0].unlocked = 1;
+       
+       // Load and copy data into encoded
+       void *cr = vg_asset_read_s( "sav/game.sv2", &sz );
+       
+       if( cr )
+       {
+               if( sz > sizeof( struct dcareer_state ) )
+                       vg_warn( "This save file is too big! Some levels will be lost\n" );
+               
+               if( sz <= offsetof( struct dcareer_state, levels ) )
+               {
+                       vg_warn( "This save file is too small to have a header. Creating a blank one\n" );
+                       free( cr );
+                       return;
+               }
+               
+               memcpy( (void*)&encoded, cr, VG_MIN( sizeof( struct dcareer_state ), sz ) );
+               free( cr );
+       }
+       else
+               vg_info( "No save file... Using blank one\n" );
+       
+       // Reset memory
+       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
+       {
+               struct serializable_set *set = &career_serializable[i];
+               
+               for( int j = 0; j < set->count; j ++ )
+                       career_reset_level( &set->pack[j] );
+       }
+       
+       // Header information
+       // =================================
+       
+       // Decode everything from dstate
+       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
+       {
+               struct serializable_set *set = &career_serializable[i];
+               
+               for( int j = 0; j < set->count; j ++ )
+               {
+                       struct cmp_level *lvl = &set->pack[j];
+                       struct dlevel_state *src = &encoded.levels[lvl->serial_id];
+                       
+                       if( src->unlocked ) career_unlock_level( lvl );
+                       if( src->score ) lvl->completed_score = src->score;
+                       
+                       // ...
+                       if( lvl->serial_id == encoded.in_map )
+                       {
+                               if( console_changelevel( 1, &lvl->map_name ) )
+                                       world.pCmpLevel = lvl;
+                       }
+               }
+       }
+}
+
 void leaderboard_found( LeaderboardFindResult_t *pCallback );
 void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback );
 
 void leaderboard_found( LeaderboardFindResult_t *pCallback );
 void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback );
 
@@ -1139,8 +1196,8 @@ void vg_start(void)
        resource_load_main();
        
        // Restore gamestate
        resource_load_main();
        
        // Restore gamestate
+       career_local_data_init();
        career_load();
        career_load();
-       console_load_map( 1, level_pack_1 );
 }
 
 void vg_free(void)
 }
 
 void vg_free(void)
@@ -1857,6 +1914,12 @@ void vg_update(void)
                                                
                                                world.score = score;
                                                world.time = world.sim_frame;
                                                
                                                world.score = score;
                                                world.time = world.sim_frame;
+                                               
+                                               // Copy into career data
+                                               if( world.pCmpLevel )
+                                               {
+                                                       career_pass_level( world.pCmpLevel, world.score, 1 );
+                                               }
                                        }
                                }
                                else
                                        }
                                }
                                else
@@ -1867,14 +1930,6 @@ void vg_update(void)
                                        vg_error( "Level failed :(\n" );
                                }
                                
                                        vg_error( "Level failed :(\n" );
                                }
                                
-                               // Copy into career data
-                               if( world.pCmpLevel )
-                               {
-                                       if( world.score < world.pCmpLevel->completed_score || world.pCmpLevel->completed_score == 0 )
-                                               leaderboard_set_score( world.pCmpLevel, world.score );
-                                       
-                                       world.pCmpLevel->completed_score = world.score;
-                               }
                                
                                simulation_stop(); // TODO: Async?
                                break;
                                
                                simulation_stop(); // TODO: Async?
                                break;
@@ -2079,6 +2134,8 @@ void vg_render(void)
        
        
        // Level title
        
        
        // Level title
+       // TODO: Fix this?
+       /*
        ui_begin( &ui_global_ctx, 512, 256 );
        
        ui_global_ctx.override_colour = 0xff9a8a89;
        ui_begin( &ui_global_ctx, 512, 256 );
        
        ui_global_ctx.override_colour = 0xff9a8a89;
@@ -2094,6 +2151,7 @@ void vg_render(void)
        m3x3_scale( world_text, (v3f){0.01f,-0.01f,0.01f} );
        
        ui_draw( &ui_global_ctx, world_text );
        m3x3_scale( world_text, (v3f){0.01f,-0.01f,0.01f} );
        
        ui_draw( &ui_global_ctx, world_text );
+       */
        
        // Main
        // =========================================================================================
        
        // Main
        // =========================================================================================
@@ -2304,12 +2362,13 @@ void vg_render(void)
                        for( int j = 0; j < term->runs[k].condition_count; j ++ )
                        {
                                float y_offset = is_input? 1.2f: -0.2f;
                        for( int j = 0; j < term->runs[k].condition_count; j ++ )
                        {
                                float y_offset = is_input? 1.2f: -0.2f;
-                               y_offset += (is_input? 0.2f: -0.2f) * (float)k;
-                               
-                               glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)posx + 0.2f + 0.2f * (float)j, (float)posy + y_offset, 0.1f );
+                               float y_h = (is_input? 0.2f: -0.2f) * (float)k;
                                
                                if( is_input )
                                {
                                
                                if( is_input )
                                {
+                                       glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)posx + 0.2f + 0.2f * (float)j, 
+                                               (y_offset + (float)posy + (float)(term->run_count-1)*0.2f) - y_h, 0.1f );
+                               
                                        colour_code_v3( term->runs[k].conditions[j], dot_colour );
                                        glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
                                
                                        colour_code_v3( term->runs[k].conditions[j], dot_colour );
                                        glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
                                
@@ -2321,6 +2380,8 @@ void vg_render(void)
                                }
                                else
                                {
                                }
                                else
                                {
+                                       glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)posx + 0.2f + 0.2f * (float)j, (float)posy + y_offset + y_h, 0.1f );
+                               
                                        if( term->runs[k].recv_count > j )
                                        {
                                                colour_code_v3( term->runs[k].recieved[j], dot_colour );
                                        if( term->runs[k].recv_count > j )
                                        {
                                                colour_code_v3( term->runs[k].recieved[j], dot_colour );
@@ -2493,8 +2554,7 @@ void vg_ui(void)
                {
                        struct cmp_level *levels = pack_infos[ pack_selection ].levels;
                        int count = pack_infos[ pack_selection ].level_count;
                {
                        struct cmp_level *levels = pack_infos[ pack_selection ].levels;
                        int count = pack_infos[ pack_selection ].level_count;
-                       int unlocked = 3000;
-               
+
                        static struct ui_scrollbar sb = {
                                .bar_height = 400
                        };
                        static struct ui_scrollbar sb = {
                                .bar_height = 400
                        };
@@ -2530,7 +2590,7 @@ void vg_ui(void)
                                {
                                        struct cmp_level *lvl_info = &levels[i];
                                
                                {
                                        struct cmp_level *lvl_info = &levels[i];
                                
-                                       if( i < unlocked )
+                                       if( lvl_info->unlocked )
                                        {
                                                if( lvl_info->completed_score != 0 )
                                                        gui_override_colours( i&0x1? &flcol_list_complete_a: &flcol_list_complete_b );
                                        {
                                                if( lvl_info->completed_score != 0 )
                                                        gui_override_colours( i&0x1? &flcol_list_complete_a: &flcol_list_complete_b );
@@ -2540,7 +2600,7 @@ void vg_ui(void)
                                        else
                                                gui_override_colours( &flcol_list_locked );
                                        
                                        else
                                                gui_override_colours( &flcol_list_locked );
                                        
-                                       if( i < unlocked )
+                                       if( lvl_info->unlocked )
                                        {
                                                if( gui_button( 2 + i ) == k_button_click )
                                                {
                                        {
                                                if( gui_button( 2 + i ) == k_button_click )
                                                {
@@ -2648,11 +2708,13 @@ void vg_ui(void)
                                gui_override_colours( &flcol_list_complete_a );
                                if( gui_button( 3002 ) == k_button_click )
                                {
                                gui_override_colours( &flcol_list_complete_a );
                                if( gui_button( 3002 ) == k_button_click )
                                {
-                                       console_changelevel( 1, &ui_data.level_selected->map_name );
-                                       world.pCmpLevel = ui_data.level_selected;
+                                       if( console_changelevel( 1, &ui_data.level_selected->map_name ) )
+                                       {
+                                               world.pCmpLevel = ui_data.level_selected;
 
 
-                                       ui_data.level_selected = NULL;
-                                       ui_data.leaderboard_show = 0;
+                                               ui_data.level_selected = NULL;
+                                               ui_data.leaderboard_show = 0;
+                                       }
                                }
                                gui_text( "PLAY", 6, k_text_alignment_center );
                                gui_end();
                                }
                                gui_text( "PLAY", 6, k_text_alignment_center );
                                gui_end();
index c06c17de94edf307c635bb00ea0134c4dc3662b8..8c8ee3b64e32417ece53df146b67ab9fb2da9e7c 100644 (file)
@@ -566,129 +566,139 @@ struct cmp_level
        const char *title;
        const char *description;
        
        const char *title;
        const char *description;
        
+       int unlocked;
        int completed_score;
        
        int completed_score;
        
-       int unlocks;                    // When completed, unlock this many levels
-       int linked_unlocks;     // When unlocked, unlock this many levels additionally
+       int _unlock, _linked;   // When completed, unlock this level
+       struct cmp_level *unlock, *linked;
        
        int serial_id;
        
        int serial_id;
+       int is_tutorial;
        
        SteamLeaderboard_t steam_leaderboard;
 };
 
        
        SteamLeaderboard_t steam_leaderboard;
 };
 
-struct cmp_level cmp_levels_tutorials[] = 
+static struct cmp_level cmp_levels_tutorials[] = 
 {
        {
 {
        {
+               .serial_id = 0,
                .title = "PRINCIPLE 1",
                .map_name = "cmp_t01",
                .description = "Utilize basic transport methods",
                
                .title = "PRINCIPLE 1",
                .map_name = "cmp_t01",
                .description = "Utilize basic transport methods",
                
-               .serial_id = 0,
-               .unlocks = 1
+               ._unlock = 1,
+               .is_tutorial = 1
        },
        {
        },
        {
+               .serial_id = 1,
                .title = "PRINCIPLE 2",
                .map_name = "cmp_t02",
                .description = "Utilize the twisty turny(TM) piece to split\n"
                                                        "the marble stream into two",
                
                .title = "PRINCIPLE 2",
                .map_name = "cmp_t02",
                .description = "Utilize the twisty turny(TM) piece to split\n"
                                                        "the marble stream into two",
                
-               .serial_id = 1,
-               .unlocks = 1
+               ._unlock = 2,
+               .is_tutorial = 1,
        },
        {
        },
        {
+               .serial_id = 2,
                .title = "PRINCIPLE 3",
                .map_name = "cmp_t03",
                .description = "Merge transport into one",
                
                .title = "PRINCIPLE 3",
                .map_name = "cmp_t03",
                .description = "Merge transport into one",
                
-               .serial_id = 2,
-               .unlocks = 1,
+               ._unlock = 12,
+               .is_tutorial = 1
        },
        {
        },
        {
+               .serial_id = 12,
                .title = "PRINCIPLE 4",
                .map_name = "cmp_t04",
                .description = "Some stages require multiple runs to succeed\n" 
                                                        "in order to pass",
                
                .title = "PRINCIPLE 4",
                .map_name = "cmp_t04",
                .description = "Some stages require multiple runs to succeed\n" 
                                                        "in order to pass",
                
-               .serial_id = 12,
-               .unlocks = 3
+               ._unlock = 3,
+               .is_tutorial = 1
        }
 };
 
        }
 };
 
-struct cmp_level cmp_levels_basic[] =
+static struct cmp_level cmp_levels_basic[] =
 {
        {
 {
        {
+               .serial_id = 3,
                .title = "SUBDIVISION 1",
                .map_name = "cmp_b01",
                .description = "Simple maths, branching required.",
                
                .title = "SUBDIVISION 1",
                .map_name = "cmp_b01",
                .description = "Simple maths, branching required.",
                
-               .serial_id = 3,
-               .unlocks = 1
+               ._linked = 4,
+               ._unlock = 6
        },
        {
        },
        {
+               .serial_id = 4,
                .title = "SUBDIVISION 2",
                .map_name = "cmp_b02",
                .description = "Simple maths, except more.",
                .title = "SUBDIVISION 2",
                .map_name = "cmp_b02",
                .description = "Simple maths, except more.",
-
-               .serial_id = 4,
-               .unlocks = 1
+               
+               ._linked = 5,
+               ._unlock = 7
        },
        {
        },
        {
+               .serial_id = 5,
                .title = "RESTRUCTURE",
                .map_name = "cmp_b03",
                .description = "Not so simple swap",
                
                .title = "RESTRUCTURE",
                .map_name = "cmp_b03",
                .description = "Not so simple swap",
                
-               .serial_id = 5,
-               .unlocks = 1
+               ._unlock = 8
        },
        {
        },
        {
+               .serial_id = 6,
                .title = "SERIALIZE",
                .map_name = "cmp_b04",
                .description = "Merge and sort",
                
                .title = "SERIALIZE",
                .map_name = "cmp_b04",
                .description = "Merge and sort",
                
-               .serial_id = 6,
-               .unlocks = 1
+               ._unlock = 7
        },
        {
        },
        {
+               .serial_id = 7,
                .title = "PATTERNS 1",
                .map_name = "cmp_b05",
                .description = "Replicate",
                
                .title = "PATTERNS 1",
                .map_name = "cmp_b05",
                .description = "Replicate",
                
-               .serial_id = 7,
-               .unlocks = 1
+               ._linked = 8
        },
        {
        },
        {
+               .serial_id = 8,
                .title = "PATTERNS 2",
                .map_name = "cmp_b06",
                .description = "Replicate MORE",
                
                .title = "PATTERNS 2",
                .map_name = "cmp_b06",
                .description = "Replicate MORE",
                
-               .serial_id = 8,
-               .unlocks = 1
+               ._unlock = 9
        },
        {
        },
        {
+               .serial_id = 9,
                .title = "MIGHTY CONSUMER",
                .map_name = "cmp_b07",
                .description = "Build a greedy system",
                
                .title = "MIGHTY CONSUMER",
                .map_name = "cmp_b07",
                .description = "Build a greedy system",
                
-               .serial_id = 9,
-               .unlocks = 1
+               ._linked = 10,
+               ._unlock = 11
        },
        {
        },
        {
+               .serial_id = 10,
                .title = "ENCRYPTED 1",
                .map_name = "cmp_b08",
                .description = "Some configurations may not be valid",
 
                .title = "ENCRYPTED 1",
                .map_name = "cmp_b08",
                .description = "Some configurations may not be valid",
 
-               .serial_id = 10,
-               .unlocks = 1
+               ._unlock = 15
        },
        {
        },
        {
+               .serial_id = 11,
                .title = "REVERSE",
                .map_name = "cmp_b09",
                .description = "Reverse the incoming order. Always length 4",
                
                .title = "REVERSE",
                .map_name = "cmp_b09",
                .description = "Reverse the incoming order. Always length 4",
                
-               .serial_id = 11,
-               .unlocks = 1
+               ._unlock = 15
        },
        {
        },
        {
+               .serial_id = 15,
                .title = "PRINCIPLE 5",
                .map_name = "cmp_b10",
                .description = 
                .title = "PRINCIPLE 5",
                .map_name = "cmp_b10",
                .description = 
@@ -699,20 +709,20 @@ struct cmp_level cmp_levels_basic[] =
                        "of your training package, you will now be tasked to\n"
                        "complete them",
 
                        "of your training package, you will now be tasked to\n"
                        "complete them",
 
-               .serial_id = 15,
-               .linked_unlocks = 1
+               ._unlock = 16
        },
        {
        },
        {
+               .serial_id = 16,
                .title = "ROUTING PROBLEM",
                .map_name = "cmp_routing",
                .description = 
                        "Things can get a little chaotic on tight boards, do your\n"
                        "best to utilize principle 5 to get the job done\n",
                
                .title = "ROUTING PROBLEM",
                .map_name = "cmp_routing",
                .description = 
                        "Things can get a little chaotic on tight boards, do your\n"
                        "best to utilize principle 5 to get the job done\n",
                
-               .serial_id = 16,
-               .unlocks = 1
+               ._unlock = 17
        },
        {
        },
        {
+               .serial_id = 17,
                .title = "PRINCIPLE 6",
                .map_name = "cmp_b11",
                .description =
                .title = "PRINCIPLE 6",
                .map_name = "cmp_b11",
                .description =
@@ -733,93 +743,95 @@ struct cmp_level cmp_levels_basic[] =
                        "this results in no operation being performed, and no\n"
                        "state changes take place in the Twisty Turny(TM)\n",
 
                        "this results in no operation being performed, and no\n"
                        "state changes take place in the Twisty Turny(TM)\n",
 
-                       .serial_id = 17,
-                       .linked_unlocks = 1
+               ._unlock = 18
        },
        {
        },
        {
+               .serial_id = 18,
                .title = "NOT GATE",
                .map_name = "cmp_not",
                .description = 
                        "Test your knowledge of triggers, build an 'NOT GATE'\n"
                        "emulated by marble logic.",
                
                .title = "NOT GATE",
                .map_name = "cmp_not",
                .description = 
                        "Test your knowledge of triggers, build an 'NOT GATE'\n"
                        "emulated by marble logic.",
                
-               .serial_id = 18,
-               .unlocks = 1
+               ._linked = 19,
+               ._unlock = 20
        },
        {
        },
        {
+               .serial_id = 19,
                .title = "AND GATE",
                .map_name = "cmp_and",
                .description = 
                        "A slightly more complicated gate, but shouldn't be\n"
                        "too difficult for your skillset.",
                
                .title = "AND GATE",
                .map_name = "cmp_and",
                .description = 
                        "A slightly more complicated gate, but shouldn't be\n"
                        "too difficult for your skillset.",
                
-               .serial_id = 19,
-               .unlocks = 1
+               ._unlock = 20
        },
        {
        },
        {
+               .serial_id = 20,
                .title = "QUALIFICATION PROJECT",
                .map_name = "cmp_grad",
                .description =
                        "There's no instructions here, resolve and complete this\n"
                        "task to qualify yourself as an official marble engineer",
                .title = "QUALIFICATION PROJECT",
                .map_name = "cmp_grad",
                .description =
                        "There's no instructions here, resolve and complete this\n"
                        "task to qualify yourself as an official marble engineer",
-               .serial_id = 20,
-               .unlocks = 3
+               ._unlock = 13
        }
 };
 
        }
 };
 
-struct cmp_level cmp_levels_grad[] =
+static struct cmp_level cmp_levels_grad[] =
 {
        {
 {
        {
+               .serial_id = 13,
                .title = "SORT",
                .map_name = "cmp_i01",
                .description = 
                        "Device a scheme to filter and sort the inputs. If you\n"
                        "believe you lack the tools required to solve this one,\n"
                        "take a harder look at the inputs.",
                .title = "SORT",
                .map_name = "cmp_i01",
                .description = 
                        "Device a scheme to filter and sort the inputs. If you\n"
                        "believe you lack the tools required to solve this one,\n"
                        "take a harder look at the inputs.",
+               ._linked = 14
                
                
-               .serial_id = 13
        },
        {
        },
        {
+               .serial_id = 14,
                .title = "THIRDS",
                .map_name = "cmp_i02",
                .description = 
                        "Split the inputs up into a third of their values\n"
                        "\n"
                        "Is this possible? -HG",
                .title = "THIRDS",
                .map_name = "cmp_i02",
                .description = 
                        "Split the inputs up into a third of their values\n"
                        "\n"
                        "Is this possible? -HG",
+               ._linked = 21
                
                
-               .serial_id = 14
        },
        {
        },
        {
+               .serial_id = 21,
                .title = "XOR CHIP",
                .map_name = "cmp_xor",
                .description = 
                        "Significantly more complicated than an AND or NOT gate,\n"
                        "but possible.",
                .title = "XOR CHIP",
                .map_name = "cmp_xor",
                .description = 
                        "Significantly more complicated than an AND or NOT gate,\n"
                        "but possible.",
-               .serial_id = 21
+               ._linked = 22
        },
        {
        },
        {
+               .serial_id = 22,
                .title = "SECRET CODE",
                .map_name = "cmp_secret",
                .description = 
                        "Only one input should send an unlock signal marble to\n"
                        "the output.\n"
                .title = "SECRET CODE",
                .map_name = "cmp_secret",
                .description = 
                        "Only one input should send an unlock signal marble to\n"
                        "the output.\n"
-                       "The code: 100110",
-               .serial_id = 22
+                       "The code: 100110"
        }
 };
 
 #define NUM_CAMPAIGN_LEVELS (vg_list_size( cmp_levels_tutorials ) + vg_list_size( cmp_levels_basic ) + vg_list_size( cmp_levels_grad ))
 
        }
 };
 
 #define NUM_CAMPAIGN_LEVELS (vg_list_size( cmp_levels_tutorials ) + vg_list_size( cmp_levels_basic ) + vg_list_size( cmp_levels_grad ))
 
-struct
+/*
+static struct
 {
 {
-       int total_unlocked;
 }
 career_local = 
 {
 }
 career_local = 
 {
-       .total_unlocked = 1
-};
+};*/
 
 
-struct serializable_set 
+static struct serializable_set 
 {
        struct cmp_level *pack;
        int count;
 {
        struct cmp_level *pack;
        int count;
@@ -839,3 +851,31 @@ career_serializable[] =
                .count = vg_list_size( cmp_levels_grad )
        }
 };
                .count = vg_list_size( cmp_levels_grad )
        }
 };
+
+// Setup pointers and that
+static void career_local_data_init(void)
+{
+       struct cmp_level *level_ptrs[ NUM_CAMPAIGN_LEVELS ];
+       
+       // COllect pointers
+       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
+       {
+               struct serializable_set *set = &career_serializable[i];
+               
+               for( int j = 0; j < set->count; j ++ )
+                       level_ptrs[ set->pack[j].serial_id ] = &set->pack[j];
+       }
+       
+       // Apply
+       for( int i = 0; i < vg_list_size( career_serializable ); i ++ )
+       {
+               struct serializable_set *set = &career_serializable[i];
+               
+               for( int j = 0; j < set->count; j ++ )
+               {
+                       struct cmp_level *lvl = &set->pack[j];
+                       lvl->unlock = lvl->_unlock? level_ptrs[ lvl->_unlock ]: NULL;
+                       lvl->linked = lvl->_linked? level_ptrs[ lvl->_linked ]: NULL;
+               }
+       }
+}
diff --git a/maps/cmp_t01.map b/maps/cmp_t01.map
new file mode 100644 (file)
index 0000000..76b32b8
--- /dev/null
@@ -0,0 +1,8 @@
+#########;
+###-#####;aa
+##     ##;
+##     ##;
+##     ##;
+##     ##;
+#####+###;aa
+#########;
diff --git a/maps/cmp_t02.map b/maps/cmp_t02.map
new file mode 100644 (file)
index 0000000..5d06111
--- /dev/null
@@ -0,0 +1,9 @@
+#########;
+##-###-##;b,b
+##     ##;
+##     ##;
+##     ##;
+##     ##;
+##     ##;
+####+####;bb
+#########;
diff --git a/maps/cmp_t03.map b/maps/cmp_t03.map
new file mode 100644 (file)
index 0000000..46cc4e7
--- /dev/null
@@ -0,0 +1,8 @@
+###########;
+#####-#####;bbbbb
+##       ##;
+##      ###;
+##  #    ##;
+##       ##;
+###+##+####;bbb,bb
+###########;
diff --git a/maps/cmp_t04.map b/maps/cmp_t04.map
new file mode 100644 (file)
index 0000000..48bcc5b
--- /dev/null
@@ -0,0 +1,10 @@
+#############;
+###-#####-###;a:aa,b:bb
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+##         ##;
+######+######;ab:abab
+#############;
diff --git a/maps/level0.map b/maps/level0.map
deleted file mode 100644 (file)
index a30aab9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-PRINCIPLE 1
-#########;
-###-#####;acac
-##     ##;
-##     ##;
-##     ##;
-##     ##;
-#####+###;acac
-#########;
diff --git a/maps/level1.map b/maps/level1.map
deleted file mode 100644 (file)
index 5d06111..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#########;
-##-###-##;b,b
-##     ##;
-##     ##;
-##     ##;
-##     ##;
-##     ##;
-####+####;bb
-#########;
diff --git a/maps/level2.map b/maps/level2.map
deleted file mode 100644 (file)
index 46cc4e7..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-###########;
-#####-#####;bbbbb
-##       ##;
-##      ###;
-##  #    ##;
-##       ##;
-###+##+####;bbb,bb
-###########;
index 7e676545546355c7819f9f5c81b2e68a6ae8b5c8..11728509ae0d9ac7fa03feae4fd5a83c39332cd3 100644 (file)
@@ -384,8 +384,8 @@ static void ui_new_node( ui_ctx *ctx )
        
        if( parent->mouse_over )
        {
        
        if( parent->mouse_over )
        {
-               if( ctx->mouse[0] >= node->rect[0] && ctx->mouse[0] <= node->rect[0]+node->rect[2] &&
-                        ctx->mouse[1] >= node->rect[1] && ctx->mouse[1] <= node->rect[1]+node->rect[3] )
+               if( ctx->mouse[0] >= node->rect[0] && ctx->mouse[0] < node->rect[0]+node->rect[2] &&
+                        ctx->mouse[1] >= node->rect[1] && ctx->mouse[1] < node->rect[1]+node->rect[3] )
                        node->mouse_over = 1;
                else
                        node->mouse_over = 0;
                        node->mouse_over = 1;
                else
                        node->mouse_over = 0;