vdub_bobby Posted February 22, 2005 Share Posted February 22, 2005 Is there a faster way to display a variable-height ball/missile in the 2600 than this: lda BallHeight dcp BallY sbc BallHeight sta ENABL ;+14 Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted February 22, 2005 Share Posted February 22, 2005 Hi there! Is there a faster way to display a variable-height ball/missile in the 2600 than this: lda BallHeight dcp BallY sbc BallHeight sta ENABL ;+14 Hm... lda BallHeight dcp BallY rol sta ENABL maybe? Greetings, Manuel Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 22, 2005 Author Share Posted February 22, 2005 lda BallHeight dcp BallY rol sta ENABL maybe? Greetings, Manuel Don't you need two 'rol's? Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted February 22, 2005 Share Posted February 22, 2005 Hi there! Don't you need two 'rol's? You're right, yes... sorry Greetings, Manuel Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 22, 2005 Share Posted February 22, 2005 Redundancy? It seems to me that if your sprite is #N lines, you could just execute a routine that produces #N lines. The check is being done once before you need it, and no time is being wasted checking in lines that do need it. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 22, 2005 Author Share Posted February 22, 2005 Redundancy? It seems to me that if your sprite is #N lines, you could just execute a routine that produces #N lines. The check is being done once before you need it, and no time is being wasted checking in lines that do need it. I don't follow this exactly...could you explain a little further? Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 22, 2005 Share Posted February 22, 2005 Maybe if I understood it's use a bit clearer You need: To save cycles when dealing with variable heights. Solution: Write specific kernal portions dealing with each specific height. Getting there via indirect jumps maybe? Makes a lotta rom overhead, but it's one way of saving cycles. Quote Link to comment Share on other sites More sharing options...
DEBRO Posted February 22, 2005 Share Posted February 22, 2005 lda BallHeight dcp BallY rol sta ENABL maybe? Greetings, Manuel Don't you need two 'rol's? So are you using the carry bit to enable the ball? If you were able to use the Z status you could use the old Combat trick of pointing the stack to the ENABL register and php the status after the subtraction. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 22, 2005 Author Share Posted February 22, 2005 Maybe if I understood it's use a bit clearer You need: To save cycles when dealing with variable heights. Solution: Write specific kernal portions dealing with each specific height. Getting there via indirect jumps maybe? Makes a lotta rom overhead, but it's one way of saving cycles. I think we are talking past each other I need to draw the ball like you normally draw a player - it can show up on any scanline and can be any height. I.e., I am drawing a line (not a point, so I can't do what DEBRO suggested, 'cpy BallY php' - at least I haven't figured out a way to do it). I am drawing a vertical line that can be of variable length (varying between 1 and ~8 scanlines tall) and it can appear anywhere on the screen. Some other possibilities I have come up with are the code cybergoth suggested (15 cycles) and, if I can restrict my variable heights to intervals of four, this: lda BallHeight dcp BallY sbc #ADJUSTER sta ENABL ;+13 Where, for example, if BallHeight = 0, 3, 7, 11, etc. then ADJUSTER = 0. And I don't have time to do jumps, indirect or otherwise , in my kernel. This is specifically for the Prince of Persia kernel I am messing around with where I am drawing an asymmetrical PF every scanline and the ball and both players every other scanline; I have zero extra cycles in my kernel right now. As far as I know, the SkipDraw routine is the fastest way to draw a sprite (assuming you need constant cycles and without giant tables as tall as the screen) anyone has come up with, but I haven't ever read anything about the fastest way to draw a ball/missile when it is taller than one scanline. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 22, 2005 Share Posted February 22, 2005 I knew I didn't describe that well enough What I was trying to describe is unrolling a display loop. You no longer would need to CPY and such because that specific kernal already "knows" the height and already has the ball sprite enabled. You save cycle time because no loop is used and no tests are needed. The indirect jump I was referring to happens on the scanlines above the player (where you have the time to do the test, because the sprites aren't being drawn there). Could you post the attempted routine for your "draw player+sword" loop (the one that's using too many cycles)? Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted February 22, 2005 Share Posted February 22, 2005 Is there a faster way to display a variable-height ball/missile in the 2600 than this: lda BallHeight dcp BallY sbc BallHeight sta ENABL ;+14 Clever code! Hm, I did something like this in Cave1K: tya sbc yWall1 adc hWall1 lda #$00 adc #$01 sta ENABL ; = 15 But your code is faster. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 22, 2005 Author Share Posted February 22, 2005 I knew I didn't describe that well enough What I was trying to describe is unrolling a display loop. You no longer would need to CPY and such because that specific kernal already "knows" the height and already has the ball sprite enabled. You save cycle time because no loop is used and no tests are needed. The indirect jump I was referring to happens on the scanlines above the player (where you have the time to do the test, because the sprites aren't being drawn there). Could you post the attempted routine for your "draw player+sword" loop (the one that's using too many cycles)? Well, it isn't taking too many cycles now...but if I could cut a few cycles off I could maybe squeeze one of the missiles into the loop somewhere. So here's the code. Actually, I'm not currently using the 'fastest' routine I posted above, I'm using the one Cybergoth suggested. sta WSYNC nop ldy #PLAYAREAHEIGHT-1 ;+2 4 ldx #PLAYAREAHEIGHT-2 ;+2 6 lda (PFColorPtr),Y sta COLUPF ;+8 14 SLEEP 5 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 PlayAreaLoop lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P1HEIGHT-1 ;+2 58 dcp P1YPosition ;+5 63 bcs DoDraw2 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw2 lda (PlayerPtrR),Y ;+5 71 sta GRP1 ;+3 74 lda (Player2ColorPtr),Y sta COLUP1 ;+8 6 lda SwordHeight cmp SwordYPosition rol rol sta ENABL ;+13 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P0HEIGHT-1 ;+2 58 dcp P0YPosition ;+5 63 bcs DoDraw1 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw1 lda (PlayerPtrL),Y ;+5 71 sta GRP0 ;+3 74 dey sta HMOVE ;+3 3 lda (PlayerColorPtr),Y ;+5 sta COLUP0 ;+3 11 lda (PFColorPtr),Y sta COLUPF ;+8 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dex bpl PlayAreaLoop ;+4/5 40 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted February 22, 2005 Share Posted February 22, 2005 Maybe it's time to share my code too? .skipDraw1: ; 5 @30 sec ; 2 sbc yP0 ; 3 adc #PLAYER_H ; 2 = 7 SLEEP 4 ; 4 = 4 lda pf2RLst0,x ; 4 sta PF2 ; 3 @48 *!* lda pf1RLst0,x ; 4 sta PF1 ; 3 = 14 @55 SLEEP 6 ; 6 = 6 lda #0 ; 2 sta GRP1 ; 3 sta ENAM1 ; 3 @69 bcs .contDraw1a ; 2³= 10/11 bcc .skipDraw0a ; 3 .skipDraw0: ;10 @60 lda (ptrC1),y ; 5 sta.w COLUP1 ; 4 @69 adc #$fc ; 2 sta ENAM1 ; 3 = 13 @74 .skipDraw0a: sec ; 2 ;--------------------------------------- sta.w HMOVE ; 3 @04 lda #0 ; 2 sta GRP0 ; 3 beq .contDraw0 ; 3 @12 .nextRow: SLEEP 4 ; 4 = 4 .nextBlock: ; @63 sbc yP1 ; 3 adc #ENEMY_H ; 2 = 5 lda colLst0,x ; 4 sta COLUPF ; 3 = 7 @75 ;--------------------------------------- SLEEP 12 ;12 12 free cycles lda pf1LLst0,x ; 4 sta PF1 ; 3 @18 lda pf2LLst0,x ; 4 sta PF2 ; 3 = 14 @25 tya ; 2 bcc .skipDraw1 ; 2³= 4/5 sbc yP0 ; 3 adc #PLAYER_H ; 2 = 5 lda pf1RLst0,x ; 4 sta PF1 ; 3 @41 lda pf2RLst0,x ; 4 sta PF2 ; 3 = 14 @48 *!* lda (ptrP1),y ; 5 sta.w GRP1 ; 4 = 9 @VDEL! 1 cycle to optimize! bcc .skipDraw0 ; 2³= 9/10 lda (ptrC1),y ; 5 sta COLUP1 ; 3 @67 >=@70! adc #$fc ; 2 sta ENAM1 ; 3 = 13 @72 >=@70! .contDraw1a: lda (ptrP0),y ; 5 = 5 ;--------------------------------------- sta HMOVE ; 3 @04 sta GRP0 ; 3 @07 lda (ptrC0),y ; 5 = 11 .contDraw0: ; @12 sta COLUP0 ; 3 @15 adc #$fc ; 2 sta ENAM0 ; 3 = 8 @20 lda pf1LLst0,x ; 4 sta PF1 ; 3 @27 lda pf2LLst0,x ; 4 sta PF2 ; 3 @34 lda pf1RLst0,x ; 4 sta PF1 ; 3 @41 lda pf2RLst0,x ; 4 sta PF2 ; 3 = 28 @48 *!* dey ; 2 tya ; 2 cmp BlockTbl,x ; 4 bne .nextRow ; 2³ dex ; 2 bpl .nextBlock ; 2³= 15 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted February 22, 2005 Share Posted February 22, 2005 Hm, probably this code should belong into the PoP thread... Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 22, 2005 Share Posted February 22, 2005 Actually, I'm not currently using the 'fastest' routine I posted above, I'm using the one Cybergoth suggested. Thanks for posting it. This is an example of redundancy below. Notice how the loop is no longer a loop...but just a string of code. What this does is free 5 cycles from the bottom of each group, in addition to freeing up the X register (so you should be able to come up with a better use for it). I didn't look at the variables too closely, but eliminating the compare in each group will also be possible now that the X register is free to use. sta WSYNC nop ldy #PLAYAREAHEIGHT-1 ;+2 4 ldx #PLAYAREAHEIGHT-2 ;+2 6 lda (PFColorPtr),Y sta COLUPF ;+8 14 SLEEP 5 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 ;changes begin here... ;PlayAreaLoop ... label not needed lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P1HEIGHT-1 ;+2 58 dcp P1YPosition ;+5 63 bcs DoDraw2_1 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw2_1 lda (PlayerPtrR),Y ;+5 71 sta GRP1 ;+3 74 lda (Player2ColorPtr),Y sta COLUP1 ;+8 6 lda SwordHeight cmp SwordYPosition rol rol sta ENABL ;+13 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P0HEIGHT-1 ;+2 58 dcp P0YPosition ;+5 63 bcs DoDraw1_1 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw1_1 lda (PlayerPtrL),Y ;+5 71 sta GRP0 ;+3 74 dey sta HMOVE ;+3 3 lda (PlayerColorPtr),Y ;+5 sta COLUP0 ;+3 11 lda (PFColorPtr),Y sta COLUPF ;+8 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 NOP ;2 free STA $2D;3 free 40 ;next group lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P1HEIGHT-1 ;+2 58 dcp P1YPosition ;+5 63 bcs DoDraw2_2 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw2_2 lda (PlayerPtrR),Y ;+5 71 sta GRP1 ;+3 74 lda (Player2ColorPtr),Y sta COLUP1 ;+8 6 lda SwordHeight cmp SwordYPosition rol rol sta ENABL ;+13 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P0HEIGHT-1 ;+2 58 dcp P0YPosition ;+5 63 bcs DoDraw1_2 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw1_2 lda (PlayerPtrL),Y ;+5 71 sta GRP0 ;+3 74 dey sta HMOVE ;+3 3 lda (PlayerColorPtr),Y ;+5 sta COLUP0 ;+3 11 lda (PFColorPtr),Y sta COLUPF ;+8 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 NOP ;2 free STA $2D;3 free 40 ;next group lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P1HEIGHT-1 ;+2 58 dcp P1YPosition ;+5 63 bcs DoDraw2_3 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw2_3 lda (PlayerPtrR),Y ;+5 71 sta GRP1 ;+3 74 lda (Player2ColorPtr),Y sta COLUP1 ;+8 6 lda SwordHeight cmp SwordYPosition rol rol sta ENABL ;+13 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 dec SwordYPosition ;+5 40 lda (PF3Ptr),Y sta PF2 ;+8 48 lda (PF4Ptr),Y sta PF1 ;+8 56 lda #P0HEIGHT-1 ;+2 58 dcp P0YPosition ;+5 63 bcs DoDraw1_3 ;+2/3 65/66 lda #0 ;+2 67 .byte $2C ;-1 66 DoDraw1_3 lda (PlayerPtrL),Y ;+5 71 sta GRP0 ;+3 74 dey sta HMOVE ;+3 3 lda (PlayerColorPtr),Y ;+5 sta COLUP0 ;+3 11 lda (PFColorPtr),Y sta COLUPF ;+8 19 lda (PF1Ptr),Y sta PF1 ;+8 27 lda (PF2Ptr),Y sta PF2 ;+8 35 NOP ;2 free STA $2D;3 free 40 ;next group ;etc...etc... Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 22, 2005 Author Share Posted February 22, 2005 Actually, I'm not currently using the 'fastest' routine I posted above, I'm using the one Cybergoth suggested. Thanks for posting it. This is an example of redundancy below. Notice how the loop is no longer a loop...but just a string of code. What this does is free 5 cycles from the bottom of each group, in addition to freeing up the X register (so you should be able to come up with a better use for it). I didn't look at the variables too closely, but eliminating the compare in each group will also be possible now that the X register is free to use. Ok, now I understand what you mean! Unfortunately, since I loop 64 times, that solution probably isn't feasible. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted February 22, 2005 Share Posted February 22, 2005 Unfortunately, since I loop 64 times, that solution probably isn't feasible. You wouldn't need 64 copies if a test is done before the top WSYNC to decide when to jump to this section (this is designed to display the players...none of that code is needed if the players don't exist on the scanlines) Since those cycles would be free, there's plenty of time to check when players are coming up...and then branch to this. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted February 25, 2005 Author Share Posted February 25, 2005 Is there a faster way to display a variable-height ball/missile in the 2600 than this: lda BallHeight dcp BallY sbc BallHeight sta ENABL ;+14 Well, I got around to actually using this in a program, and it doesn't work Turns out I had the carry states backwards in my head. This will work though: lda BallHeight dcp BallY sbc BallAdjuster sta ENABL ;+14 Where BallAdjuster = BallHeight - 2 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.