"level2",
"level3",
"level4",
- "level5"
+ "level5",
+ "level6"
};
#pragma pack(push,1)
u32 const size_levels = sizeof(struct career_state)-size_header;
u32 const size_levels_input = sz - size_header;
- memcpy( (void*)career.levels, (void*)cr->levels, size_levels );
+ memcpy( (void*)career.levels, (void*)cr->levels, size_levels_input );
if( sz < sizeof( struct career_state ) )
{
u32 sim_frame;
float sim_start;
int simulating;
+ u32 sim_run;
float frame_lerp;
struct cell_terminal
{
- // TODO: Split into input/output structures
- char *conditions;
- char recv[12];
- int recv_count;
+ //char *conditions;
+ //char recv[12];
+
+ struct terminal_run
+ {
+ char conditions[8];
+ char recieved[8];
+
+ int condition_count, recv_count;
+ }
+ runs[8];
+
+ int run_count;
+
int id;
}
*io;
- u32 w, h;
+ int w, h;
struct mesh tile, circle, numbers;
} world = {};
static void map_free(void)
-{
- for( int i = 0; i < arrlen( world.io ); i ++ )
- arrfree( world.io[ i ].conditions );
-
+{
arrfree( world.data );
arrfree( world.io );
{
if( reg_start < reg_end )
{
+ struct cell_terminal *terminal = &world.io[ reg_start ];
+ struct terminal_run *run = &terminal->runs[ terminal->run_count-1 ];
+
if( *c >= 'a' && *c <= 'z' )
- {
- arrpush( world.io[ reg_start ].conditions, *c );
+ {
+ run->conditions[ run->condition_count ++ ] = *c;
}
else
{
if( *c == '\n' )
break;
}
+ else if( *c == ':' )
+ {
+ terminal->runs[ terminal->run_count ].condition_count = 0;
+ terminal->run_count ++;
+ }
else
{
vg_error( "Unkown attribute '%c' (row: %u)\n", *c, world.h );
if( *c == '+' || *c == '-' )
{
- struct cell_terminal term = { .id = cx + world.h*world.w };
- arrpush( world.io, term );
+ struct cell_terminal *term = arraddnptr( world.io, 1 );
+ term->id = cx + world.h*world.w;
+ term->run_count = 1;
+ term->runs[0].condition_count = 0;
+
cell->state = *c == '+'? FLAG_INPUT: FLAG_OUTPUT;
reg_end ++;
}
fputc( ',', stream );
terminal_write_count ++;
- for( int j = 0; j < arrlen( term->conditions ); j ++ )
- fputc( term->conditions[j], stream );
+ for( int j = 0; j < term->run_count; j ++ )
+ {
+ struct terminal_run *run = &term->runs[j];
+
+ for( int k = 0; k < run->condition_count; k ++ )
+ fputc( run->conditions[k], stream );
+
+ if( j < term->run_count-1 )
+ fputc( ':', stream );
+ }
}
}
}
if( text_source )
{
- map_load( text_source, argv[0] );
+ if( !map_load( text_source, argv[0] ) )
+ map_free();
+
free( text_source );
// Update career link
}
}
+static void io_reset(void)
+{
+ for( int i = 0; i < arrlen( world.io ); i ++ )
+ {
+ struct cell_terminal *term = &world.io[i];
+
+ for( int j = 0; j < term->run_count; j ++ )
+ term->runs[j].recv_count = 0;
+ }
+}
+
static void simulation_stop(void)
{
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;
+ io_reset();
sfx_system_fadeout( &audio_system_balls_rolling, 44100 );
{
world.selected = world.tile_y * world.w + world.tile_x;
+ static u32 modify_state = 0;
+
+ struct cell *cell_ptr = &world.data[world.selected];
+
if( vg_get_button_down("primary") )
{
- world.data[ world.selected ].state ^= FLAG_CANAL;
-
- if( world.data[ world.selected ].state & FLAG_CANAL )
+ modify_state = (cell_ptr->state & FLAG_CANAL) ^ FLAG_CANAL;
+ }
+
+ if( vg_get_button("primary") && ((cell_ptr->state & FLAG_CANAL) != modify_state) )
+ {
+ cell_ptr->state &= ~FLAG_CANAL;
+ cell_ptr->state |= modify_state;
+
+ if( cell_ptr->state & FLAG_CANAL )
{
sfx_set_playrnd( &audio_tile_mod, &audio_system_sfx, 3, 6 );
world.score ++;
world.sim_start = vg_time;
for( int i = 0; i < world.w*world.h; i ++ )
- {
world.data[ i ].state &= ~FLAG_FLIP_FLOP;
- }
- for( int i = 0; i < arrlen( world.io ); i ++ )
- world.io[i].recv_count = 0;
+ io_reset();
}
}
if( term->id == fish->pos[1]*world.w + fish->pos[0] )
{
- term->recv[ term->recv_count ++ ] = fish->payload;
+ struct terminal_run *run = &term->runs[ world.sim_run ];
+ if( run->recv_count < vg_list_size( run->recieved ) )
+ run->recieved[ run->recv_count ++ ] = fish->payload;
+
break;
}
}
if( is_input )
{
- if( world.sim_frame < arrlen( term->conditions ) )
+ if( world.sim_frame < term->runs[ world.sim_run ].condition_count )
{
struct fish *fish = &world.fishes[world.num_fishes++];
fish->pos[0] = posx;
fish->pos[1] = posy;
fish->alive = 1;
- fish->payload = term->conditions[world.sim_frame];
+ fish->payload = term->runs[ world.sim_run ].conditions[ world.sim_frame ];
int can_spawn = 0;
if( !is_input )
{
- if( term->recv_count == arrlen( term->conditions ) )
+ struct terminal_run *run = &term->runs[ world.sim_run ];
+
+ if( run->recv_count == run->condition_count )
{
- for( int j = 0; j < arrlen( term->conditions ); j ++ )
+ for( int j = 0; j < run->condition_count; j ++ )
{
- if( term->recv[j] != term->conditions[j] )
+ if( run->recieved[j] != run->conditions[j] )
{
world.completed = 0;
break;
v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f };
- for( int j = 0; j < arrlen( term->conditions ); j ++ )
+ // TODO: Iterate runs
+ for( int j = 0; j < term->runs[0].condition_count; j ++ )
{
float y_offset = is_input? 1.2f: -0.2f;
glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)posx + 0.2f + 0.2f * (float)j, (float)posy + y_offset, 0.1f );
if( is_input )
{
- colour_code_v3( term->conditions[j], dot_colour );
+ colour_code_v3( term->runs[0].conditions[j], dot_colour );
glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
// Draw filled if tick not passed, draw empty if empty
}
else
{
- if( term->recv_count > j )
+ if( term->runs[0].recv_count > j )
{
- colour_code_v3( term->recv[j], dot_colour );
+ colour_code_v3( term->runs[0].recieved[j], dot_colour );
v3_muls( dot_colour, 0.8f, dot_colour );
glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
draw_mesh( filled_start, filled_count );
}
- colour_code_v3( term->conditions[j], dot_colour );
+ colour_code_v3( term->runs[0].conditions[j], dot_colour );
glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
draw_mesh( empty_start, empty_count );
draw_mesh( empty_start, empty_count );
}
+ // Level scores
+ use_mesh( &world.numbers );
+ for( int i = 0; i < level_count; i ++ )
+ {
+ struct career_level *clevel = &career.levels[i];
+
+ v3f level_ui_space = {
+ -0.94f,
+ ((float)level_count - (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f,
+ 0.02f
+ };
+
+ if( clevel->completed )
+ {
+ draw_numbers( level_ui_space, clevel->score );
+ }
+ }
+
//use_mesh( &world.numbers );
//draw_numbers( (v3f){ 0.0f, -0.5f, 0.1f }, 128765 );
}