X-Git-Url: https://harrygodden.com/git/?p=fishladder.git;a=blobdiff_plain;f=fishladder.c;h=5ad95d6844efef42a71a8c8d2e0e4ec6fb54732e;hp=89bc1d8432c2b63eaaf7fa205244ec91d0d486e8;hb=bd3188f0fe52c9231f79af85d6cfaef2576b9f83;hpb=a36c7a3bddb23de2276f844d94dfd20227b68093 diff --git a/fishladder.c b/fishladder.c index 89bc1d8..5ad95d6 100644 --- a/fishladder.c +++ b/fishladder.c @@ -10,13 +10,12 @@ SHADER_DEFINE( colour_shader, // VERTEX "layout (location=0) in vec2 a_co;" - "uniform mat4 uPv;" - "uniform mat4 uMdl;" + "uniform mat3 uPv;" + "uniform mat3 uMdl;" "" "void main()" "{" - " vec4 vert_pos = uPv * uMdl * vec4( a_co.x, 0.0, a_co.y, 1.0 );" - " gl_Position = vert_pos;" + " gl_Position = vec4( uPv * uMdl * vec3( a_co, 1.0 ), 1.0 );" "}", // FRAGMENT @@ -37,7 +36,7 @@ SHADER_DEFINE( tilemap_shader, "layout (location=0) in vec2 a_co;" // XY "layout (location=1) in vec2 a_offset;" // XY offset "layout (location=2) in vec4 a_data;" // atlas-uv, amt, other - "uniform mat4 uPv;" + "uniform mat3 uPv;" "uniform vec2 uOrigin;" "" "out vec4 aCoords;" @@ -45,8 +44,8 @@ SHADER_DEFINE( tilemap_shader, "void main()" "{" "vec2 world_coord = a_co+a_offset+uOrigin;" - "gl_Position = uPv * vec4( world_coord.x, 0.0, world_coord.y, 1.0 );" - "aCoords = vec4((a_co*0.98+0.01 + vec2(a_data.x,0.0)) * 0.0625, a_data.zw);" + "gl_Position = vec4( uPv * vec3( world_coord, 1.0 ), 1.0 );" + "aCoords = vec4( (a_co*0.98+0.01 + vec2(a_data.x,0.0)) * 0.0625, a_data.zw );" "}", // FRAGMENT @@ -63,7 +62,10 @@ SHADER_DEFINE( tilemap_shader, "vec4 ripple = texture( uTexRipples, vec2( glyph.x - uTime, glyph.y ));" "float wstatus = -((aCoords.z/128.0)-1.0);" // -1 := None in, 0.0 := Hold middle, 1.0 := All out "float dev = step( 0.0, glyph.x+wstatus ) * step( glyph.x+wstatus, 1.0 );" //+ abs(glyph.y-0.5) );" - "vec3 composite = mix( vec3(0.5,0.5,0.5), vec3(0.3,0.6,1.0) + ripple.xyz * 0.05, step( 0.75, glyph.a )*dev ) * glyph.z;" + + // TODO: Fix texture instead of doing this.. + "float shadow = mix( 1.0, glyph.z, step(0.25, glyph.w) );" + "vec3 composite = mix( vec3(0.5,0.5,0.5), vec3(0.3,0.6,1.0) + ripple.xyz * 0.05, step( 0.75, glyph.a )*dev ) * shadow;" "FragColor = vec4( composite, 1.0 );" "}" , @@ -74,7 +76,7 @@ SHADER_DEFINE( fish_shader, // VERTEX "layout (location=0) in vec2 a_co;" // XY UV - "uniform mat4 uPv;" + "uniform mat3 uPv;" "uniform vec3 uPosition;" "out vec2 aTexCoords;" @@ -82,7 +84,7 @@ SHADER_DEFINE( fish_shader, "void main()" "{" "vec2 world_coord = a_co + uPosition.xy;" - "gl_Position = uPv * vec4( world_coord.x, 0.0, world_coord.y, 1.0 );" + "gl_Position = vec4( uPv * vec3( world_coord, 1.0 ), 1.0 );" "aTexCoords = vec2( (a_co.x + uPosition.z) * 0.125, a_co.y );" "}", // FRAGMENT @@ -101,9 +103,9 @@ SHADER_DEFINE( fish_shader, UNIFORMS({ "uPv", "uTexMain", "uColour", "uPosition" }) ) -mat4 m_projection; -mat4 m_view; -mat4 m_mdl; +m3x3f m_projection; +m3x3f m_view; +m3x3f m_mdl; int main( int argc, char *argv[] ) { @@ -151,7 +153,7 @@ static struct fishes[ 20 ]; int num_fishes; - vec3 origin; + v2f origin; struct cell *selected; int select_valid; int playing; @@ -196,21 +198,21 @@ static void map_free(void) map.io = NULL; } -static struct cell *map_tile( int pos[2] ) +static struct cell *ptile( int pos[2] ) { return map.cells + pos[1]*map.x + pos[0]; } -static struct cell *map_tile_at( int pos[2] ) +static struct cell *gettile( int pos[2] ) { if( pos[0] >= 0 && pos[0] < map.x && pos[1] >= 0 && pos[1] < map.y ) return map.cells + pos[1]*map.x + pos[0]; return NULL; } -static struct cell *map_tile_at_cond( int pos[2], u32 flags ) +static struct cell *getiftile( int pos[2], u32 flags ) { - struct cell *cell = map_tile_at( pos ); + struct cell *cell = gettile( pos ); if( cell && (cell->flags & flags) ) return cell; @@ -250,7 +252,7 @@ static struct cell *map_stack_next(void) if( frame->i < 3 ) { int *dir = output_dirs[ frame->i ]; - tile = map_tile_at_cond( (int[2]){frame->x+dir[0], frame->y+dir[1]}, CELL_FLAG_WALKABLE ); + tile = getiftile( (int[2]){frame->x+dir[0], frame->y+dir[1]}, CELL_FLAG_WALKABLE ); if( tile && !(tile->flags & CELL_FLAG_VISITED) ) { @@ -318,10 +320,10 @@ static void map_update_visual(void) { struct cell *a, *b, *c, *d; - a = map_tile_at_cond( (int[2]){ x,y+1 }, CELL_FLAG_WALKABLE ); - b = map_tile_at_cond( (int[2]){ x+1,y }, CELL_FLAG_WALKABLE ); - c = map_tile_at_cond( (int[2]){ x,y-1 }, CELL_FLAG_WALKABLE ); - d = map_tile_at_cond( (int[2]){ x-1,y }, CELL_FLAG_WALKABLE ); + a = getiftile( (int[2]){ x,y+1 }, CELL_FLAG_WALKABLE ); + b = getiftile( (int[2]){ x+1,y }, CELL_FLAG_WALKABLE ); + c = getiftile( (int[2]){ x,y-1 }, CELL_FLAG_WALKABLE ); + d = getiftile( (int[2]){ x-1,y }, CELL_FLAG_WALKABLE ); u32 config = (a?0x1:0x0) | (b?0x2:0x0) | (c?0x4:0x0) | (d?0x8:0x0); cellbytes[ 0 ] = config; @@ -347,7 +349,7 @@ static void map_update_visual(void) { map_tile_coords_from_index( map.io[i], inputcoord ); map_stack_init( inputcoord ); - struct cell *cell = map_tile_at( inputcoord ); + struct cell *cell = gettile( inputcoord ); int cr[2]; @@ -362,9 +364,9 @@ static void map_update_visual(void) int outrate = outflow == 128? k_rate_flow: 0; struct cell *a, *b, *d; - a = map_tile( (int[2]){ cr[0], cr[1]+1 } ); - b = map_tile( (int[2]){ cr[0]+1, cr[1] } ); - d = map_tile( (int[2]){ cr[0]-1, cr[1] } ); + a = gettile( (int[2]){ cr[0], cr[1]+1 } ); + b = gettile( (int[2]){ cr[0]+1, cr[1] } ); + d = gettile( (int[2]){ cr[0]-1, cr[1] } ); int compute_l = 0, compute_r = 0; @@ -423,7 +425,7 @@ static int map_load( const char *str ) { map_free(); - char *c = str; + char const *c = str; // Scan for width for(;; map.x ++) @@ -538,7 +540,7 @@ static int map_load( const char *str ) // Origin top left corner map.origin[0] = -((float)map.x) * 0.5f; - map.origin[2] = -((float)map.y) * 0.5f; + map.origin[1] = -((float)map.y) * 0.5f; float *offset_array = (float *)malloc( map.x*map.y*2*sizeof(float) ); @@ -560,34 +562,24 @@ static int map_load( const char *str ) return 1; } +// Determines if tile at position co is contentious static int map_tile_availible( int co[2] ) { - // Extract 5x5 grid surrounding tile + // Extract tiles area of influence as a 5x5 grid in bitfield format u32 blob = 0x1000; for( int y = vg_max( co[1]-2, 0 ); y < vg_min( map.y, co[1]+3 ); y ++ ) for( int x = vg_max( co[0]-2, 0 ); x < vg_min( map.x, co[0]+3 ); x ++ ) - { - struct cell *cell = map_tile( (int[2]){ x, y } ); - - if( cell && (cell->flags & CELL_FLAG_WALKABLE) ) + if( getiftile( (int[2]){ x, y }, CELL_FLAG_WALKABLE ) ) blob |= 0x1 << ((y-(co[1]-2))*5 + x-(co[0]-2)); - } // Run filter over center 3x3 grid to check for invalid configurations + // The kernel codes both the offsets for reaching each tile inside it, as well as the offsets + // to move the kernel as a whole. int kernel[] = { 0, 1, 2, 5, 6, 7, 10, 11, 12 }; for( int i = 0; i < vg_list_size(kernel); i ++ ) - { if( blob & (0x1 << (6+kernel[i])) ) { - // (reference window: 0x1CE7) Illegal moves - // 0100011100010 ; - // 0000001100011 ; - // 0000011000110 ; - // 0110001100000 ; - // 1100011000000 ; - // 0100001100010 ; - // 0100011000010 ; - + // Illegal moves list in bitfield format u32 invalid[] = { 0x8E2, 0x63, 0xC6, 0xC60, 0x18C0, 0x862, 0x8C2 }; u32 window = blob >> kernel[i]; @@ -595,7 +587,6 @@ static int map_tile_availible( int co[2] ) if((window & invalid[j]) == invalid[j]) return 0; } - } return 1; } @@ -605,13 +596,11 @@ void vg_update(void) // Update camera float ratio = (float)vg_window_y / (float)vg_window_x; float const size = 7.5f; - glm_ortho( -size, size, -size*ratio, size*ratio, 0.01f, 150.f, m_projection ); - - glm_mat4_identity( m_view ); - glm_translate_z( m_view, -10.f ); - glm_rotate_x( m_view, 1.5708f, m_view ); - glm_mat4_mul( m_projection, m_view, vg_pv ); + m3x3_projection( m_projection, -size, size, size*ratio, -size*ratio ); + m3x3_identity( m_view ); + m3x3_mul( m_projection, m_view, vg_pv ); + vg_projection_update(); // Compute map update for( int y = 0; y < map.y; y ++ ) @@ -619,18 +608,18 @@ void vg_update(void) for( int x = 0; x < map.x; x ++ ) { struct cell *tile, *upper, *lower, *l, *r; - tile = map_tile_at( (int [2]){ x, y } ); + tile = gettile( (int [2]){ x, y } ); tile->flags &= ~(CELL_FLAG_SPLIT|CELL_FLAG_MERGE|CELL_FLAG_UPLVL); if( tile->flags & CELL_FLAG_WALKABLE ) { - r = map_tile_at_cond( (int[2]){ x+1, y }, CELL_FLAG_WALKABLE ); - l = map_tile_at_cond( (int[2]){ x-1, y }, CELL_FLAG_WALKABLE ); + r = getiftile( (int[2]){ x+1, y }, CELL_FLAG_WALKABLE ); + l = getiftile( (int[2]){ x-1, y }, CELL_FLAG_WALKABLE ); if( r && l ) { - upper = map_tile_at_cond( (int[2]){ x, y-1 }, CELL_FLAG_WALKABLE ); - lower = map_tile_at_cond( (int[2]){ x, y+1 }, CELL_FLAG_WALKABLE ); + upper = getiftile( (int[2]){ x, y-1 }, CELL_FLAG_WALKABLE ); + lower = getiftile( (int[2]){ x, y+1 }, CELL_FLAG_WALKABLE ); if( upper ) { @@ -647,170 +636,21 @@ void vg_update(void) } } } - - // Compute classification - /* - map_stack_refresh(); - - for( int i = 0; i < arrlen( map.io ); i ++ ) - { - struct *cell cell = &map.cells[ map.io ]; - int coords[2]; - if( cell->flags & CELL_FLAG_INPUT ) - { - map_tile_coords_from_index( map.io, coords ); - map_stack_init( coords ); - - do - { - if( cell->flags & CELL_FLAG_CONNECTOR ) - { - - } - } - while( (cell = map_stack_next()) ); - } - }*/ - - // Get mouse ray - vec3 ray_origin; - vec3 ray_dir; - - mat4 pv_inverse; - vec4 vp = { 0.f, 0.f, vg_window_x, vg_window_y }; - glm_mat4_inv( vg_pv, pv_inverse ); - glm_unprojecti( (vec3){ vg_mouse_x, vg_window_y-vg_mouse_y, -1.f }, pv_inverse, vp, ray_dir ); - glm_unprojecti( (vec3){ vg_mouse_x, vg_window_y-vg_mouse_y, 0.f }, pv_inverse, vp, ray_origin ); - glm_vec3_sub( ray_dir, ray_origin, ray_dir ); - - // Get floor tile intersection - float ray_t = -ray_origin[1] / ray_dir[1]; - - vec3 tile_pos; - glm_vec3_copy( ray_origin, tile_pos ); - glm_vec3_muladds( ray_dir, ray_t, tile_pos ); - glm_vec3_sub( tile_pos, map.origin, tile_pos ); + v2f tile_pos; + v2_copy( vg_mouse_ws, tile_pos ); + v2_sub( tile_pos, map.origin, tile_pos ); int tile_x = floorf( tile_pos[0] ); - int tile_y = floorf( tile_pos[2] ); + int tile_y = floorf( tile_pos[1] ); - map.selected = map_tile_at( (int [2]){tile_x, tile_y} ); + map.selected = ptile( (int [2]){tile_x, tile_y} ); if( map.playing ) { - static int fish_counter = 0; - fish_counter ++; - - if( fish_counter > 20 ) - { - fish_counter = 0; - - // Advance characters - for( int i = 0; i < map.num_fishes; i ++ ) - { - struct fish *fish = map.fishes + i; - - if( !fish->alive ) - continue; - - struct cell *tile, *next; - tile = map_tile_at( fish->co ); - - if( tile->flags & CELL_FLAG_OUTPUT ) - { - vg_info( "Fish got zucced (%d)\n", i ); - fish->alive = 0; - continue; - } - - int die = 0; - if( tile->flags & CELL_FLAG_SPLIT ) - { - die = 1; - int new_dir[][2] = { {0,-1},{1,0},{-1,0} }; - int *test_dir; - - for( int j = 0; j < 3; j ++ ) - { - test_dir = new_dir[ tile->state ]; - tile->state = (tile->state+1)%3; - - next = map_tile_at( (int[2]){ fish->co[0]+test_dir[0], fish->co[1]+test_dir[1] } ); - if( next && (next->flags & (CELL_FLAG_WALKABLE)) ) - { - fish->dir[0] = test_dir[0]; - fish->dir[1] = test_dir[1]; - die = 0; - break; - } - } - } - - next = map_tile_at( (int[2]){ fish->co[0]+fish->dir[0], fish->co[1]+fish->dir[1] } ); - if( !next || (next && !(next->flags & CELL_FLAG_WALKABLE)) ) - { - // Try UP - die = 1; - } - - if( die ) - { - vg_info( "Fish died! (%d)\n", i ); - fish->alive = 0; - continue; - } - - - fish->co[0] += fish->dir[0]; - fish->co[1] += fish->dir[1]; - } - - // Try spawn fish - for( int i = 0; i < arrlen( map.io ); i ++ ) - { - struct cell *input = &map.cells[ map.io[i] ]; - - if( input->flags & CELL_FLAG_INPUT ) - { - if( input->state < arrlen( input->conditions ) ) - { - struct fish *fish = &map.fishes[ map.num_fishes ]; - map_tile_coords_from_index( map.io[i], fish->co ); - - int output_dirs[][2] = { {0,-1}, {-1,0}, {1,0} }; - int can_spawn = 0; - - for( int i = 0; i < vg_list_size( output_dirs ); i ++ ) - { - int *dir = output_dirs[i]; - struct cell *next = map_tile_at( (int[2]){ fish->co[0]+dir[0], fish->co[1]+dir[1] } ); - if( next && next->flags & CELL_FLAG_CANAL ) - { - fish->dir[0] = dir[0]; - fish->dir[1] = dir[1]; - can_spawn = 1; - } - } - - if( can_spawn ) - { - fish->alive = 1; - input->state ++; - map.num_fishes ++; - } - } - } - } - - vg_info( "There are now %u active fish\n", map.num_fishes ); - } - if( vg_get_button_down( "go" ) ) { map.playing = 0; - map.num_fishes = 0; - vg_info( "Ending!\n" ); } } @@ -819,11 +659,6 @@ void vg_update(void) if( vg_get_button_down( "go" ) ) { map.playing = 1; - - // Reset everything - for( int i = 0; i < map.x*map.y; i ++ ) - map.cells[ i ].state = 0; - vg_info( "Starting!\n" ); } @@ -866,7 +701,7 @@ void vg_render(void) map_update_visual(); SHADER_USE( tilemap_shader ); - glUniformMatrix4fv( SHADER_UNIFORM( tilemap_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); + glUniformMatrix3fv( SHADER_UNIFORM( tilemap_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); glUniform1i( SHADER_UNIFORM( tilemap_shader, "uTexTiles" ), 0 ); glActiveTexture( GL_TEXTURE0 ); @@ -876,13 +711,14 @@ void vg_render(void) glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, map.flow_texture ); - glUniform2f( SHADER_UNIFORM( tilemap_shader, "uOrigin" ), map.origin[0], map.origin[2] ); + glUniform2fv( SHADER_UNIFORM( tilemap_shader, "uOrigin" ), 1, map.origin ); glUniform1f( SHADER_UNIFORM( tilemap_shader, "uTime" ), vg_time * 0.5f ); glDrawArraysInstanced( GL_TRIANGLES, 0, 6, map.x*map.y ); + /* SHADER_USE( fish_shader ); - glUniformMatrix4fv( SHADER_UNIFORM( fish_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); + glUniformMatrix3fv( SHADER_UNIFORM( fish_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); glUniform1i( SHADER_UNIFORM( fish_shader, "uTexMain" ), 0 ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, fish_texture ); @@ -896,6 +732,7 @@ void vg_render(void) glDrawArrays( GL_TRIANGLES, 0, 6 ); glDisable( GL_BLEND ); + */ } void vg_register(void)