X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=bb3c98a4157fcc02dedcb6e15c6c2c57de943e8c;hb=cc51e344cfe81fe418d44fcfa91e55bb1b4f89d0;hp=e671208e560f6c6558f04c061d84ee72ab7bf3b2;hpb=7d33b1d4576c1e35cd03ee3034840b8053914ae1;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index e671208..bb3c98a 100644 --- a/fishladder.c +++ b/fishladder.c @@ -14,10 +14,9 @@ enum world_button_mode struct world_button { v2i position; - v3f colour; - float light_target, light; - int state, click_grab; + float light_target, light, extra_light; + int state; enum world_button_mode mode; }; @@ -62,7 +61,8 @@ enum e_world_button k_world_button_none = -1, k_world_button_sim = 0, k_world_button_pause = 1, - k_world_button_speedy = 2 + k_world_button_speedy = 2, + k_world_button_settings = 3 }; #define FLAG_CANAL 0x1 @@ -192,21 +192,10 @@ struct world_static world_static = { .buttons = { - { - .colour = { 0.204f, 0.345f, 0.553f }, - .mode = k_world_button_mode_toggle - }, - { - .colour = { 0.204f, 0.345f, 0.553f }, - .mode = k_world_button_mode_toggle - }, - { - .colour = { 0.553f, 0.345f, 0.204f }, - .mode = k_world_button_mode_toggle - }, - { - // TODO: Settings button and menu - } + { .mode = k_world_button_mode_toggle }, + { .mode = k_world_button_mode_toggle }, + { .mode = k_world_button_mode_toggle }, + { .mode = k_world_button_mode_toggle } } }; @@ -940,13 +929,21 @@ static int map_load( const char *str, const char *name ) for( int i = 0; i < vg_list_size( career_packs ); i ++ ) { struct career_level_pack *grid = &career_packs[ i ]; - + + int j = 0; + for( int y = 0; y < grid->dims[1]; y ++ ) { for( int x = 0; x < grid->dims[0]; x ++ ) { u8 *px = &info_buffer[((y+16+grid->origin[1])*64+16+x+grid->origin[0])*4]; px[0] = 0x10; + + if( j < grid->count ) + { + struct cmp_level *lvl = &grid->pack[ j ++ ]; + v2i_add( grid->origin, (v2i){x,y}, lvl->btn.position ); + } } } } @@ -1464,7 +1461,7 @@ static int cell_interactive( v2i co ) return 1; } -void vg_update(void) +static void vg_update(void) { // Camera // ======================================================================================================== @@ -1475,17 +1472,29 @@ void vg_update(void) static float size_current = 2.0f; static v3f origin_current = { 0.0f, 0.0f, 0.0f }; + static v2f drag_offset = { 0.0f, 0.0f }; + static v2f view_point = { 0.0f, 0.0f }; + v2f result_view; + static float view_zoom_extra = 0.0f; + + size = ( r2 < r1? (float)(world.w+5) * 0.5f: ((float)(world.h+5) * 0.5f) / r1 ) + 0.5f; - size = ( r2 < r1? (float)(world.w+5) * 0.5f: ((float)(world.h+5) * 0.5f) / r1 ) + 0.5f; - - v3f origin; + v2f origin; + v2f vt_target; + origin[0] = floorf( -0.5f * ((float)world.w-4.5f) ); origin[1] = floorf( -0.5f * world.h ); - origin[2] = 0.0f; + // Create and clamp result view + v2_add( view_point, drag_offset, result_view ); + result_view[0] = vg_clampf( result_view[0], -view_zoom_extra, view_zoom_extra ); + result_view[1] = vg_clampf( result_view[1], -view_zoom_extra*r1, view_zoom_extra*r1 ); + + v2_add( origin, result_view, vt_target ); + // Lerp towards target - size_current = vg_lerpf( size_current, size, vg_time_delta * 6.0f ); - v2_lerp( origin_current, origin, vg_time_delta * 6.0f, origin_current ); + size_current = vg_lerpf( size_current, size - view_zoom_extra, vg_time_delta * 6.0f ); + v2_lerp( origin_current, vt_target, vg_time_delta * 6.0f, origin_current ); m3x3_projection( m_projection, -size_current, size_current, -size_current*r1, size_current*r1 ); m3x3_identity( m_view ); @@ -1500,6 +1509,82 @@ void vg_update(void) world.tile_x = floorf( world.tile_pos[0] ); world.tile_y = floorf( world.tile_pos[1] ); + // Camera dragging + static v2f drag_origin; // x/y pixel + + if( vg_get_button_down( "tertiary" ) ) + v2_copy( vg_mouse, drag_origin ); + else if( vg_get_button( "tertiary" ) ) + { + // get offset + v2_sub( vg_mouse, drag_origin, drag_offset ); + v2_div( drag_offset, (v2f){ vg_window_x, vg_window_y }, drag_offset ); + v2_mul( drag_offset, (v2f){ size_current*2.0f, -size_current*r1*2.0f }, drag_offset ); + } + else + { + v2_copy( result_view, view_point ); + v2_copy( (v2f){0.0f,0.0f}, drag_offset ); + } + + // calculate relative position of mouse in view_point space + + { // Debug + v2f lwr; v2f upr; + v2f lwr1; v2f upr1; + v2f p0; v2f p1; + v2f vo; + v2f mouse_viewspace; + + float rsize = size-view_zoom_extra; + + v2_sub( (v2f){ -size + 0.1f, -size*r1 + 0.1f }, origin, lwr ); + v2_sub( (v2f){ size - 0.1f, size*r1 - 0.1f }, origin, upr ); + + v2_sub( (v2f){ -rsize, -rsize*r1 }, vt_target, lwr1 ); + v2_sub( (v2f){ rsize, rsize*r1 }, vt_target, upr1 ); + + vg_line_box( lwr, upr, 0xffffff00 ); + vg_line_box( lwr1, upr1, 0xff00ff00 ); + + // Calculate vector towards mouse from vt_target + v2f mouse_delta; + v2_muls( vt_target, -1.0f, vo ); + + v2_sub( vt_target, vg_mouse_ws, mouse_delta ); + + vg_line( vo, vg_mouse_ws, 0xffffffff ); + + // Mouse Locally + v2_div( vg_mouse, (v2f){ vg_window_x, vg_window_y }, mouse_viewspace ); + mouse_viewspace[0] = mouse_viewspace[0]*rsize*2.0f; + mouse_viewspace[1] = (1.0f-mouse_viewspace[1])*rsize*2.0f*r1; + + v2_add( lwr1, mouse_viewspace, mouse_viewspace ); + + vg_line( mouse_viewspace, (v2f){0.0f, 0.0f}, 0xff0000ff ); + //} + + // Zoom + view_zoom_extra = vg_clampf( view_zoom_extra + vg_mouse_wheel[1], 0.0f, size - 4.0f ); + + // Zoom offset adjust + rsize = size-view_zoom_extra; + v2_sub( (v2f){ -rsize, -rsize*r1 }, vt_target, lwr1 ); + v2_sub( (v2f){ rsize, rsize*r1 }, vt_target, upr1 ); + + v2f mouse_viewspace_new; + v2_div( vg_mouse, (v2f){ vg_window_x, vg_window_y }, mouse_viewspace_new ); + mouse_viewspace_new[0] = mouse_viewspace_new[0]*rsize*2.0f; + mouse_viewspace_new[1] = (1.0f-mouse_viewspace_new[1])*rsize*2.0f*r1; + + v2_add( lwr1, mouse_viewspace_new, mouse_viewspace_new ); + + v2f zoom_offset; + v2_sub( mouse_viewspace, mouse_viewspace_new, zoom_offset ); + v2_muladds( view_point, zoom_offset, -1.0f, view_point ); + } + // Tilemap // ======================================================================================================== if( !is_simulation_running() && !gui_want_mouse() ) @@ -2206,10 +2291,22 @@ static void render_tiles( v2i start, v2i end, v4f const regular_colour, v4f cons } } -static int world_button_exec( struct world_button *btn, v2f texture, enum world_button_status *status ) +static int world_button_exec( struct world_button *btn, v2f texture, v3f colour, enum world_button_status *status ) { + static v2i click_grab = { -9999, -9999 }; + + // Reset click_grab + if( !btn ) + { + click_grab[0] = -9999; + click_grab[1] = -9999; + return 0; + } + + v2i click_tile = { world.tile_x, world.tile_y }; + int triggered = 0; - int is_hovering = v2i_eq( (v2i){ world.tile_x, world.tile_y }, btn->position ); + int is_hovering = v2i_eq( click_tile, btn->position ); // Set up light targets before logic runs if( btn->state ) @@ -2224,10 +2321,8 @@ static int world_button_exec( struct world_button *btn, v2f texture, enum world_ if( is_hovering ) { if( vg_get_button_down( "primary" ) && is_hovering ) - { - btn->click_grab = 1; - } - else if( btn->click_grab && vg_get_button_up( "primary" ) ) + v2i_copy( click_tile, click_grab ); + else if( v2i_eq( click_grab, click_tile ) && vg_get_button_up( "primary" ) ) { // Click event *status = btn->state? k_world_button_on_disable: k_world_button_on_enable; @@ -2239,15 +2334,13 @@ static int world_button_exec( struct world_button *btn, v2f texture, enum world_ triggered = 1; } } - if( vg_get_button_up( "primary" ) ) - btn->click_grab = 0; // Drawing stage v4f final_colour; - btn->light = vg_lerpf( btn->light, btn->light_target, vg_time_delta*26.0f ); + btn->light = vg_lerpf( btn->light, btn->light_target + btn->extra_light, vg_time_delta*26.0f ); - v3_copy( btn->colour, final_colour ); + v3_copy( colour, final_colour ); final_colour[3] = btn->light; glUniform4f( SHADER_UNIFORM( shader_buttons, "uOffset" ), @@ -2402,84 +2495,34 @@ static void level_selection_buttons(void) { v3f tutorial_colour = { 0.204f, 0.345f, 0.553f }; v3f locked_colour = { 0.2f, 0.2f, 0.2f }; - - v4f final_colour = { 0.0f, 0.0f, 0.0f, 0.2f }; - v2i button_pos; - static struct cmp_level *select_from = NULL; + struct cmp_level *switch_level_to = NULL; - - if( vg_get_button_down( "primary" ) ) - select_from = NULL; - + for( int i = 0; i < vg_list_size( career_packs ); i ++ ) { struct career_level_pack *grid = &career_packs[i]; - int j = 0; - - for( int x = 0; x < grid->dims[0]; x ++ ) + for( int j = 0; j < grid->count; j ++ ) { - for( int y = 0; y < grid->dims[1]; y ++ ) - { - if( j < grid->count ) - { - struct cmp_level *lvl = &grid->pack[ j ]; - - // Determine colour - if( lvl->unlocked ) - { - if( lvl->is_tutorial ) - v3_copy( tutorial_colour, final_colour ); - else - v3_copy( grid->primary_colour, final_colour ); - - if( lvl->completed_score ) - final_colour[3] = 0.8f; - else - final_colour[3] = 0.2f; - } - else - { - v3_copy( locked_colour, final_colour ); - final_colour[3] = 0.2f; - } - - v2i_add( grid->origin, (v2i){ x,y }, button_pos ); - int is_hovering = v2i_eq( (v2i){world.tile_x, world.tile_y}, button_pos ); + struct cmp_level *lvl = &grid->pack[ j ]; - if( is_hovering ) - { - final_colour[3] += 0.1f; - - // Up click - if( vg_get_button_up( "primary" ) ) - if( select_from == lvl && lvl->unlocked ) - { - switch_level_to = lvl; - sfx_set_play( &audio_clicks, &audio_system_ui, 1 ); - } - - // Start click - if( vg_get_button_down( "primary" ) ) - select_from = lvl; - - if( vg_get_button( "primary" ) ) - final_colour[3] += 0.2f; - } - - if( world.pCmpLevel == lvl ) - { - final_colour[3] += 0.15f + fabsf(sinf( vg_time * 2.0f )) * 0.05f; - - if( lvl->completed_score ) - final_colour[3] += 0.1f; - } - - //wbutton_draw( (v2i){ grid->origin[0] + x, grid->origin[1] + y }, tex_coord, final_colour ); - } - else break; - - j ++; + if( world.pCmpLevel == lvl ) + lvl->btn.extra_light = 0.35f + fabsf(sinf( vg_time * 2.0f )) * 0.05f; + else lvl->btn.extra_light = 0.2f; + + if( lvl->completed_score ) + lvl->btn.extra_light += 0.8f; + + enum world_button_status status; + if( world_button_exec( + &lvl->btn, + (v2f){0.0f,0.0f}, + lvl->unlocked? (lvl->is_tutorial? tutorial_colour: grid->primary_colour): locked_colour, + &status + )) + { + if( status == k_world_button_on_enable && lvl->unlocked ) + switch_level_to = lvl; } } } @@ -2702,7 +2745,10 @@ void vg_render(void) float sim_icon_x = world_paused? 3.0f: (world_running? 2.0f: 0.0f); - if( world_button_exec( &world_static.buttons[k_world_button_sim], (v2f){ sim_icon_x, 3.0f }, &stat )) + v3f btn_dark_blue = { 0.204f, 0.345f, 0.553f }; + v3f btn_orange = { 0.553f, 0.345f, 0.204f }; + + if( world_button_exec( &world_static.buttons[k_world_button_sim], (v2f){ sim_icon_x, 3.0f }, btn_dark_blue, &stat )) { if( stat == k_world_button_on_enable ) { @@ -2726,7 +2772,7 @@ void vg_render(void) } } - if( world_button_exec( &world_static.buttons[k_world_button_pause], (v2f){ 1.0f, 3.0f }, &stat )) + if( world_button_exec( &world_static.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; @@ -2740,7 +2786,7 @@ void vg_render(void) world.pause_offset_target = 0.0f; } - if( world_button_exec( &world_static.buttons[k_world_button_speedy], (v2f){ 0.0f, 2.0f }, &stat )) + if( world_button_exec( &world_static.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; @@ -2751,8 +2797,16 @@ void vg_render(void) } } + if( world_button_exec( &world_static.buttons[k_world_button_settings], (v2f){ 1.0f, 2.0f }, btn_orange, &stat )) + { + + } + level_selection_buttons(); + if( vg_get_button_up( "primary" ) ) + world_button_exec( NULL, NULL, NULL, NULL ); + // TEXT ELEMENTS // ======================================================================================================== SHADER_USE( shader_sdf ); @@ -3393,7 +3447,7 @@ void vg_start(void) } resource_load_main(); - + // Create text buffers { // Work out the counts for each 'segment'