Mikes360 Posted January 6, 2015 Author Share Posted January 6, 2015 It seems to me that for some reason my ORG commands are not working correctly When I assemble the code using DASM this is a sample from the output of a table aligned to $F300 110 c23f 38 .byte.b #%00111000 111 c240 112 c240 ;============================================================================== 113 c240 ; R A I L - D A T A 114 c240 ;============================================================================== 115 c300 ORG BANK_ORIGIN + $300 116 c300 RailData 117 c300 00 0a RAIL_START = 10 118 c300 00 2e RAIL_HEIGHT = 23 * 2 119 c300 120 c300 ea nop 121 c301 RailTable1 SUBROUTINE Here is the code that sets a pointer to this table (standard macro from macro.h): SET_POINTER railGfxPtr1, RailTable1-1 And the value in the two bytes for railGfxPtr1 is $F240. Any idea why its not getting aligned correctly? Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted January 6, 2015 Share Posted January 6, 2015 The ORG looks fine to me, RailTable starts at $C301. How to you setup the two bytes of the pointer? Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted January 6, 2015 Share Posted January 6, 2015 It looks like the pointer for railGfxPtr1 is getting set before BANK_ORIGIN is getting resolved. You can see c240 above the c300 in the code snippet. So if BANK_ORIGIN is known before the macro it should work. It might be with the order of your includes. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted January 6, 2015 Share Posted January 6, 2015 (edited) Could it be that you base your pointer on RailData and not RailTable1? And BANK_ORIGIN is a constant, no? Edited January 6, 2015 by Thomas Jentzsch Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 6, 2015 Author Share Posted January 6, 2015 (edited) BANK_ORIGIN is first set like this BANK_ORIGIN SET $C000 For the start of each new bank I use this MAC NEW_BANK SEG {1} ORG BANK_ORIGIN RORG $F000 ENDM For the end of each bank I use this. MAC END_BANK ORG BANK_ORIGIN + $FFA RORG $FFFA .word {1} ; NMI .word {2} ; RESET .word {3} ; IRQ BANK_ORIGIN SET BANK_ORIGIN + $1000 CURRENT_BANK SET CURRENT_BANK + 1 ENDM Edited January 6, 2015 by Mikes360 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 6, 2015 Share Posted January 6, 2015 consider using align to make your data line up on page boundaries: align 256 YourData: .byte xx .byte xx .byte xx .byte xx ... This way you don't have to make any changes if the code before YourData expands in size. 1 Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 6, 2015 Author Share Posted January 6, 2015 (edited) Hi SpiceWare, That does work thank you very much for your recommendation, I have no idea what was going wrong before it looks ok in the debug output but in Stella itself it clearly was not getting aligned properly. This is a very handy way to line up data ill read more about it. Edited January 6, 2015 by Mikes360 Quote Link to comment Share on other sites More sharing options...
Robert M Posted January 7, 2015 Share Posted January 7, 2015 If you are willing to accept that the railing pole (at least on top) is only 3 pixels high, then you can draw the whole rail and suppport poles by skewing the P1 sprite. The sprite starts on the left and moves 2 pixels to the right each line: 01234567 XXXX X XX X XX X XX 01234567XX XX XX Then of course the sprite image data is skewed to make the support pole straight: %00001111 %00001011 %00100011 %10000011 %00000011 .. repeat this line for the height of the railing %00001000 %00100000 %10000000 Quote Link to comment Share on other sites More sharing options...
iesposta Posted January 7, 2015 Share Posted January 7, 2015 If you are willing to accept that the railing pole (at least on top) is only 3 pixels high, then you can draw the whole rail and suppport poles by skewing the P1 sprite. The sprite starts on the left and moves 2 pixels to the right each line: 01234567 XXXX X XX X XX X XX 01234567XX XX XX Then of course the sprite image data is skewed to make the support pole straight: %00001111 %00001011 %00100011 %10000011 %00000011 .. repeat this line for the height of the railing %00001000 %00100000 %10000000 That's pretty tricky, drawing the entire rail with player1! You could use its missile, being the railing color, to extend the top post. The bottom post could just continue down the screen as player1, right? Quote Link to comment Share on other sites More sharing options...
Robert M Posted January 7, 2015 Share Posted January 7, 2015 That's pretty tricky, drawing the entire rail with player1! You could use its missile, being the railing color, to extend the top post. The bottom post could just continue down the screen as player1, right? Yes, you can extend the sprite to any height at the bottom pole as long as you stop the skewing action. If you skew the sprite one pixel at a time rather than 2 you can get a pole 7 pixels high, but the railing angle is much steeper. Quote Link to comment Share on other sites More sharing options...
walaber Posted January 7, 2015 Share Posted January 7, 2015 That's a really cool method! Quote Link to comment Share on other sites More sharing options...
iesposta Posted January 7, 2015 Share Posted January 7, 2015 That's a really cool method!Yeah. Although it goes back to Stampede and Dolphin, SpiceWare used it for the Medieval Mayhem dragon, and the big Space Rocks to make them less blocky. I also like the mangled missiles and the ball object that smooth the PlayField chunky diagonals in Escape From The Mindmaster. Quite a lot of tricks if you view Stella Debug Colors. Something I can not do with batari Basic. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 7, 2015 Author Share Posted January 7, 2015 Some interesting ideas thanks Robert, I am not sure what you mean by skewing the sprite would you mind providing a example in code? Along with the rail at 2 scan line resolution I have to draw an asymmetrical play field at 2 scan line resolution and the player sprite at single line resolution so I am a bit tight for kernel time. I am using a form of Masked Draw at the moment as it seems simpler and faster than using switch draw in this context. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 7, 2015 Share Posted January 7, 2015 (edited) I am not sure what you mean by skewing the sprite would you mind providing a example in code? I talk about that here, basically you update HMP1 and hit HMOVE on every scanline in order to shift player1 left/right. I use that technique in Medieval Mayhem (the dragon and knight), Space Rocks (large asteroids) and Draconian (space stations). Look for KernelGameDragonCode in the source for Medieval Mayem. Edited January 7, 2015 by SpiceWare Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 7, 2015 Author Share Posted January 7, 2015 The idea of drawing the whole rail with one sprite is very appealing but I will need to see if the height of the first pole is too much of a compromise. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 8, 2015 Author Share Posted January 8, 2015 (edited) Hi Guys, I have finally completed a first version of my kernel for this and it gives me the following 2 scanline resolution asymmetrical scrolling playfield 2 scanline resolution handrail 1 scanline resolution player The playfield data is loaded from a RAM buffer, the rail and player is drawn using masking. Its not perfect by any stretch and I think some of you guys could optimise this more so i though I would post it here and see if you can spot any obvious improvements. Here is the main kernel: DrawFrame SUBROUTINE ldy #PLAYFIELD_START ldx #PF_BUFFER_SIZE - PF_COL_COUNT lda #PF_BLOCK_HEIGHT sta pfBlockCount sec sta WSYNC Sleep 76 - 13 ;=========================== .drawLoop PLAYER_DRAW ; 13 ;***** ; first scanline sta HMOVE ; 3 PLAYFIELD_DRAW_LEFT ; 21 dey ; 2 Sleep 2 ; 3 PLAYFIELD_DRAW_RIGHT ; 21 PLAYER_DRAW ; 13 dey ; 2 dec pfBlockCount ; 5 CLEAR_PLAYFIELD_GFX ; 11 ;***** ; second scanline RAIL_DRAW ; 43 lda pfBlockCount ; 3 bne .skipNewBlock ; 2,3 txa ; 2 sbc #PF_COL_COUNT ; 2 tax ; 2 lda #PF_BLOCK_HEIGHT ; 2 sta pfBlockCount ; 3 bcs .drawLoop ; 2,3 - 15,16 jmp Endframe .skipNewBlock Sleep 11 jmp .drawLoop ; 3 Endframe CLEAR_PLAYFIELD_GFX sta GRP0 ; a = zero from macro sta ENAM0 sta ENAM1 jmp Bottom There are a number of macros in here which I added to make the logic more readable they are below: ;============================================================================== MAC PLAYFIELD_DRAW_LEFT lda pfBuffer,x ; 4 sta PF0 ; 3 lda pfBuffer+1,x ; 4 sta PF1 ; 3 lda pfBuffer+2,x ; 4 sta PF2 ; 3 - 21 ENDM ;============================================================================== MAC PLAYFIELD_DRAW_RIGHT lda pfBuffer+3,x ; 4 sta PF0 ; 3 lda pfBuffer+4,x ; 4 sta PF1 ; 3 lda pfBuffer+5,x ; 4 sta PF2 ; 3 - 21 ENDM ;============================================================================== MAC CLEAR_PLAYFIELD_GFX lda #0 ; 2 sta PF0 ; 3 sta PF1 ; 3 sta PF2 ; 3 - 11 ENDM ;============================================================================== MAC RAIL_DRAW lda (railGfxPtr1),y ;5 and (railMaskPtr),y ;5 sta ENAM0 ;3 lda (railGfxPtr2),y ;5 and (railMaskPtr),y ;5 sta ENAM1 ;3 lda (railMovePtr),y ;5 and (railMaskPtr),y ;5 sta HMM1 ;3 ENDM ;============================================================================== MAC PLAYER_DRAW lda (playerGfxPtr),y ;5 and (playerMaskPtr),y ;5 sta GRP0 ;3 - 13 ENDM ;============================================================================== If anyone is interested in seeing the full source code let me know and ill post it. Edited January 8, 2015 by Mikes360 Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 8, 2015 Author Share Posted January 8, 2015 Here is a couple of new screen shots showing the player, rail and playfield all being drawn together. 1 Quote Link to comment Share on other sites More sharing options...
walaber Posted January 9, 2015 Share Posted January 9, 2015 This is looking awesome! I'm surprised how good the skater looks even at such low resolution. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 9, 2015 Author Share Posted January 9, 2015 Thanks I am pretty happy with the result graphically. However in order to achieve this I have had to use a masking technique for both the player and rail which adds 20 cycles. 5 cycles every time you and the graphics or move value with a mask before storing it a register. I think its definitely better than skip draw which I used in my point zero game but there are looking forward some tricky challenges with ensuring the graphics is laid out in a way to never cross a page boundary when I load it from the relevant tables. I am planning on this being an F6 16K game so I am willing to take the hit on the ROM for the graphics tables in order to achieve the efficiency in the main drawing kernel. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 10, 2015 Author Share Posted January 10, 2015 I have been in the process of trying to optimise what I have to get some more cycles back in the Kernel, I have found a simple but significant saving for both the kernel and ROM. The kinked and bottom vertical part of the rail are always being drawn when the mask is off so you can completely remove the need for a table to draw this. So now drawing the rail goes from this MAC RAIL_DRAW lda (railGfxPtr1),y ;5 and (railMaskPtr),y ;5 sta ENAM0 ;3 lda (railGfxPtr2),y ;5 and (railMaskPtr),y ;5 sta ENAM1 ;3 lda (railMovePtr),y ;5 and (railMaskPtr),y ;5 sta HMM1 ;3 ENDM To this MAC RAIL_DRAW lda (railGfxPtr1),y ;5 and (railMaskPtr),y ;5 sta ENAM0 ;3 lda #2 and (railMaskPtr),y ;5 sta ENAM1 ;3 lda (railMovePtr),y ;5 and (railMaskPtr),y ;5 sta HMM1 ;3 ENDM Saving 3 cycles in the kernel and loads of ROM space as the table needed padding for the masking. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 10, 2015 Author Share Posted January 10, 2015 Secondly I have clipped the playfield by mirroring it and not setting PF0. I noticed walaber is doing this in the Moto X game and with the HMOVE lines issue it just seems like a no brainer. This saves me 14 cycles a total of 17 when coupled with the first saving, there is also an additional RAM saving with this too as I was actually using 2 bytes for each row of my playfield for the PF0 data. I should now be able to get kinked and sparks going on now! Quote Link to comment Share on other sites More sharing options...
walaber Posted January 10, 2015 Share Posted January 10, 2015 I think you could also use the SAX command, which ANDs A and X and then stores the result. That way you only load the mask once and reuse it multiple times LDA (maskPtr),Y TAX ... LDA (gfxPtr),Y SAX ENAM1 LDA (movePtr),Y SAX HMM1 1 Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 10, 2015 Author Share Posted January 10, 2015 Is SAX considered a stable illegal opcode? Quote Link to comment Share on other sites More sharing options...
Kylearan Posted January 10, 2015 Share Posted January 10, 2015 Yes, it's stable (and I call it "undocumented" instead of "illegal" :-P) Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted January 10, 2015 Author Share Posted January 10, 2015 Ill try it out then thanks for the tip :-) 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.