@@ -65,6 +65,7 @@ PLATFORMS:
6565# L12 gw scratch: platform w
6666# L13 gh scratch: platform h
6767# L14 jump_held 1 while a jump key is held (edge detection)
68+ # L15 anim walk - cycle counter ( 0 when standing still)
6869#
6970push 10240 ; # L0 px = 40 * 256
7071push 89600 ; # L1 py = 350 * 256
@@ -81,6 +82,7 @@ push 0; # L11 gy
8182push 0 ; # L12 gw
8283push 0 ; # L13 gh
8384push 0 ; # L14 jump_held (1 while a jump key is held)
85+ push 0 ; # L15 anim (walk-cycle counter)
8486
8587# Create the window
8688push 640 ;
@@ -191,6 +193,16 @@ get_local 5; jz SKIP_L;
191193 get_local 2 ; push 720; sub_u64; set_local 2; # moving left
192194SKIP_L:
193195
196+ # Advance the walk cycle while moving on the ground , else stand still
197+ get_local 2 ; push 0; ne_u64; # trying to move? (vx != 0)
198+ get_local 4 ; and_u64; # AND on the ground
199+ jz WALK_RESET ;
200+ get_local 15 ; push 1; add_u64; set_local 15;
201+ jmp WALK_DONE ;
202+ WALK_RESET:
203+ push 0 ; set_local 15;
204+ WALK_DONE:
205+
194206# =====================================================================
195207# Horizontal movement + collision
196208# =====================================================================
@@ -346,9 +358,10 @@ push 400; push 136; call DRAW_DOOR, 2; pop;
346358get_local 0 ; push 8; rshift_i64;
347359get_local 1 ; push 8; rshift_i64;
348360call DRAW_SHADOW , 2 ; pop;
349- get_local 0 ; push 8; rshift_i64;
350- get_local 1 ; push 8; rshift_i64;
351- call DRAW_GUY , 2 ; pop;
361+ get_local 0 ; push 8; rshift_i64; # x
362+ get_local 1 ; push 8; rshift_i64; # y
363+ get_local 15 ; call WALK_SWING, 1; # leg swing for this frame
364+ call DRAW_GUY , 3 ; pop;
352365jmp RENDER_PRESENT ;
353366
354367RENDER_WIN:
@@ -460,13 +473,33 @@ and_u64;
460473ret ;
461474
462475#
463- # DRAW_GUY(i64 x , i64 y)
476+ # DRAW_GUY(i64 x , i64 y , i64 swing )
464477#
465478# Draw a little character inside the 24 x 32 player box whose top - left
466479# corner is at the given pixel coordinates. Built out of FILL_RECT parts:
467- # hair , head , eyes , shirt , arms , legs and shoes. Returns 0 .
480+ # hair , head , eyes , shirt , arms , legs and shoes. The signed `swing`
481+ # ( - 3 .. 3 ) lifts alternate feet to produce a simple walk cycle ; 0 is the
482+ # standing pose. Returns 0 .
483+ #
484+ # Locals:
485+ # L0 lift_l how far the left foot is lifted = max( 0 , swing)
486+ # L1 lift_r how far the right foot is lifted = max( 0 , - swing)
468487#
469488DRAW_GUY:
489+ push 0 ; push 0;
490+ # lift_l = max( 0 , swing)
491+ get_arg 2 ;
492+ dup ; push 0; lt_i64; jz DG_LIFTL;
493+ pop ; push 0;
494+ DG_LIFTL:
495+ set_local 0 ;
496+ # lift_r = max( 0 , - swing)
497+ push 0 ; get_arg 2; sub_u64;
498+ dup ; push 0; lt_i64; jz DG_LIFTR;
499+ pop ; push 0;
500+ DG_LIFTR:
501+ set_local 1 ;
502+
470503# head (skin)
471504get_arg 0 ; push 6; add_u64; get_arg 1; push 2; add_u64; push 12; push 9; push_u32 0xFFF0C8A0; call FILL_RECT, 5; pop;
472505# hair crown (slightly wider than the head , drawn over its top)
@@ -490,17 +523,35 @@ get_arg 0; push 4; add_u64; get_arg 1; push 18; add_u64; push 16; push 3; push
490523get_arg 0 ; push 1; add_u64; get_arg 1; push 11; add_u64; push 3; push 9; push_u32 0xFFF0C8A0; call FILL_RECT, 5; pop;
491524# right arm
492525get_arg 0 ; push 20; add_u64; get_arg 1; push 11; add_u64; push 3; push 9; push_u32 0xFFF0C8A0; call FILL_RECT, 5; pop;
493- # left leg
494- get_arg 0 ; push 5; add_u64; get_arg 1; push 21; add_u64; push 6; push 9; push_u32 0xFF2A50A0; call FILL_RECT, 5; pop;
495- # right leg
496- get_arg 0 ; push 13; add_u64; get_arg 1; push 21; add_u64; push 6; push 9; push_u32 0xFF2A50A0; call FILL_RECT, 5; pop;
497- # left shoe
498- get_arg 0 ; push 5; add_u64; get_arg 1; push 29; add_u64; push 6; push 3; push_u32 0xFF3A2A1A; call FILL_RECT, 5; pop;
499- # right shoe
500- get_arg 0 ; push 13; add_u64; get_arg 1; push 29; add_u64; push 6; push 3; push_u32 0xFF3A2A1A; call FILL_RECT, 5; pop;
526+ # left leg (shortened by lift_l so the foot rises)
527+ get_arg 0 ; push 5; add_u64; get_arg 1; push 21; add_u64; push 6; push 9; get_local 0; sub_u64; push_u32 0xFF2A50A0; call FILL_RECT, 5; pop;
528+ # right leg (shortened by lift_r)
529+ get_arg 0 ; push 13; add_u64; get_arg 1; push 21; add_u64; push 6; push 9; get_local 1; sub_u64; push_u32 0xFF2A50A0; call FILL_RECT, 5; pop;
530+ # left shoe (raised by lift_l)
531+ get_arg 0 ; push 5; add_u64; get_arg 1; push 29; add_u64; get_local 0; sub_u64; push 6; push 3; push_u32 0xFF3A2A1A; call FILL_RECT, 5; pop;
532+ # right shoe (raised by lift_r)
533+ get_arg 0 ; push 13; add_u64; get_arg 1; push 29; add_u64; get_local 1; sub_u64; push 6; push 3; push_u32 0xFF3A2A1A; call FILL_RECT, 5; pop;
501534push 0 ;
502535ret ;
503536
537+ #
538+ # WALK_SWING(i64 counter) - > i64 swing
539+ #
540+ # Map a free - running animation counter onto a 4 - phase leg swing:
541+ # 0 (both feet down) , + 3 (left foot up) , 0 , - 3 (right foot up) , repeating.
542+ # Phase 0 is neutral so a counter of 0 (standing still) keeps both feet on
543+ # the ground. Each phase lasts 3 frames , so a full stride takes 12 frames.
544+ #
545+ WALK_SWING:
546+ get_arg 0 ; push 3; div_i64; push 4; mod_u64; # phase 0..3
547+ dup ; push 1; eq_u64; jnz WS_POS;
548+ dup ; push 3; eq_u64; jnz WS_NEG;
549+ pop ; push 0; ret;
550+ WS_POS:
551+ pop ; push 3; ret;
552+ WS_NEG:
553+ pop ; push -3; ret;
554+
504555#
505556# DRAW_DOOR(i64 x , i64 y)
506557#
@@ -637,10 +688,12 @@ push 32;
637688push_u32 0xFFFFE9A0 ;
638689call FILL_RECT , 5 ; pop;
639690
640- # the little guy steps into the doorway during the first ~ 48 frames
691+ # the little guy walks into the doorway during the first ~ 48 frames
641692get_arg 0 ; push 48; lt_i64; jz DW_NOGUY;
642693 push 372 ; get_arg 0; push 2; mul_u64; push 3; div_i64; add_u64; set_local 1; # gx = 372 + t*2/3
643- get_local 1 ; push 144; call DRAW_GUY, 2; pop;
694+ get_local 1 ; push 144;
695+ get_arg 0 ; call WALK_SWING, 1; # animate his legs as he walks in
696+ call DRAW_GUY , 3 ; pop;
644697DW_NOGUY:
645698
646699# confetti: 16 falling squares whose colour cycles
0 commit comments