X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=d66cd2e18780b27eb48890130eeade53a7b0b04c;hb=27f1751d523e9dee4ab00ec10666bbb3d8db74bc;hp=c928a816437a9342f5246cf7b1eb254aa8424180;hpb=4f304e68ef414a6daf4cc4a8cc9bb9d79aa892e0;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index c928a81..d66cd2e 100644 --- a/fishladder.c +++ b/fishladder.c @@ -27,6 +27,64 @@ SHADER_DEFINE( shader_tile_colour, UNIFORMS({ "uPv", "uOffset", "uColour" }) ) +const char *level_pack[] = +{ + // 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" +}; + m3x3f m_projection; m3x3f m_view; m3x3f m_mdl; @@ -62,6 +120,44 @@ static void colour_code_v3( char cc, v3f target ) v3_copy( (v3f){0.0f,0.0f,0.0f}, target ); } +struct mesh +{ + GLuint vao, vbo; + u32 elements; +}; + +static void init_mesh( struct mesh *m, float *tris, u32 length ) +{ + m->elements = length/3; + glGenVertexArrays( 1, &m->vao ); + glGenBuffers( 1, &m->vbo ); + + glBindVertexArray( m->vao ); + glBindBuffer( GL_ARRAY_BUFFER, m->vbo ); + glBufferData( GL_ARRAY_BUFFER, length*sizeof(float), tris, GL_STATIC_DRAW ); + + glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0 ); + glEnableVertexAttribArray( 0 ); + + VG_CHECK_GL(); +} + +static void free_mesh( struct mesh *m ) +{ + glDeleteVertexArrays( 1, &m->vao ); + glDeleteBuffers( 1, &m->vbo ); +} + +static void draw_mesh( int const start, int const count ) +{ + glDrawArrays( GL_TRIANGLES, start*3, count*3 ); +} + +static void use_mesh( struct mesh *m ) +{ + glBindVertexArray( m->vao ); +} + struct world { struct cell @@ -89,10 +185,7 @@ struct world u32 w, h; - GLuint tile_vao; - GLuint tile_vbo; - GLuint circle_vao; - GLuint circle_vbo; + struct mesh tile, circle, splitter_l, splitter_r; int selected; @@ -249,7 +342,7 @@ static struct cell *pcell( v2i pos ) int main( int argc, char *argv[] ) { - vg_init( argc, argv, "FishLadder" ); + vg_init( argc, argv, "Fish (Marbles Computer) Ladder Simulator 2022 | N,M: change level | SPACE: Test | LeftClick: Toggle tile" ); } void vg_register(void) @@ -261,9 +354,6 @@ void vg_start(void) { // Quad mesh { - glGenVertexArrays( 1, &world.tile_vao ); - glGenBuffers( 1, &world.tile_vbo ); - float quad_mesh[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, @@ -276,27 +366,11 @@ void vg_start(void) 0.75f, 0.375f, 0.25f, 0.5f, 0.75f, 0.625f }; - glBindVertexArray( world.tile_vao ); - glBindBuffer( GL_ARRAY_BUFFER, world.tile_vbo ); - glBufferData - ( - GL_ARRAY_BUFFER, - sizeof( quad_mesh ), - quad_mesh, - GL_STATIC_DRAW - ); - - glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0 ); - glEnableVertexAttribArray( 0 ); - - VG_CHECK_GL(); + init_mesh( &world.tile, quad_mesh, vg_list_size(quad_mesh) ); } // Circle mesh { - glGenVertexArrays( 1, &world.circle_vao ); - glGenBuffers( 1, &world.circle_vbo ); - float circle_mesh[32*6*3]; int res = vg_list_size( circle_mesh ) / (6*3); @@ -322,38 +396,33 @@ void vg_start(void) v2_copy( v1, circle_mesh+i*6+2 ); } - glBindVertexArray( world.circle_vao ); - glBindBuffer( GL_ARRAY_BUFFER, world.circle_vbo ); - glBufferData( GL_ARRAY_BUFFER, sizeof( circle_mesh ), circle_mesh, GL_STATIC_DRAW ); - - glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0 ); - glEnableVertexAttribArray( 0 ); + init_mesh( &world.circle, circle_mesh, vg_list_size( circle_mesh ) ); + } + + // splitters (temp) + { + float splitter_l[] = + { + #include "models/splitter_l.obj.h" + }; + float splitter_r[] = + { + #include "models/splitter_r.obj.h" + }; - VG_CHECK_GL(); + init_mesh( &world.splitter_l, splitter_l, vg_list_size( splitter_l ) ); + init_mesh( &world.splitter_r, splitter_r, vg_list_size( splitter_r ) ); } - map_load - ( - "#############;\n" - "###-#####-###;aaa,aa\n" - "## ##;\n" - "## ##;\n" - "## ##;\n" - "## ##;\n" - "## ##;\n" - "## ##;\n" - "###+#####+###;aa,aaa\n" - "#############;\n" - ); + map_load( level_pack[ 0 ] ); } void vg_free(void) { - glDeleteVertexArrays( 1, &world.tile_vao ); - glDeleteBuffers( 1, &world.tile_vbo ); - - glDeleteVertexArrays( 1, &world.circle_vao ); - glDeleteBuffers( 1, &world.circle_vbo ); + free_mesh( &world.tile ); + free_mesh( &world.circle ); + free_mesh( &world.splitter_l ); + free_mesh( &world.splitter_r ); map_free(); } @@ -445,6 +514,27 @@ static int cell_interactive( v2i co ) 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 ++; } + + if( changelvl != curlevel ) + { + map_load( level_pack[ changelvl ] ); + curlevel = changelvl; + + // TEMP!!! code dupe + world.simulating = 0; + world.num_fishes = 0; + world.sim_frame = 0; + + for( int i = 0; i < arrlen( world.io ); i ++ ) + world.io[i].recv_count = 0; + + vg_info( "Stopping simulation!\n" ); + } + float ratio = (float)vg_window_y / (float)vg_window_x; float const size = 9.5f; @@ -466,7 +556,7 @@ void vg_update(void) int tile_x = floorf( tile_pos[0] ); int tile_y = floorf( tile_pos[1] ); - + // Tilemap editing if( !world.simulating ) { @@ -592,8 +682,6 @@ void vg_update(void) v2i dirs[] = {{1,0},{-1,0},{0,-1}}; for( int j = 0; j < vg_list_size(dirs); j ++ ) - { - v2i target; if( pcell( (v2i){ posx+dirs[j][0], posy+dirs[j][1] } )->state & FLAG_CANAL ) { fish->dir[0] = dirs[j][0]; @@ -601,7 +689,6 @@ void vg_update(void) can_spawn = 1; break; } - } if( !can_spawn ) world.num_fishes--; @@ -658,7 +745,7 @@ void vg_update(void) else { struct cell *cell_next = pcell( (v2i){ fish->pos[0]+fish->dir[0], fish->pos[1]+fish->dir[1] } ); - if( !(cell_next->state & FLAG_CANAL) ) + if( !(cell_next->state & (FLAG_CANAL|FLAG_OUTPUT)) ) { // Try other directions for valid, so down, left, right.. v2i dirs[] = {{1,0},{-1,0},{0,-1}}; @@ -669,7 +756,7 @@ void vg_update(void) if( (dirs[j][0] == -fish->dir[0]) && (dirs[j][1] == -fish->dir[1]) ) continue; - if( pcell( (v2i){ fish->pos[0]+dirs[j][0], fish->pos[1]+dirs[j][1] } )->state & FLAG_CANAL ) + if( pcell( (v2i){ fish->pos[0]+dirs[j][0], fish->pos[1]+dirs[j][1] } )->state & (FLAG_CANAL|FLAG_OUTPUT) ) { fish->dir[0] = dirs[j][0]; fish->dir[1] = dirs[j][1]; @@ -696,7 +783,7 @@ void vg_render(void) glClearColor( 0.8f, 0.8f, 0.8f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glBindVertexArray( world.tile_vao ); + use_mesh( &world.tile ); SHADER_USE( shader_tile_colour ); glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); @@ -713,7 +800,7 @@ void vg_render(void) } glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)x - 0.2f, (float)y - 0.15f, 1.0f ); - glDrawArrays( GL_TRIANGLES, 0, 6 ); + draw_mesh( 0, 2 ); } for( int y = 0; y < world.h; y ++ ) @@ -723,7 +810,19 @@ void vg_render(void) struct cell *cell = pcell((v2i){x,y}); int selected = world.selected == y*world.w + x; - if( cell->state & FLAG_CANAL && !selected ) + if( cell->state & FLAG_SPLIT ) + { + glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.9f, 0.9f, 0.9f, 1.0f ); + glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)x, (float)y, 1.0f ); + + struct mesh *splitter = cell->state & FLAG_FLIP_FLOP? &world.splitter_r: &world.splitter_l; + + use_mesh( splitter ); + draw_mesh( 0, splitter->elements ); + use_mesh( &world.tile ); + } + + if( (cell->state & FLAG_CANAL) && !selected ) continue; glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)x, (float)y, 1.0f ); @@ -733,7 +832,7 @@ void vg_render(void) if( cell->state & FLAG_WALL ) { v4_copy( (v4f){ 0.2f, 0.2f, 0.2f, 1.0f }, colour ); } else if( cell->state & FLAG_CANAL ) { v4_copy( (v4f){ 0.6f, 0.6f, 0.6f, 1.0f }, colour ); } else if( cell->state & FLAG_INPUT ) { v4_copy( (v4f){ 0.5f, 0.5f, 0.5f, 1.0f }, colour ); } - else if( cell->state & FLAG_OUTPUT ) { v4_copy( (v4f){ 0.2f, 0.7f, 0.3f, 1.0f }, colour ); } + else if( cell->state & FLAG_OUTPUT ) { v4_copy( (v4f){ 0.4f, 0.4f, 0.4f, 1.0f }, colour ); } else v4_copy( (v4f){ 0.9f, 0.9f, 0.9f, 1.0f }, colour ); //if( cell->water[world.frame&0x1] ) @@ -749,17 +848,11 @@ void vg_render(void) glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, colour ); - glDrawArrays( GL_TRIANGLES, 0, 6 ); - - if( cell->state & FLAG_CANAL ) - { - glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1.0f, 1.0f, 1.0f, 1.0f ); - glDrawArrays( GL_TRIANGLES, 6, 3 ); - } + draw_mesh( 0, 2 ); } } - glBindVertexArray( world.circle_vao ); + use_mesh( &world.circle ); // Draw i/o arrays for( int i = 0; i < arrlen( world.io ); i ++ ) @@ -770,9 +863,9 @@ void vg_render(void) int is_input = world.data[ term->id ].state & FLAG_INPUT; int const filled_start = 0; - int const filled_count = 32*3; - int const empty_start = 32*3; - int const empty_count = 32*6; + int const filled_count = 32; + int const empty_start = 32; + int const empty_count = 32*2; v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -787,9 +880,9 @@ void vg_render(void) // Draw filled if tick not passed, draw empty if empty if( world.sim_frame > j ) - glDrawArrays( GL_TRIANGLES, empty_start, empty_count ); + draw_mesh( empty_start, empty_count ); else - glDrawArrays( GL_TRIANGLES, filled_start, filled_count ); + draw_mesh( filled_start, filled_count ); } else { @@ -799,13 +892,13 @@ void vg_render(void) v3_muls( dot_colour, 0.8f, dot_colour ); glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour ); - glDrawArrays( GL_TRIANGLES, filled_start, filled_count ); + draw_mesh( filled_start, filled_count ); } colour_code_v3( term->conditions[j], dot_colour ); glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour ); - glDrawArrays( GL_TRIANGLES, empty_start, empty_count ); + draw_mesh( empty_start, empty_count ); } } } @@ -829,9 +922,19 @@ void vg_render(void) glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour ); glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)fish->pos[0] + 0.5f - (float)fish->dir[0]*lerp, (float)fish->pos[1] + 0.25f - (float)fish->dir[1]*lerp, 0.25f ); - glDrawArrays( GL_TRIANGLES, 0, 32*3 ); + draw_mesh( 0, 32 ); } } + + if( world.simulating ) + { + glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.0f, 0.0f, 0.0f, 1.0f ); + glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), -0.5f + cosf( vg_time * 4.0f ) * 0.2f, sinf( vg_time * 4.0f ) * 0.2f + (float)world.h * 0.5f, 0.05f ); + draw_mesh( 0, 32 ); + } } -void vg_ui(void){} +void vg_ui(void) +{ + ui_test(); +}