Skip to content

Improve sprites animation

LSM edited this page Mar 14, 2026 · 1 revision

Sprites animation is skipped while OAM is max usage. It causes animation be delayed and lose control, like bombeam trap and wily machine 2 fighting. This tutorial is used for improving sprites animation.

Edit home/sprites.asm

_sprites:
...
@loop_1:
	JSR _draw_megaman_with_animation
-	BCS @max_1
+	BCS @megaman_max_1
	INC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$10
	BNE @loop_1

@loop_2:
	JSR _draw_enemies_with_animation
-	BCS @max_1
+	BCS @enemies_max_1
	INC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$20
	BNE @loop_2
	LDA z:z06
	STA z:z0C
	JSR _draw_bar

-@max_1:
	JMP _draw_sprites_done

+@megaman_max_1:
+@loopmax_1:
+	INC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$10
+	BEQ @animate_megaman_done
+	JSR _draw_megaman_with_animation_max
+	JMP @loopmax_1

+@enemies_max_1:
+@animate_megaman_done:
+@loopmax_2:
+	INC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$20
+	BEQ _draw_sprites_done
+	JSR _draw_enemies_with_animation_max
+	JMP @loopmax_2
+	JMP _draw_sprites_done
...
@loop_3:
	JSR _draw_enemies_with_animation
-	BCS @max_2
+	BCS @enemies_max_2
	DEC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$0F
	BNE @loop_3

@loop_4:
	JSR _draw_megaman_with_animation
-	BCS @max_2
+	BCS @megaman_max_2
	DEC z:zsprites_pointer
	BPL @loop_4
	LDA z:z06
	STA z:z0C
+	JMP _draw_sprites_done

+@enemies_max_2:
+@loopmax_3:
+	DEC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$0F
+	BEQ @animate_enemies_done
+	JSR _draw_enemies_with_animation_max
+	JMP @loopmax_3

+@megaman_max_2:
+@animate_enemies_done:
+@loopmax_4:
+	DEC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	BMI _draw_sprites_done
+	JSR _draw_megaman_with_animation_max
+	JMP @loopmax_4

-@max_2:
_draw_sprites_done:
...

_time_stopper_flag_set:
...
@done_2:
-	BCS @max_1
+	BCS @megaman_max_1
	INC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$10
	BNE @loop_1

@loop_2:
	JSR _draw_enemies_without_animation
-	BCS @max_1
+	BCS @enemies_max_1
	INC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$20
	BNE @loop_2
	LDA z:z06
	STA z:z0C
	JSR _draw_bar

-@max_1:
+@animate_enemies_done_1:
	JMP _draw_sprites_done

+@megaman_max_1:
+@loopmax_1:
+	INC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$10
+	BEQ @animate_megaman_done_1
+	JSR _draw_megaman_with_animation_max
+	JMP @loopmax_1

+@enemies_max_1:
+@animate_megaman_done_1:
+@loopmax_2:
+	INC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$20
+	BEQ @animate_enemies_done_1
+	JSR _draw_enemies_with_animation_max
+	JMP @loopmax_2
...
@loop_3:
	JSR _draw_enemies_without_animation
-	BCS @max_2
+	BCS @enemies_max_2
	DEC z:zsprites_pointer
	LDA z:zsprites_pointer
	CMP #$0F
	BNE @loop_3
...
@done_3:
-	BCS @max_2
+	BCS @megaman_max_2
	DEC z:zsprites_pointer
	BNE @loop_4
	LDA z:ztime_stopper_flag
	AND #megaman_frozen
	BEQ @megaman_frozen_not_set_2
	JSR _draw_megaman_without_animation
	JMP @done_4
...
-@max_2:
+@animate_megaman_done_2:
	JMP _draw_sprites_done

+@enemies_max_2:
+@loopmax_3:
+	DEC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	CMP #$0F
+	BEQ @animate_enemies_done_2
+	JSR _draw_enemies_with_animation_max
+	JMP @loopmax_3

+@megaman_max_2:
+@animate_enemies_done_2:
+@loopmax_4:
+	DEC z:zsprites_pointer
+	LDA z:zsprites_pointer
+	BMI @animate_megaman_done_2
+	JSR _draw_megaman_with_animation_max
+	JMP @loopmax_4
...
+_draw_megaman_with_animation_max:
+	LDX z:zsprites_pointer
+	LDA aobject_attributes, X
+	BMI @exist
+	CLC
+	RTS

+@exist:
+	LDY aobject_pointer, X
+	LDA oam_megaman_frameset_pointers_lo, Y
+	STA z:z08
+	LDA oam_megaman_frameset_pointers_hi, Y
+	STA z:z09
+	LDA aobject_frameset_upper_timer, X
+	PHA
+	INC aobject_frameset_lower_timer, X
+	LDY #$01
+	LDA (z08), Y
+	CMP aobject_frameset_lower_timer, X
+	BCS @max
+	LDA #0
+	STA aobject_frameset_lower_timer, X
+	INC aobject_frameset_upper_timer, X
+	DEY
+	LDA (z08), Y
+	CMP aobject_frameset_upper_timer, X
+	BCS @max
+	LDA #0
+	STA aobject_frameset_upper_timer, X

+@max:
+	PLA
+	CLC
+	ADC #2
+	TAY
+	LDA (z08), Y
+	BNE @is_object
+	LSR aobject_attributes, X

+@is_object:
+	RTS

_draw_enemies_with_animation:
...
+_draw_enemies_with_animation_max:
+	LDX z:zsprites_pointer
+	LDA aobject_attributes, X
+	BMI @exist
+	CLC
+	RTS

+@exist:
+	LDY aobject_pointer, X
+	LDA oam_enemies_frameset_pointers_lo, Y
+	STA z:z08
+	LDA oam_enemies_frameset_pointers_hi, Y
+	STA z:z09
+	LDA aobject_frameset_upper_timer, X
+	PHA
+	INC aobject_frameset_lower_timer, X
+	LDY #$01
+	LDA (z08), Y
+	CMP aobject_frameset_lower_timer, X
+	BCS @max
+	LDA #0
+	STA aobject_frameset_lower_timer, X
+	INC aobject_frameset_upper_timer, X
+	DEY
+	LDA (z08), Y
+	CMP aobject_frameset_upper_timer, X
+	BCS @max
+	LDA #0
+	STA aobject_frameset_upper_timer, X

+@max:
+	PLA
+	CLC
+	ADC #2
+	TAY
+	LDA (z08), Y
+	BNE @is_object
+	LSR aobject_attributes, X

+@is_object:
+	RTS

...

With these edit, sprites animation never skipped while OAM is max usage.

Clone this wiki locally