+ enum world_button_status stat;
+ int world_paused = world.st.buttons[k_world_button_pause].state;
+ int world_running = world.st.buttons[k_world_button_sim].state;
+
+ float sim_icon_x = world_paused? 3.0f: (world_running? 2.0f: 0.0f);
+
+ v3f btn_dark_blue = { 0.204f, 0.345f, 0.553f };
+ v3f btn_orange = { 0.553f, 0.345f, 0.204f };
+
+ if( world_button_exec( &world.st.buttons[k_world_button_sim], (v2f){ sim_icon_x, 3.0f }, btn_dark_blue, &stat ))
+ {
+ if( stat == k_world_button_on_enable )
+ {
+ simulation_start();
+
+ if( world_paused )
+ world.pause_offset_target = 0.5f;
+ }
+ else
+ {
+ if( world_paused )
+ {
+ // Trigger single step
+ world.pause_offset_target += 1.0f;
+ world.st.buttons[k_world_button_sim].state = 1;
+ }
+ else
+ {
+ simulation_stop();
+ }
+ }
+ }
+
+ if( world_button_exec( &world.st.buttons[k_world_button_pause], (v2f){ 1.0f, 3.0f }, btn_dark_blue, &stat ))
+ {
+ world.sim_internal_ref = world.sim_internal_time;
+ world.sim_delta_ref = vg_time;
+
+ if( stat == k_world_button_on_enable )
+ {
+ float time_frac = world.sim_internal_time-floorf(world.sim_internal_time);
+ world.pause_offset_target = 0.5f - time_frac;
+ }
+ else
+ world.pause_offset_target = 0.0f;
+ }
+
+ if( world_button_exec( &world.st.buttons[k_world_button_speedy], (v2f){ 0.0f, 2.0f }, btn_orange, &stat ))
+ {
+ world.sim_delta_speed = stat == k_world_button_on_enable? 10.0f: 2.5f;
+
+ if( !world_paused )
+ {
+ world.sim_delta_ref = vg_time;
+ world.sim_internal_ref = world.sim_internal_time;
+ }
+ }
+
+ if( world_button_exec( &world.st.buttons[k_world_button_settings], (v2f){ 1.0f, 2.0f }, btn_orange, &stat ))
+ {
+ world.st.state = stat == k_world_button_on_enable? k_game_state_settings: k_game_state_main;
+ }
+
+ level_selection_buttons();
+
+ if( vg_get_button_up( "primary" ) )
+ world_button_exec( NULL, NULL, NULL, NULL );
+
+ // SPRITES
+ // ========================================================================================================
+ SHADER_USE( shader_sprite );
+ glUniformMatrix3fv( SHADER_UNIFORM( shader_sprite, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+
+ vg_tex2d_bind( &tex_sprites, 0 );
+ glUniform1i( SHADER_UNIFORM( shader_sprite, "uTexMain" ), 0 );
+
+ for( int i = 0; i < world.tile_special_count; i ++ )
+ {
+ struct render_cmd *cmd = &world.cmd_buf_specials[i];
+ struct cell *cell = cmd->ptr;
+
+ if( cell->config == k_cell_type_split )
+ {
+ v2f center = { cmd->pos[0] + 0.5f, cmd->pos[1] + 0.5f };
+
+ v3f p0 = { 0.0f, 0.0f, 4.0f };
+ v3f p1 = { 0.0f, 0.0f, 4.0f };
+
+ v2_add( center, (v2f){ -0.25f, -0.25f }, p0 );
+ v2_add( center, (v2f){ 0.25f, -0.25f }, p1 );
+
+ render_sprite( k_sprite_jack_1, p0 );
+ render_sprite( k_sprite_jack_2, p1 );
+ }
+ }
+
+ // TEXT ELEMENTS
+ // ========================================================================================================
+ SHADER_USE( shader_sdf );
+ glBindVertexArray( text_buffers.vao );
+ glUniformMatrix3fv( SHADER_UNIFORM( shader_sdf, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+
+ vg_tex2d_bind( &tex_ubuntu, 0 );
+ glUniform1i( SHADER_UNIFORM( shader_sdf, "uTexGlyphs" ), 0 );
+
+ glUniform4f( SHADER_UNIFORM( shader_sdf, "uColour" ), 1.0f, 1.0f, 1.0f, 1.0f );
+ glDrawElements( GL_TRIANGLES, text_buffers.title_count*6, GL_UNSIGNED_SHORT, (void*)( text_buffers.title_start*6*sizeof(u16) ) );
+ glDrawElements( GL_TRIANGLES, text_buffers.desc_count*6, GL_UNSIGNED_SHORT, (void*)( text_buffers.desc_start*6*sizeof(u16) ) );
+
+ glUniform4f( SHADER_UNIFORM( shader_sdf, "uColour" ), 1.0f, 1.0f, 1.0f, 0.17f );
+ glDrawElements( GL_TRIANGLES, text_buffers.grid_count*6, GL_UNSIGNED_SHORT, (void*)( text_buffers.grid_start*6*sizeof(u16) ) );