diff --git a/games/tfv/Makefile b/games/tfv/Makefile index da1cbde7..c388b4a5 100644 --- a/games/tfv/Makefile +++ b/games/tfv/Makefile @@ -80,7 +80,7 @@ tfv_world.o: tfv_world.s zp.inc \ tfv_battle.s tfv_battle_menu.s tfv_battle_limit.s tfv_battle_summons.s \ tfv_battle_magic.s tfv_battle_enemy.s tfv_battle_draw_hero.s \ tfv_battle_boss.s tfv_battle_attack.s \ - help_overworld.s rotate_intro.s \ + help_overworld.s rotate_intro.s rotozoom.s \ sound_effects.s speaker_tone.s \ graphics_map/tfv_backgrounds.inc \ tfv_sprites.inc battle_sprites.inc diff --git a/games/tfv/c00_scrn_offsets.s b/games/tfv/c00_scrn_offsets.s new file mode 100644 index 00000000..02a5f7dc --- /dev/null +++ b/games/tfv/c00_scrn_offsets.s @@ -0,0 +1,16 @@ +common_offsets_l: + .byte <$c00,<$c80,<$d00,<$d80,<$e00,<$e80,<$f00,<$f80 + .byte <$c28,<$ca8,<$d28,<$da8,<$e28,<$ea8,<$f28,<$fa8 + .byte <$c50,<$cd0,<$d50,<$dd0,<$e50,<$ed0,<$f50,<$fd0 + +scrn_c00_offsets_h: + .byte >$c00,>$c80,>$d00,>$d80,>$e00,>$e80,>$f00,>$f80 + .byte >$c28,>$ca8,>$d28,>$da8,>$e28,>$ea8,>$f28,>$fa8 + .byte >$c50,>$cd0,>$d50,>$dd0,>$e50,>$ed0,>$f50,>$fd0 + + +gr_400_offsets_h: + .byte >$400,>$480,>$500,>$580,>$600,>$680,>$700,>$780 + .byte >$428,>$4a8,>$528,>$5a8,>$628,>$6a8,>$728,>$7a8 + .byte >$450,>$4d0,>$550,>$5d0,>$650,>$6d0,>$750,>$7d0 + diff --git a/games/tfv/rotate_intro.s b/games/tfv/rotate_intro.s index f4ad5673..923bd59c 100644 --- a/games/tfv/rotate_intro.s +++ b/games/tfv/rotate_intro.s @@ -4,51 +4,50 @@ rotate_intro: + ; init the multiply routines + + jsr init_multiply_tables + ; first copy current screen to background jsr gr_copy_current_to_offscreen_40x40 -; int xx,yy,color,x2,y2; -; double h,theta,dx,dy,theta2,thetadiff,nx,ny; -; int i; + lda #0 + sta ANGLE + sta SCALE_F + sta FRAMEL -; gr_copy(0x400,0xc00); + lda #1 + sta SCALE_I -; gr_copy_to_current(0xc00); -; page_flip(); -; gr_copy_to_current(0xc00); -; page_flip(); +rotate_loop: -; thetadiff=0; + jsr rotozoom + jsr page_flip -; for(i=0;i<8;i++) { + ; zoom out -; for(yy=0;yy<40;yy++) { -; for(xx=0;xx<40;xx++) { -; dx=(xx-20); -; dy=(yy-20); -; h=sqrt((dx*dx)+(dy*dy)); -; theta=atan2(dy,dx); -; -; theta2=theta+thetadiff; -; nx=h*cos(theta2); -; ny=h*sin(theta2); -; -; x2=nx+20; -; y2=ny+20; -; if ((x2<0) || (x2>39)) color=0; -; else if ((y2<0) || (y2>39)) color=0; -; else color=scrn_page(x2,y2,PAGE2); + sec + lda SCALE_F + sbc #$10 + sta SCALE_F + lda SCALE_I + sbc #$00 + sta SCALE_I -; color_equals(color); -; plot(xx,yy); -; } -; } -; thetadiff+=(6.28/16.0); -; page_flip(); + dec ANGLE + lda ANGLE + and #$1f + sta ANGLE -; usleep(100000); -; } + ; rotate counter-clockwise + + cmp #16 + beq done_rotate + + jmp rotate_loop + +done_rotate: rts diff --git a/games/tfv/rotozoom.s b/games/tfv/rotozoom.s new file mode 100644 index 00000000..cc8c1e9d --- /dev/null +++ b/games/tfv/rotozoom.s @@ -0,0 +1,624 @@ + + ; rotozoomer! + ; takes a lores-formatted image in $c00 and rotozooms it + ; by ANGLE and SCALE_I/SCALE_F and draws it to the + ; lo-res page in DRAW_PAGE + + ; ANGLE in our case is 0..31 + ; SCALE_I/SCALE_F is 8.8 fixed point scale multiplier + +; optimization (cycles measured at ANGLE=0) +; $6BD76=441,718=2.26fps initial code with external plot and scrn +; $62776=403,318=2.48fps inline plot +; $597b6=366,518=2.73fps inline scrn +; $4F496=324,758=3.08fps move plot line calc outside of inner loop +; $49d16=302,358=3.31fps do color*17 ourselves +; $4645e=287,838=3.47fps move XX into X +; $3ef7e=257,918=3.87fps optimize plot +; $3c9fe=248,318=4.03fps optimize scrn +; $39e3e=237,118=4.22fps add scrn address lookup table +; $39fdf=237,535 add two scale multiplies +; $39e17=237,079=4.22fps change the init to also use multiply +; $39dc9=237,001= change to use common lookup table (outside inner loop) +; $3399f=211,359=4.73fps unroll the Y loop by one +; $2BA83=178,819=5.59fps optimize unrolled loop + +CAL = $C0 +CAH = $C1 +SAL = $C2 +SAH = $C3 +YPL = $C4 +YPH = $C5 +XPL = $C6 +XPH = $C7 +CCAL = $C8 +CCAH = $C9 +CSAL = $CA +CSAH = $CB +YCAL = $CC +YCAH = $CD +YSAL = $CE +YSAH = $CF + +rotozoom: + + ; setup scale for multiply + + lda SCALE_I ; 3 + sta NUM1H ; 3 + lda SCALE_F ; 3 + sta NUM1L ; 3 + + ; ca = cos(theta)*scale; + ; (we use equiv ca=fixed_sin[(theta+8)&0xf] ) + + lda ANGLE ; 3 + clc ; 2 + adc #8 ; 2 + and #$1f ; 2 + asl ; 2 + tay ; 2 + lda fixed_sin,Y ; load integer half ; 4 + sta NUM2H ; 3 + lda fixed_sin+1,Y ; load float half ; 4 + sta NUM2L ; 3 + ;=========== + ; 27 + + sec ; reload NUM1H/NUM1L ; 2 + jsr multiply ; 6+??? + stx CAH ; 3 + sta CAL ; 3 + + + ; sa = sin(theta)*scale; + + lda ANGLE ; 3 + asl ; 2 + tay ; 2 + lda fixed_sin,Y ; load integer half ; 4 + sta NUM2H ; 3 + lda fixed_sin+1,Y ; load integer half ; 4 + sta NUM2L ; 3 + ;========== + ; 21 + + + clc ; NUM1H/NUM1L same as last time ; 2 + jsr multiply ; 6+??? + + stx SAH ; 3 + sta SAL ; 3 + + + ; cca = -20*ca; + + lda #-20 ; 2 + sta NUM1H ; 3 + lda #0 ; 2 + sta NUM1L ; 3 + + lda CAL ; 3 + sta NUM2L ; 3 + lda CAH ; 3 + sta NUM2H ; 3 + + sec ; reload NUM1H/NUM1L ; 2 + jsr multiply ; 6+??? + stx CCAH ; 3 + sta CCAL ; 3 + + + ; csa = -20*sa; + + lda SAL ; 3 + sta NUM2L ; 3 + lda SAH ; 3 + sta NUM2H ; 3 + + clc ; same NUM1H/NUM1L as las time ; 2 + jsr multiply ; 6+??? + + stx CSAH ; 3 + sta CSAL ; 3 + + + ; yca=cca+ycenter; + + lda CCAL ; 3 + sta YCAL ; 3 + clc ; 2 + lda CCAH ; 3 + adc #20 ; 2 + sta YCAH ; 3 + ;=========== + ; 16 + ; ysa=csa+xcenter; + + lda CSAL ; 3 + sta YSAL ; 3 + clc ; 2 + lda CSAH ; 3 + adc #20 ; 2 + sta YSAH ; 3 + ;=========== + ; 16 + + ; yloop, unrolled once + ;=================================================================== + ; for(yy=0;yy<40;yy++) { + ;=================================================================== + + ldy #0 ; 2 + sty YY ; 3 + +rotozoom_yloop: + + ; setup self-modifying code for plot + ; YY already in Y from end of loop +; ldy YY ; 3 + + lda common_offsets_l,Y ; lookup low-res memory address ; 4 + sta rplot2_smc+1 ; 4 + sta rplot12_smc+1 ; 4 + sta rplot22_smc+1 ; 4 + + clc ; 2 + lda gr_400_offsets_h,Y ; 4 + adc DRAW_PAGE ; add in draw page offset ; 3 + sta rplot2_smc+2 ; 4 + sta rplot12_smc+2 ; 4 + sta rplot22_smc+2 ; 4 + + + +;===================== +; unroll 0, even line +;===================== + + + ; xp=cca+ysa; 8.8 fixed point + clc ; 2 + lda YSAL ; 3 + adc CCAL ; 3 + sta XPL ; 3 + lda YSAH ; 3 + adc CCAH ; 3 + sta XPH ; 3 + ;========== + ; 20 + + ; yp=yca-csa; 8.8 fixed point + + sec ; 2 + lda YCAL ; 3 + sbc CSAL ; 3 + sta YPL ; 3 + lda YCAH ; 3 + sbc CSAH ; 3 + sta YPH ; 3 + ;=========== + ; 20 + + + + ; for(xx=0;xx<40;xx++) { + ldx #0 ; 2 +rotozoom_xloop: + + + + ;=================================================================== + ;=================================================================== + ; note: every cycle saved below here + ; saves 1600 cycles + ;=================================================================== + ;=================================================================== + + ; if ((xp<0) || (xp>39)) color=0; + ; else if ((yp<0) || (yp>39)) color=0; + ; else color=scrn_page(xp,yp,PAGE2); + + ; we know it's never going to go *that* far out of bounds + ; so we could avoid the Y check by just having "0" + ; on the edges of the screen? Tricky due to Apple II + ; interlacing + +roto_color_even_smc: + lda #0 ; default color ; 2 + + ldy XPH ; 3 + bmi rplot ; 2nt/3 + cpy #40 ; 2 + bcs rplot ; 2nt/3 + + ldy YPH ; 3 + bmi rplot ; 2nt/3 + cpy #40 ; 2 + bcs rplot ; 2nt/3 + + + +;================================================== + + ; scrn(xp,yp) + + tya ; YPH ; 2 + + lsr ; divide to get index, also low bit in carry ; 2 + tay ; 2 + + ; TODO: put these in zero page? + ; also we can share low bytes with other lookup + + lda common_offsets_l,Y ; lookup low-res memory address ; 4 + sta BASL ; 3 + lda scrn_c00_offsets_h,Y ; 4 + sta BASH ; 3 + + + ldy XPH ; 3 + lda (BASL),Y ; top/bottom color ; 5+ + + ; carry was set a bit before to low bit of YPH + ; hopefully nothing has cleared it + + bcs rscrn_adjust_odd ; 2nt/3 + +rscrn_adjust_even: + + ; YP was even so want bottom nibble + and #$f ; 2 + jmp rscrn_done ; 3 + +rscrn_adjust_odd: + ; YP was odd so want top nibble + lsr ; 2 + lsr ; 2 + lsr ; 2 + lsr ; 2 + +rscrn_done: + + + +;============================================= + + +; always even, want A in bottom of nibble +; so we are all set + +rotozoom_set_color: + ; want same color in top and bottom nibbles + ;========== + ; 0 + +;================================================= + +rplot: + + ; plot(xx,yy); (color is in A) + + ; we are in loop unroll0 so always even line here + + ; meaning we want to load old color, save top nibble, and over-write + ; bottom nibble with our value + + ; but! we don't need to save old as we are re-drawing whole screen! + +rplot_even: + +rplot2_smc: + sta $400,X ; 5 + ;============ + ; 5 + +;======================= + + ; xp=xp+ca; fixed point 8.8 + + clc ; 2 + lda CAL ; 3 + adc XPL ; 3 + sta XPL ; 3 + lda CAH ; 3 + adc XPH ; 3 + sta XPH ; 3 + + ; yp=yp-sa; fixed point 8.8 + + sec ; 2 + lda YPL ; 3 + sbc SAL ; 3 + sta YPL ; 3 + lda YPH ; 3 + sbc SAH ; 3 + sta YPH ; 3 + +rotozoom_end_xloop: + inx ; 2 + cpx #40 ; 2 + bne rotozoom_xloop ; 2nt/3 +rotozoom_xloop_done: + + + + ; yca+=ca; 8.8 fixed point + + clc ; 2 + lda YCAL ; 3 + adc CAL ; 3 + sta YCAL ; 3 + lda YCAH ; 3 + adc CAH ; 3 + sta YCAH ; 3 + ;=========== + ; 20 + + ; ysa+=sa; 8.8 fixed point + + clc ; 2 + lda YSAL ; 3 + adc SAL ; 3 + sta YSAL ; 3 + lda YSAH ; 3 + adc SAH ; 3 + sta YSAH ; 3 + ;========== + ; 20 + + +;=============== +; loop unroll 1 +;=============== + +;rotozoom_yloop: + + ; xp=cca+ysa; 8.8 fixed point + clc ; 2 + lda YSAL ; 3 + adc CCAL ; 3 + sta XPL ; 3 + lda YSAH ; 3 + adc CCAH ; 3 + sta XPH ; 3 + ;========== + ; 20 + + ; yp=yca-csa; 8.8 fixed point + + sec ; 2 + lda YCAL ; 3 + sbc CSAL ; 3 + sta YPL ; 3 + lda YCAH ; 3 + sbc CSAH ; 3 + sta YPH ; 3 + ;=========== + ; 20 + + ; for(xx=0;xx<40;xx++) { + ldx #0 ; 2 +rotozoom_xloop2: + + + + ;=================================================================== + ;=================================================================== + ; note: every cycle saved below here + ; saves 1600 cycles + ;=================================================================== + ;=================================================================== + + ; if ((xp<0) || (xp>39)) color=0; + ; else if ((yp<0) || (yp>39)) color=0; + ; else color=scrn_page(xp,yp,PAGE2); + + ; we know it's never going to go *that* far out of bounds + ; so we could avoid the Y check by just having "0" + ; on the edges of the screen? Tricky due to Apple II + ; interlacing + +roto_color_odd_smc: + lda #0 ; default color ; 2 + + ldy XPH ; 3 + bmi rplot2 ; 2nt/3 + cpy #40 ; 2 + bcs rplot2 ; 2nt/3 + + ldy YPH ; 3 + bmi rplot2 ; 2nt/3 + cpy #40 ; 2 + bcs rplot2 ; 2nt/3 + + + +;================================================== + + ; scrn(xp,yp) + + tya ; YPH ; 2 + + lsr ; divide to get index, also low bit in carry ; 2 + tay ; 2 + + ; TODO: put these in zero page? + ; also we can share low bytes with other lookup + + lda common_offsets_l,Y ; lookup low-res memory address ; 4 + sta BASL ; 3 + lda scrn_c00_offsets_h,Y ; 4 + sta BASH ; 3 + + + ldy XPH ; 3 + lda (BASL),Y ; top/bottom color ; 5+ + + ; carry was set a bit before to low bit of YPH + ; hopefully nothing has cleared it + + bcs rscrn_adjust_odd2 ; 3 + +rscrn_adjust_even2: + + ; want bottom color, but put it in top of A + asl ; 2 + asl ; 2 + asl ; 2 + asl ; 2 + + jmp rscrn_done2 ; 3 + +rscrn_adjust_odd2: + ; want top color alone + + and #$f0 ; 2 + +rscrn_done2: + + + +;============================================= + + +rotozoom_set_color2: + ; always odd + ; want color in top, which it is from above + ;========== + ; 0 + +;================================================= + +rplot2: + + ; plot(xx,yy); (color is in A) + + ; always odd, so place color in top + + ; note! since we are drawing whole screen, we know the top of + ; the value is already clear from loop=0 so we don't have to mask + +rplot_odd: +rplot12_smc: + ora $400,X ; 4 +rplot22_smc: + sta $400,X ; 5 + + ;============ + ; 9 + +;======================= + + ; xp=xp+ca; 8.8 fixed point + + clc ; 2 + lda CAL ; 3 + adc XPL ; 3 + sta XPL ; 3 + lda CAH ; 3 + adc XPH ; 3 + sta XPH ; 3 + + ; yp=yp-sa; 8.8 fixed point + + sec ; 2 + lda YPL ; 3 + sbc SAL ; 3 + sta YPL ; 3 + lda YPH ; 3 + sbc SAH ; 3 + sta YPH ; 3 + +rotozoom_end_xloop2: + inx ; 2 + cpx #40 ; 2 + bne rotozoom_xloop2 ; 3 +rotozoom_xloop_done2: + + ; yca+=ca; 8.8 fixed point + + clc ; 2 + lda YCAL ; 3 + adc CAL ; 3 + sta YCAL ; 3 + lda YCAH ; 3 + adc CAH ; 3 + sta YCAH ; 3 + ;=========== + ; 20 + + ; ysa+=sa; 8.8 fixed point + + clc ; 2 + lda YSAL ; 3 + adc SAL ; 3 + sta YSAL ; 3 + lda YSAH ; 3 + adc SAH ; 3 + sta YSAH ; 3 + ;========== + ; 20 + +rotozoom_end_yloop: + inc YY ; 5 + ldy YY ; 3 + cpy #20 ; 2 + beq done_rotozoom ; 2nt/3 + jmp rotozoom_yloop ; too far ; 3 + +done_rotozoom: + rts ; 6 + + + +fixed_sin: +; .byte $00,$00 ; 0.000000=00.00 +; .byte $00,$61 ; 0.382683=00.61 +; .byte $00,$b5 ; 0.707107=00.b5 +; .byte $00,$ec ; 0.923880=00.ec +; .byte $01,$00 ; 1.000000=01.00 +; .byte $00,$ec ; 0.923880=00.ec +; .byte $00,$b5 ; 0.707107=00.b5 +; .byte $00,$61 ; 0.382683=00.61 +; .byte $00,$00 ; 0.000000=00.00 +; .byte $ff,$9f ; -0.382683=ff.9f +; .byte $ff,$4b ; -0.707107=ff.4b +; .byte $ff,$14 ; -0.923880=ff.14 +; .byte $ff,$00 ; -1.000000=ff.00 +; .byte $ff,$14 ; -0.923880=ff.14 +; .byte $ff,$4b ; -0.707107=ff.4b +; .byte $ff,$9f ; -0.382683=ff.9f + + .byte $00,$00 ; 0.000000 + .byte $00,$31 ; 0.195090 + .byte $00,$61 ; 0.382683 + .byte $00,$8E ; 0.555570 + .byte $00,$B5 ; 0.707107 + .byte $00,$D4 ; 0.831470 + .byte $00,$EC ; 0.923880 + .byte $00,$FB ; 0.980785 + .byte $01,$00 ; 1.000000 + .byte $00,$FB ; 0.980785 + .byte $00,$EC ; 0.923880 + .byte $00,$D4 ; 0.831470 + .byte $00,$B5 ; 0.707107 + .byte $00,$8E ; 0.555570 + .byte $00,$61 ; 0.382683 + .byte $00,$31 ; 0.195090 + .byte $00,$00 ; 0.000000 + .byte $FF,$CF ; -0.195090 + .byte $FF,$9F ; -0.382683 + .byte $FF,$72 ; -0.555570 + .byte $FF,$4B ; -0.707107 + .byte $FF,$2C ; -0.831470 + .byte $FF,$14 ; -0.923880 + .byte $FF,$05 ; -0.980785 + .byte $FF,$00 ; -1.000000 + .byte $FF,$05 ; -0.980785 + .byte $FF,$14 ; -0.923880 + .byte $FF,$2C ; -0.831470 + .byte $FF,$4B ; -0.707107 + .byte $FF,$72 ; -0.555570 + .byte $FF,$9F ; -0.382683 + .byte $FF,$CF ; -0.195090 diff --git a/games/tfv/tfv_battle.s b/games/tfv/tfv_battle.s index 8b72e43b..95ff99fb 100644 --- a/games/tfv/tfv_battle.s +++ b/games/tfv/tfv_battle.s @@ -8,6 +8,12 @@ do_battle: + ;======================== + ; rotate intro + ; this happens first as it stomps on zero page + + jsr rotate_intro + ; set start position lda #34 sta HERO_X @@ -16,7 +22,7 @@ do_battle: ; reset state lda #0 - sta HERO_STATE + sta BATTLE_STATE sta MENU_STATE sta MENU_POSITION sta ENEMY_DEAD @@ -36,10 +42,7 @@ do_battle: jsr update_hero_hp jsr update_hero_mp - ;======================== - ; rotate intro - jsr rotate_intro ;======================== ; zoom to battlefield @@ -131,8 +134,8 @@ main_battle_loop: ; not dead, so draw running or standing hero_not_dead: - lda HERO_STATE - and #HERO_STATE_RUNNING + lda BATTLE_STATE + and #BATTLE_STATE_RUNNING bne battle_draw_hero_running jmp battle_draw_normal_hero @@ -270,8 +273,8 @@ update_battle_counter: ; If running, escape ; TODO: randomly fail at running? - lda HERO_STATE - and #HERO_STATE_RUNNING + lda BATTLE_STATE + and #BATTLE_STATE_RUNNING beq battle_open_menu ; we bravely ran away diff --git a/games/tfv/tfv_battle_menu.s b/games/tfv/tfv_battle_menu.s index 16788b83..a31aaf26 100644 --- a/games/tfv/tfv_battle_menu.s +++ b/games/tfv/tfv_battle_menu.s @@ -766,9 +766,9 @@ keypress_main_summon: rts keypress_main_escape: - lda #HERO_STATE_RUNNING - ora HERO_STATE - sta HERO_STATE + lda #BATTLE_STATE_RUNNING + ora BATTLE_STATE + sta BATTLE_STATE jsr done_attack rts diff --git a/games/tfv/tfv_overworld.s b/games/tfv/tfv_overworld.s index 833ca194..4f3e3e59 100644 --- a/games/tfv/tfv_overworld.s +++ b/games/tfv/tfv_overworld.s @@ -29,12 +29,10 @@ handle_overworld: ; Init Variables ;=============== - lda #$0 - sta ODD - sta ON_BIRD + lda #HERO_DIRECTION ; have us face right (1) + sta HERO_STATE lda #$1 - sta DIRECTION sta REFRESH lda #5 @@ -52,7 +50,7 @@ handle_overworld: worldmap_loop: lda #$0 - sta MOVED + sta HERO_MOVED lda TFV_X sta NEWX lda TFV_Y @@ -74,7 +72,8 @@ worldmap_handle_up: dec NEWY dec NEWY - inc MOVED + + inc HERO_MOVED jmp worldmap_done_keyboard worldmap_handle_down: @@ -83,25 +82,27 @@ worldmap_handle_down: inc NEWY inc NEWY - inc MOVED + inc HERO_MOVED jmp worldmap_done_keyboard worldmap_handle_left: cmp #'A' bne worldmap_handle_right - lda DIRECTION ; 0=left, 1=right + lda HERO_STATE + and #HERO_DIRECTION ; 0=left, 1=right beq go_left ; if (0) already left, keep going left_turn: - lda #0 ; change direction to left - sta DIRECTION - sta ODD ; stand (not walk) if changing - beq done_handle_left ; bra skip ahead + lda HERO_STATE + and #~HERO_DIRECTION ; change direction to left (0) + and #~HERO_ODD ; stand (not walk) if changing + sta HERO_STATE + jmp done_handle_left ; skip ahead go_left: dec NEWX ; decrement x - inc MOVED ; we moved + inc HERO_MOVED ; we moved done_handle_left: jmp worldmap_done_keyboard @@ -109,19 +110,20 @@ worldmap_handle_right: cmp #('D') bne worldmap_handle_enter - lda DIRECTION ; 0=left, 1=right + lda HERO_STATE + and #HERO_DIRECTION ; 0=left, 1=right bne go_right ; if (1) already right, keep going right_turn: - lda #1 ; change direction to right - sta DIRECTION - lda #0 ; change to standing - sta ODD - beq done_handle_right ; bra skip ahead + lda HERO_STATE + ora #HERO_DIRECTION ; change direction to right (1) + and #~HERO_ODD ; change to standing + sta HERO_STATE + jmp done_handle_right ; skip ahead go_right: inc NEWX ; increment X - inc MOVED + inc HERO_MOVED done_handle_right: jmp worldmap_done_keyboard @@ -172,11 +174,14 @@ worldmap_done_keyboard: ; Handle Movement ;=========================== - lda MOVED + lda HERO_MOVED beq worldmap_refresh_screen - inc ODD - inc STEPS + lda HERO_STATE ; toggle ODD + eor #HERO_ODD + sta HERO_STATE + + inc HERO_STEPS ; Handle Collision Detection @@ -420,12 +425,14 @@ back_no_forest: clc - lda #1 - bit ODD + ; check if standing + lda HERO_STATE + and #HERO_ODD bne standing walking: - lda DIRECTION ; 0=left, 1=right + lda HERO_STATE + and #HERO_DIRECTION ; 0=left, 1=right bne walking_right ; if(!0) walk right walking_left: @@ -443,7 +450,8 @@ walking_right: bcc done_walking standing: - lda DIRECTION + lda HERO_STATE + and #HERO_DIRECTION bne standing_right standing_left: lda #>tfv_stand_left_sprite @@ -709,7 +717,7 @@ fore_no_forest: cmp #3 bne no_lightning - lda STEPS + lda HERO_STEPS and #$f bne no_lightning diff --git a/games/tfv/tfv_world.s b/games/tfv/tfv_world.s index 24ceb5f9..9bda52d7 100644 --- a/games/tfv/tfv_world.s +++ b/games/tfv/tfv_world.s @@ -70,6 +70,9 @@ .include "tfv_battle_draw_hero.s" .include "rotate_intro.s" +.include "rotozoom.s" +.include "multiply_fast.s" +.include "c00_scrn_offsets.s" ;=============================================== ; Graphics diff --git a/games/tfv/zp.inc b/games/tfv/zp.inc index ec7bb336..4437ac53 100644 --- a/games/tfv/zp.inc +++ b/games/tfv/zp.inc @@ -67,20 +67,13 @@ LAST_SPACEY_I = $88 LAST_MAP_COLOR = $89 COLOR_MASK = $8A -;; World Map Only +;; rotozoom (can overlap with flying routine?) +SCALE_I = $64 ; scale of rotozoom +SCALE_F = $65 ; + + + -ODD = $7B -DIRECTION = $7C -REFRESH = $7D -ON_BIRD = $7E -MOVED = $7F -STEPS = $80 -TFV_X = $81 -TFV_Y = $82 -NEWX = $83 -NEWY = $84 -MAP_X = $85 -GROUND_COLOR = $86 ;==================GLOBAL STATE, STORED IN SAVE GAME========== WHICH_LOAD = $90 ; current level @@ -100,6 +93,24 @@ HERO_NAME3 = $9D ; 7 chars HERO_NAME4 = $9E ; 7 chars HERO_NAME5 = $9F ; 7 chars HERO_NAME6 = $A0 ; 7 chars +HERO_STATE = $A1 ; state of hero + HERO_ON_BIRD = $01 + HERO_ODD = $02 ; stand/walk position + HERO_DIRECTION = $04 ; 0=left, 1=right +HERO_STEPS = $A2 ; number of steps + +TFV_X = $A3 ; location on screen +TFV_Y = $A4 ; location on screen +MAP_X = $A5 ; which map region we're on + +;; World Map Only + +;ODD = $7B +;DIRECTION = $7C +;MOVED = $7F +;STEPS = $80 + + ;==================GAME STATE (not in save game)============== @@ -117,8 +128,8 @@ ANIMATE_LOOP = $B7 HERO_X = $C0 ; used in battle HERO_Y = $C1 ; used in battle -HERO_STATE = $C2 ; used in battle - HERO_STATE_RUNNING = $01 ; running from battle +BATTLE_STATE = $C2 ; used in battle + BATTLE_STATE_RUNNING = $01 ; running from battle BATTLE_COUNT = $C3 ; battle counter ENEMY_TYPE = $C4 ; used in battle ENEMY_HP_LO = $C5 ; enemy hitpoints @@ -165,6 +176,14 @@ FINGER_DIRECTION= $D3 ENEMY_DEAD = $D4 MAGIC_COST = $D5 ENEMY_ATTACKING = $D6 +HERO_MOVED = $D7 + +; worldmap +REFRESH = $D8 +NEWX = $D9 +NEWY = $DA +GROUND_COLOR = $DB + COLOR1 = $E0 COLOR2 = $E1