substantial refactor to movement code
authorhgn <hgodden00@gmail.com>
Thu, 2 Dec 2021 05:00:01 +0000 (05:00 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 2 Dec 2021 05:00:01 +0000 (05:00 +0000)
fishladder.c
vg/vg_m.h

index 26a94eb404d0abf76f19a0a5e9a33ce64342165c..372f21e2a7e780b1e1a2ae846900cdeb3ffec50b 100644 (file)
@@ -121,8 +121,41 @@ m3x3f m_mdl;
                |          |    |     |    |     |    |
 */
 
+struct cell_description
+{
+       v2i start;
+       v2i end;
+       
+       int is_special;
+       int is_linear;
+}
+cell_descriptions[] =
+{
+       // 0-3
+       {},
+       { .start = {  1,  0 }, .end = { -1,  0 } },
+       { .start = {  0,  1 }, .end = {  0, -1 } },
+       { .start = {  0,  1 }, .end = {  1,  0 } },
+       // 4-7
+       { .start = { -1,  0 }, .end = {  1,  0 } },
+       { .start = { -1,  0 }, .end = {  1,  0 }, .is_linear = 1 },
+       { .start = {  0,  1 }, .end = { -1,  0 } },
+       { .start = {  0,  1 }, .is_special = 1 },
+       // 8-11
+       { .start = {  0, -1 }, .end = {  0,  1 } },
+       { .start = {  1,  0 }, .end = {  0, -1 } },
+       { .start = {  0,  1 }, .end = {  0, -1 }, .is_linear = 1 },
+       { },
+       // 12-15
+       { .start = { -1,  0 }, .end = {  0, -1 } },
+       { .end = { 0, -1 }, .is_special = 1 },
+       { },
+       { }
+};
+
 enum cell_type
 {
+       k_cell_type_stub = 0,
        k_cell_type_ramp_right = 3,
        k_cell_type_ramp_left = 6,
        k_cell_type_split = 7,
@@ -133,6 +166,21 @@ enum cell_type
        k_cell_type_con_d = 8
 };
 
+v2f const curve_3[] = {{0.5f,1.0f},{0.5f,0.625f},{0.625f,0.5f},{1.0f,0.5f}};
+v2f const curve_6[] = {{0.5f,1.0f},{0.5f,0.625f},{0.375f,0.5f},{0.0f,0.5f}};
+v2f const curve_9[] = {{1.0f,0.5f},{0.625f,0.5f},{0.5f,0.375f},{0.5f,0.0f}};
+v2f const curve_12[]= {{0.0f,0.5f},{0.375f,0.5f},{0.5f,0.375f},{0.5f,0.0f}};
+
+v2f const curve_1[] = {{1.0f,0.5f},{0.8f,0.5f},{0.3f,0.5f},{0.2f,0.5f}};
+v2f const curve_4[] = {{0.0f,0.5f},{0.3f,0.5f},{0.5f,0.5f},{0.8f,0.5f}};
+v2f const curve_2[] = {{0.5f,1.0f},{0.5f,0.8f},{0.5f,0.3f},{0.5f,0.2f}};
+v2f const curve_8[] = {{0.5f,0.0f},{0.5f,0.3f},{0.5f,0.5f},{0.5f,0.8f}};
+
+v2f const curve_7[] = {{0.5f,0.8438f},{0.875f,0.8438f},{0.625f,0.5f},{1.0f,0.5f}};
+v2f const curve_7_1[] = {{0.5f,0.8438f},{1.0f-0.875f,0.8438f},{1.0-0.625f,0.5f},{0.0f,0.5f}};
+
+float const curve_7_linear_section = 0.1562f;
+
 v3f colour_sets[] =
 { { 0.9f, 0.6f, 0.20f },
   { 0.2f, 0.9f, 0.14f },
@@ -266,6 +314,7 @@ struct world
                v2i dir;
                enum e_fish_state state;
                char payload;
+               int flow_reversed;
                float death_time;
                v2f physics_v;
                v2f physics_co;
@@ -1153,22 +1202,6 @@ static void map_reclassify( v2i start, v2i end, int update_texbuffer )
        }
 }
 
-
-v2f const curve_3[] = {{0.5f,1.0f},{0.5f,0.625f},{0.625f,0.5f},{1.0f,0.5f}};
-v2f const curve_6[] = {{0.5f,1.0f},{0.5f,0.625f},{0.375f,0.5f},{0.0f,0.5f}};
-v2f const curve_9[] = {{1.0f,0.5f},{0.625f,0.5f},{0.5f,0.375f},{0.5f,0.0f}};
-v2f const curve_12[]= {{0.0f,0.5f},{0.375f,0.5f},{0.5f,0.375f},{0.5f,0.0f}};
-
-v2f const curve_1[] = {{1.0f,0.5f},{0.8f,0.5f},{0.3f,0.5f},{0.2f,0.5f}};
-v2f const curve_4[] = {{0.0f,0.5f},{0.3f,0.5f},{0.5f,0.5f},{0.8f,0.5f}};
-v2f const curve_2[] = {{0.5f,1.0f},{0.5f,0.8f},{0.5f,0.3f},{0.5f,0.2f}};
-v2f const curve_8[] = {{0.5f,0.8f},{0.5f,0.5f},{0.5f,0.3f},{0.5f,0.0f}};
-
-v2f const curve_7[] = {{0.5f,0.8438f},{0.875f,0.8438f},{0.625f,0.5f},{1.0f,0.5f}};
-v2f const curve_7_1[] = {{0.5f,0.8438f},{1.0f-0.875f,0.8438f},{1.0-0.625f,0.5f},{0.0f,0.5f}};
-
-float const curve_7_linear_section = 0.1562f;
-
 u16 id_drag_from = 0;
 v2f drag_from_co;
 v2f drag_to_co;
@@ -1389,87 +1422,70 @@ void vg_update(void)
                                                continue;
                                        }
                                        
-                                       if( cell_current->config == k_cell_type_split )
-                                       {
-                                               // Flip flop L/R
-                                               fish->dir[0] = cell_current->state&FLAG_FLIP_FLOP?1:-1;
-                                               fish->dir[1] = 0;
-                                               
-                                               if( !(cell_current->state & FLAG_TARGETED) )
-                                                       cell_current->state ^= FLAG_FLIP_FLOP;
-                                       }
-                                       else if( cell_current->config == k_cell_type_merge )
+
+                                       if( cell_current->config == k_cell_type_merge )
                                        {
                                                // Can only move up
                                                fish->dir[0] = 0;
                                                fish->dir[1] = -1;
+                                               fish->flow_reversed = 0;
                                        }
                                        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|FLAG_OUTPUT)) )
+                                               if( cell_current->config == k_cell_type_split )
                                                {
-                                                       // Try other directions for valid, so down, left, right..
-                                                       v2i dirs[] = {{1,0},{-1,0},{0,-1}};
-                                                       //vg_info( "Trying some other directions...\n" );
+                                                       // Flip flop L/R
+                                                       fish->dir[0] = cell_current->state&FLAG_FLIP_FLOP?1:-1;
+                                                       fish->dir[1] = 0;
                                                        
-                                                       for( int j = 0; j < vg_list_size(dirs); j ++ )
-                                                       {
-                                                               if( (dirs[j][0] == -fish->dir[0]) && (dirs[j][1] == -fish->dir[1]) )
-                                                                       continue;
+                                                       if( !(cell_current->state & FLAG_TARGETED) )
+                                                               cell_current->state ^= FLAG_FLIP_FLOP;
+                                               }
+                                               else
+                                               {
+                                                       // Apply cell out-flow
+                                                       struct cell_description *desc = &cell_descriptions[ cell_current->config ];
                                                        
-                                                               if( pcell( (v2i){ fish->pos[0]+dirs[j][0], fish->pos[1]+dirs[j][1] } )->state & (FLAG_CANAL|FLAG_OUTPUT) )
+                                                       v2i_copy( fish->flow_reversed? desc->start: desc->end, fish->dir );
+                                               }
+                                               
+                                               v2i pos_next;
+                                               v2i_add( fish->pos, fish->dir, pos_next );
+                                               
+                                               struct cell *cell_next = pcell( pos_next );
+                                               
+                                               if( cell_next->state & (FLAG_CANAL|FLAG_OUTPUT) )
+                                               {
+                                                       struct cell_description *desc = &cell_descriptions[ cell_next->config ];
+                                                       
+                                                       if( cell_next->config == k_cell_type_merge )
+                                                               fish->flow_reversed = 0;
+                                                       else
+                                                       {
+                                                               if( cell_next->config == k_cell_type_split )
                                                                {
-                                                                       fish->dir[0] = dirs[j][0];
-                                                                       fish->dir[1] = dirs[j][1];
+                                                                       if( fish->dir[0] == 0 )
+                                                                       {
+                                                                               sfx_set_playrnd( &audio_splitter, &audio_system_balls_important, 0, 1 );
+                                                                               cell_next->state |= FLAG_FLIP_ROTATING;
+                                                                       }
+                                                                       else
+                                                                               fish->state = k_fish_state_dead;
                                                                }
+                                                               else
+                                                                       fish->flow_reversed = ( fish->dir[0] != -desc->start[0] || 
+                                                                                                                                       fish->dir[1] != -desc->start[1] )? 1: 0;
                                                        }
                                                }
-                                       }
-                                       
-                                       fish->pos[0] += fish->dir[0];
-                                       fish->pos[1] += fish->dir[1];
-                                       
-                                       struct cell *cell_entry = pcell( fish->pos );
-                                       
-                                       if( !(cell_entry->state & (FLAG_INPUT|FLAG_CANAL|FLAG_OUTPUT) ))
-                                       {
-                                               if( world_check_pos_ok( fish->pos ) )
-                                                       fish->state = k_fish_state_bg;
                                                else
-                                                       fish->state = k_fish_state_dead;
+                                                       fish->state = world_check_pos_ok( fish->pos )? k_fish_state_bg: k_fish_state_dead;
                                        }
-                                       else
-                                       {
-                                               if( fish->dir[0] )
-                                               {
-                                                       if( cell_entry->config == k_cell_type_split ||
-                                                                cell_entry->config == k_cell_type_ramp_right ||
-                                                                cell_entry->config == k_cell_type_ramp_left )
-                                                       {
-                                                               // Special death (FALL)
-                                                               /*
-                                                               v2_sub( fish->physics_co, fish->physics_v, fish->physics_v );
-                                                               v2_divs( fish->physics_v, vg_time_delta, fish->physics_v );
-                                                               */
-                                                               
-                                                               fish->state = k_fish_state_dead;
-                                                               vg_error( "REMOVE THIS CONDITION\n" );
-                                                               continue;
-                                                       }
-                                               }
                                        
-                                               if( cell_entry->config == k_cell_type_split )
-                                               {
-                                                       sfx_set_playrnd( &audio_splitter, &audio_system_balls_important, 0, 1 );
-                                                       cell_entry->state |= FLAG_FLIP_ROTATING;
-                                               }
-                                       }
+                                       v2i_add( fish->pos, fish->dir, fish->pos );
                                }
                                else if( fish->state == k_fish_state_bg )
                                {
-                                       fish->pos[0] += fish->dir[0];
-                                       fish->pos[1] += fish->dir[1];
+                                       v2i_add( fish->pos, fish->dir, fish->pos );
                                        
                                        if( !world_check_pos_ok( fish->pos ) )
                                                fish->state = k_fish_state_dead;
@@ -1486,6 +1502,7 @@ void vg_update(void)
                                                                
                                                                fish->dir[0] = 0;
                                                                fish->dir[1] = 0;
+                                                               fish->flow_reversed = 1;
                                                                
                                                                switch( cell_entry->config )
                                                                {
@@ -1567,28 +1584,24 @@ void vg_update(void)
                                {
                                        if( world.sim_frame < term->runs[ world.sim_run ].condition_count )
                                        {
-                                               struct fish *fish = &world.fishes[world.num_fishes++];
+                                               struct fish *fish = &world.fishes[ world.num_fishes ];
                                                fish->pos[0] = posx;
                                                fish->pos[1] = posy;
                                                fish->state = k_fish_state_alive;
                                                fish->payload = term->runs[ world.sim_run ].conditions[ world.sim_frame ];
                                                
-                                               int can_spawn = 0;
-                                               
-                                               v2i dirs[] = {{1,0},{-1,0},{0,-1}};
-                                               for( int j = 0; j < vg_list_size(dirs); j ++ )
-                                                       if( pcell( (v2i){ posx+dirs[j][0], posy+dirs[j][1] } )->state & FLAG_CANAL )
-                                                       {
-                                                               fish->dir[0] = dirs[j][0];
-                                                               fish->dir[1] = dirs[j][1];
-                                                               can_spawn = 1;
-                                                               break;
-                                                       }
+                                               struct cell *cell_ptr = pcell( fish->pos );
                                                
-                                               if( !can_spawn )
-                                                       world.num_fishes--;
-                                               else
+                                               if( cell_ptr->config != k_cell_type_stub )
+                                               {
+                                                       struct cell_description *desc = &cell_descriptions[ cell_ptr->config ];
+                                                       
+                                                       v2i_copy( desc->start, fish->dir );
+                                                       fish->flow_reversed = 1;
+                                                       
+                                                       world.num_fishes ++;
                                                        alive_count ++;
+                                               }
                                        }
                                }
                        }
@@ -1685,33 +1698,28 @@ void vg_update(void)
                                continue; // Todo: particle thing?
                                
                        struct cell *cell = pcell(fish->pos);
+                       struct cell_description *desc = &cell_descriptions[ cell->config ];
+                       
                        v2f const *curve;
                        
                        float t = world.frame_lerp;
-                       float ti = 1.0f-t;
-                       
+                       if( fish->flow_reversed && !desc->is_linear )
+                               t = 1.0f-t;
+
                        v2_copy( fish->physics_co, fish->physics_v );
                        
                        switch( cell->config )
                        {
-                               case 13:
+                               case k_cell_type_merge:
                                        if( fish->dir[0] == 1 )
                                                curve = curve_12;
                                        else
                                                curve = curve_9;
                                break;
-                               case k_cell_type_con_r: curve = curve_1; 
-                                       if( fish->dir[0] == 1 ) t = ti;
-                               break;
-                               case k_cell_type_con_l: curve = curve_4; 
-                                       if( fish->dir[0] == -1 ) t = ti;
-                               break;
-                               case k_cell_type_con_u: curve = curve_2; 
-                                       if( fish->dir[1] == 1 ) t = ti;
-                               break;
-                               case k_cell_type_con_d: curve = curve_8; 
-                                       if( fish->dir[1] == 1 ) t = ti;
-                               break;
+                               case k_cell_type_con_r: curve = curve_1; break;
+                               case k_cell_type_con_l: curve = curve_4; break;
+                               case k_cell_type_con_u: curve = curve_2; break;
+                               case k_cell_type_con_d: curve = curve_8; break;
                                case 3: curve = curve_3; break;
                                case 6: curve = curve_6; break;
                                case 9: curve = curve_9; break;
index 9e70c9290ca48d859df9f9c054065c506040df23..dd7f49b6d4cf7571862ee6c01df317701beda59f 100644 (file)
--- a/vg/vg_m.h
+++ b/vg/vg_m.h
@@ -50,6 +50,16 @@ static inline void v2_copy( v2f a, v2f b )
        b[0] = a[0]; b[1] = a[1];
 }
 
+static inline void v2i_copy( v2i a, v2i b )
+{
+       b[0] = a[0]; b[1] = a[1];
+}
+
+static inline void v2i_add( v2i a, v2i b, v2i d )
+{
+       d[0] = a[0]+b[0]; d[1] = a[1]+b[1];
+}
+
 static inline void v2_minv( v2f a, v2f b, v2f dest ) 
 {
        dest[0] = vg_minf(a[0], b[0]);