ZackAttack Posted January 11, 2015 Share Posted January 11, 2015 I've created a macro to position player0 and was hoping I could get someone to test it on real hardware for me. It only uses 72 CPU cycles and supports a horizontal position from 0 through 157. Left/Right on joystick moves sprite back and forth. Hold fire to step the movement 1 pixel per joystick movement. I'm including the bin and the asm file. Any feedback is appreciated. Thanks. positionMacro.bin positionMacro.asm Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 12, 2015 Author Share Posted January 12, 2015 I was able to increase the range to 0-160. 160 is equivalent to 0, but it could be useful for smoothly moving the player off the right side of the screen. The ides behind this algorithm is that it uses the division by 15 to create the delay required to position the RESP0 strobe. The remainder is used for fine movement of course. Since the division itself produces the delay, there is no need to track the quotient. Bit 7 in PlayerX is used to decide if the player is on the left or right side of the screen. This gives enough time to calculate and set HMP0 on the same scan line. I wrote this cause I couldn't find any existing code to do this. If there is a better way to do it, I'd like to know. I couldn't figure out how to edit my original post so I'll attach the files here. positionMacro.asm positionMacro.bin Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 12, 2015 Share Posted January 12, 2015 The divide by seven trick is well known a routine like this is commonly used HorizontalPositioning SUBROUTINE sta WSYNC sec .loopDivideBy15 sbc #15 bcs .loopDivideBy15 tay lda fineAdjustTable,y sta HMP0,x sta RESP0,x rts fineAdjustTable is a table of values to store in the HMPx register based on the remainder of the divide loop. fineAdjustBegin .byte %01110000 ; Left 7 .byte %01100000 ; Left 6 .byte %01010000 ; Left 5 .byte %01000000 ; Left 4 .byte %00110000 ; Left 3 .byte %00100000 ; Left 2 .byte %00010000 ; Left 1 .byte %00000000 ; No movement. .byte %11110000 ; Right 1 .byte %11100000 ; Right 2 .byte %11010000 ; Right 3 .byte %11000000 ; Right 4 .byte %10110000 ; Right 5 .byte %10100000 ; Right 6 .byte %10010000 ; Right 7 fineAdjustTable EQU fineAdjustBegin - %11110001 ; NOTE: %11110001 = -15 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 12, 2015 Share Posted January 12, 2015 (edited) Came up with it on your own? Not bad. This is what we tend to use: PosObject: ; A holds X value sec ; 2 sta WSYNC ; X holds object, 0=P0, 1=P1, 2=M0, 3=M1, 4=Ball DivideLoop: sbc #15 ; 2 bcs DivideLoop ; 2 4 eor #7 ; 2 6 asl ; 2 8 asl ; 2 10 asl ; 2 12 asl ; 2 14 sta.wx HMP0,X ; 5 19 sta RESP0,X ; 4 23 <- set object position SLEEP12: rts ; 6 29 Benefits are it works for all objects, and it eliminates the table. Disadvantage is it sometimes goes to a second scanline. That SLEEP12 label at the end is used for wasting 12 cycles by doing a jsr SLEEP12. If you check my blog you'll find source code for all my projects (with the exception of Stay Frosty 2, whose source will be eventually posted as part of my The Story of Stay Frosty 2 blog series). Edited January 12, 2015 by SpiceWare Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted January 12, 2015 Share Posted January 12, 2015 And that very trick was (re)discovered in Battlezone by Cybergoth some years ago. 1 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted January 12, 2015 Author Share Posted January 12, 2015 Came up with it on your own? Not bad. This is what we tend to use: PosObject: ; A holds X value sec ; 2 sta WSYNC ; X holds object, 0=P0, 1=P1, 2=M0, 3=M1, 4=Ball DivideLoop: sbc #15 ; 2 bcs DivideLoop ; 2 4 eor #7 ; 2 6 asl ; 2 8 asl ; 2 10 asl ; 2 12 asl ; 2 14 sta.wx HMP0,X ; 5 19 sta RESP0,X ; 4 23 <- set object position SLEEP12: rts ; 6 29 Benefits are it works for all objects, and it eliminates the table. Disadvantage is it sometimes goes to a second scanline. That SLEEP12 label at the end is used for wasting 12 cycles by doing a jsr SLEEP12. If you check my blog you'll find source code for all my projects (with the exception of Stay Frosty 2, whose source will be eventually posted as part of my The Story of Stay Frosty 2 blog series). This is really nice. I will definitely use this routine when I need to position multiple objects and the extra scanline/cycles can be tolerated. The 8way scrolling engine I'm constructing only needs to position P0 in this manner. I guess once I run out of CPU cycles or ROM bytes I'll know which approach is right for that project. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 12, 2015 Share Posted January 12, 2015 And that very trick was (re)discovered in Battlezone by Cybergoth some years ago. Thanks, I didn't know where it came from. This is really nice. I will definitely use this routine when I need to position multiple objects and the extra scanline/cycles can be tolerated. The 8way scrolling engine I'm constructing only needs to position P0 in this manner. I guess once I run out of CPU cycles or ROM bytes I'll know which approach is right for that project. Have you seen my series Collect? I go through the creation of a simple 2K game. Be sure to download and read the source code for each step, I put in way more comments than normal. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.