Acorn Arcade forums: Programming: Sprite clipping
|
Sprite clipping |
|
andreww (11:34 27/2/2002) johnstlr (12:29 27/2/2002) andreww (13:51 27/2/2002) Phlamethrower (15:03 27/2/2002) andreww (15:37 27/2/2002) Loris (17:05 27/2/2002) johnstlr (10:07 28/2/2002) andreww (21:48 5/3/2002) andreww (21:56 5/3/2002) davidm (14:13 7/3/2002) andreww (14:41 7/3/2002) andreww (14:43 7/3/2002) Loris (17:45 7/3/2002) Phlamethrower (18:51 7/3/2002) andreww (19:37 7/3/2002) Phlamethrower (19:39 7/3/2002) andreww (21:52 7/3/2002)
|
|
Andrew |
Message #86212, posted by andreww at 11:34, 27/2/2002 |
AA refugee
Posts: 555
|
I'm trying to clip the left hand side of a sprite in an assembler sprite plotter.I'm checking the x-coordinate to see if it's negative before plotting and if so I add an offset to the sprite data for each scan line of plotting (as of course this amount won't be needed since it's offscreen) and also calculate the bytes to plot with a deduction for the clipping. Does this seem right? I'm yet to get it to work? regards Andrew |
|
[ Log in to reply ] |
|
Lee Johnston |
Message #86213, posted by johnstlr at 12:29, 27/2/2002, in reply to message #86212 |
Member
Posts: 193
|
If "spriteData" points to the start of a row then surely all you have to do is spriteData -= left coordinate where left coordinate is obviously a negative number. This of course assumes you don't have some fancy, optimised, sprite format. |
|
[ Log in to reply ] |
|
Andrew |
Message #86214, posted by andreww at 13:51, 27/2/2002, in reply to message #86213 |
AA refugee
Posts: 555
|
Hi Lee, Yes it should point to the start of a data row containing extracted words of 32K sprite data. Therefore I'm trying to calculate the bytes which arent plotted when the x-plot position is less than the width (maybe I have not divided width in bytes by 2 to get pixels). This value I'm then adding on to each pass of the loop which plots each row of the sprite before it accesses the data so it knows how much to deduct from the plot. There is a corresponding reduction in bytes plotted per line as well. It's one of those problems which gets out of control and plots throughout the memory until the program crashes. |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #86215, posted by Phlamethrower at 15:03, 27/2/2002, in reply to message #86214 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
OK, the technique which I tend to use is to have two seperate widths for the sprite - the number of pixels you need to draw on each row, and the amount of memory to move on at the end of each row in order to get to the correct start of the next. This allows you to enter a simple loop to draw n pixels, then add the 'skip amount' onto the sprite pointer you ended the loop with (And reload the number of pixels from the stack or some temp register): spr=Pointer to sprite w=sprite width (Pixels) x=x-pos on screen scr=Screen adr sw=Screen width (Pixels) MOV pix,w ; Get how many pixels to draw MOV skip,#0 ; Number of bytes of sprite to skip at the end of each row CMP x,#0 ; Off left hand edge? ADDLT pix,pix,x ; Yes, so decrease number of pixels to draw SUBLT pix,pix,x,LSL #1 ; And shift sprite ptr on to skip those pixels SUBLT skip,skip,x,LSL #1 ; And increase number of bytes to skip at end of row ADDGT scr,scr,x,LSL #1 ; No, so shift the screen pointer across ADD x,x,w ; Get right hand edge of sprite SUBS x,x,sw ; Get number of pixels it goes off the right hand edge SUBGT pix,pix,x ; If off the edge, decrease number to draw... ADDGT skip,skip,x,LSL #1 ; And increase the amount to skip at the end of each row That's essentially it for X-clipping, although depending on how you treat the screen memory it may be different - e.g. you may need a screen skip amount to shift the screen ptr on at the end of each row as well. Also I haven't thought about the right hand edge too much, so don't be surprised if it clips too soon or too late if you use the above code. The technique your using sounds OK, but you may be able to get an extra register or two free if you use mine |
|
[ Log in to reply ] |
|
Andrew |
Message #86216, posted by andreww at 15:37, 27/2/2002, in reply to message #86215 |
AA refugee
Posts: 555
|
Hi (Mr.)Lee, That sounds very similar to what I'm doing. I'll have a have a look tonight and get back as I think the problem may be the discrepancy between width in pixels and bytes is not being taken account of at some point. |
|
[ Log in to reply ] |
|
Tony Haines |
Message #86217, posted by Loris at 17:05, 27/2/2002, in reply to message #86216 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
Looks to me like it should work...It's one of those problems which gets out of control and plots throughout the memory until the program crashes. Are you remembering to decrement the number of rows counter? (Or is it getting corrupted?) Are you sure the whole sprite is plotted to the screen? I don't think you need to be more than 1 byte outside screen-space to crash the thing. Have you got an already working non-clipped plotter? I recommend that unless you are really concentrating on the borders (possible I suppose), you have a seperate routines for clipped and non-clipped. One thing I like to do is have the left- and right-clipping routines sharing the same plot routine. The left side just needs to have the off-screen width added on to the sprite data pointer (etc) before falling through to somewhere near the start of the right-clipping routine. Or summat. Yours, Tony |
|
[ Log in to reply ] |
|
Lee Johnston |
Message #86218, posted by johnstlr at 10:07, 28/2/2002, in reply to message #86217 |
Member
Posts: 193
|
Hi (Mr.)Lee, That sounds very similar to what I'm doing. I'll have a have a look tonight and get back as I think the problem may be the discrepancy between width in pixels and bytes is not being taken account of at some point. As others have pointed out, if you're plotting in 32K colours and you know how many PIXELS you're off the left hand side by then you need spriteData -= (amount off edge * 2) |
|
[ Log in to reply ] |
|
Andrew |
Message #86219, posted by andreww at 21:48, 5/3/2002, in reply to message #86218 |
AA refugee
Posts: 555
|
Here's what I'm doing. I'm not looking for ways to do this better or more efficiently and I want to use this routine for the left-hand clipping but I would appreciate if you could point out where I may be going wrong. Ths is the plotting routine for the left-hand clipping - the plotter is in 32K mode and te sprite moves in multiples of 4 bytes. R1 contains the screenbase address with an offset for y-position and a copy is kept in R10 unaltered:.collob_plotlooplc MOV R3,R8 ; place copy of width in pixels into R3 ADD R5,R5,R6 ; offset sprite data pointer (R6 contains bytes) ; .bytelooplc LDR R4,[R5],#4 MOV R7,#255 ORR R7,R7,#65280 ;R7=&FFFF AND R9,R4,R7 ; get lower two bytes of word CMP R9,#0 ADDEQ R1,R1,#2 STRNEB R9,[R1],#1 MOVNE R9,R9,LSR#8 STRNEB R9,[R1],#1 ; MOV R7,#255 ORR R7,R7,#65280 ;R7=&FFFF MOV R4,R4,LSR#16 AND R9,R4,R7 ; get lower two bytes of word CMP R9,#0 ADDEQ R1,R1,#2 STRNEB R9,[R1],#1 MOVNE R9,R9,LSR#8 STRNEB R9,[R1],#1 ; SUBS R3,R3,#2 BNE bytelooplc ; ADD R12,R12,#1 MOV R11,#1280 MUL R11,R12,R11 ADD R1,R10,R11 SUBS R2,R2,#1 BNE collob_plotlooplc |
|
[ Log in to reply ] |
|
Andrew |
Message #86220, posted by andreww at 21:56, 5/3/2002, in reply to message #86219 |
AA refugee
Posts: 555
|
I should have said these are the calculation before the above routine. R7 contains the position on the scanline in bytes, therefore the first position offscreen will be -4 as it moves in steps of 4.MOV R3,R3,LSL#1 ; width in pixels of sprite (R3 originally contains width in words) RSB R7,R7,#0 ; MOV R7,R7,LSR#1 ; convert clipped bytes to pixels SUB R8,R3,R7 ; calculate width in pixels by taking off clipped pixel no. MOV R7,R7,LSL#1 ; bytes to be clipped MOV R6,R7 ; MOV R11,#1280 MUL R11,R4,R11 ; R4 contains y-pos (intially 0) ADD R1,R1,R11 ; starting position address of sprite (R1 screenbase) MOV R10,R1 ; put copy in R10 |
|
[ Log in to reply ] |
|
David McEwen |
Message #86221, posted by davidm at 14:13, 7/3/2002, in reply to message #86220 |
Member
Posts: 100
|
Umm... where do you set the x offset for the sprite onscreen ? Do you ensure that the first pixel plotted is on screen ? Oh yeah... I assumed R2 is the height of the sprite. It's pretty awkward to spot probs in asm in a forum. Other than working a strange way the above is all I could think of. |
|
[ Log in to reply ] |
|
Andrew |
Message #86222, posted by andreww at 14:41, 7/3/2002, in reply to message #86221 |
AA refugee
Posts: 555
|
Umm... where do you set the x offset for the sprite onscreen ?AW: In basic px%=0 and moves in blocks of 4 before being set as an integer. Do you ensure that the first pixel plotted is on screen ? AW: I think so but could be the problem. I get 2 sprites plotted of half the height and with the rest filled with junk!?? Oh yeah... I assumed R2 is the height of the sprite. AW: yes. It's pretty awkward to spot probs in asm in a forum. Other than working a strange way the above is all I could think of. A.W.:Some (but please don't) may say I'm a quite strange kind of bloke.
[Edited by andreww at 14:45, 7/3/2002] |
|
[ Log in to reply ] |
|
Andrew |
Message #86223, posted by andreww at 14:43, 7/3/2002, in reply to message #86222 |
AA refugee
Posts: 555
|
Umm... where do you set the x offset for the sprite onscreen ?AW: In basic px%=0 and moves in blocks of 4 before being set as an integer. Do you ensure that the first pixel plotted is on screen ? AW: I think so but could be the problem. I get 2 sprites plotted of half the height and with the rest filled with junk!?? Oh yeah... I assumed R2 is the height of the sprite. AW: yes. It's pretty awkward to spot probs in asm in a forum. Other than working a strange way the above is all I could think of. A.W.:Some (but please don't) may say I'm a quite strange kind of bloke.
[Edited by andreww at 14:45, 7/3/2002] |
|
[ Log in to reply ] |
|
Tony Haines |
Message #86224, posted by Loris at 17:45, 7/3/2002, in reply to message #86223 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
Hmm. The quoting seems to be odd. Please forgive me if any of this is wrong - I've only scanned through the code.
Do you ensure that the first pixel plotted is on screen ? AW: I think so but could be the problem. I get 2 sprites plotted of half the height and with the rest filled with junk!?? Sounds to me like 2 problems...What screenwidth are you using? Appearing to have two half-height sprites is fairly common to me. It means you've only added on half the screen-width. If you examine the two half-height sprites you should find that they are slightly different, being the odd and even sprite row datas. If your screen width is 1280 pixels it will be double that in bytes, in 32thou. colours. Oh yeah... I assumed R2 is the height of the sprite. AW: yes. Do you set it to that? You haven't in the code you have posted. As a trial, try setting it explicitly at the start of the routine, you may be reading the wrong value from the wrong address for example. For what its worth, I've not checked any of your code in any detail; it might be doing just about anything and I wouldn't have noticed, instead I used your discriptions of the effect produced (that is how I debug - use Zen ) HTH. Yours, Tony |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #86225, posted by Phlamethrower at 18:51, 7/3/2002, in reply to message #86224 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
*pieces together code* (Amendmended lines are marked with 's) ; Entry data: ; Screen (Presumably) 640x?, 16bpp ; R1 = screen base ptr ; R2 = sprite height ; R3 = sprite width in words ; R4 = sprite y pos ; R7 = position on the scanline in bytes, therefore the ; first position offscreen will be -4 as it moves in steps of 4. ; R12 = UNKNOWN!! Presumed to be count of lines drawn so far. Affected code corrected.MOV R3,R3,LSL#1 ; width in pixels of sprite (R3 originally contains width in words) RSB R7,R7,#0 ; MOV R7,R7,LSR#1 ; convert clipped bytes to pixels SUB R8,R3,R7 ; calculate width in pixels by taking off clipped pixel no. MOV R7,R7,LSL#1 ; bytes to be clipped MOV R6,R7 MOV R11,#1280 MUL R11,R4,R11 ; R4 contains y-pos (intially 0) ADD R1,R1,R11 ; starting position address of sprite (R1 screenbase) MOV R10,R1 ; put copy in R10 .collob_plotlooplc MOV R3,R8 ; place copy of width in pixels into R3 ADD R5,R5,R6 ; offset sprite data pointer (R6 contains bytes) .bytelooplc LDR R4,[R5],#4 ; MOV R7,#255 ; ORR R7,R7,#65280 ;R7=&FFFF ; AND R9,R4,R7 ; get lower two bytes of word ; CMP R9,#0 MOV R9,R4,LSL #16 ; Clear top bits MOVS R9,R9,LSR #16 ; Shift back to bottom bits, compare with 0 ADDEQ R1,R1,#2 STRNEB R9,[R1],#1 MOVNE R9,R9,LSR#8 STRNEB R9,[R1],#1 ; MOV R7,#255 ; ORR R7,R7,#65280 ;R7=&FFFF ; MOV R4,R4,LSR#16 ; AND R9,R4,R7 ; get lower two bytes of word MOV R9,R4,LSR #16 ; Clear bottom bits (And shift top bits to bottom) CMP R9,#0 ADDEQ R1,R1,#2 STRNEB R9,[R1],#1 MOVNE R9,R9,LSR#8 STRNEB R9,[R1],#1 SUBS R3,R3,#2 BNE bytelooplc ; ADD R12,R12,#1 ; MOV R11,#1280 ; MUL R11,R12,R11 ; ADD R1,R10,R11 ADD R1,R10,#1280 ; Move on to next line SUBS R2,R2,#1 BNE collob_plotlooplc
Right... there appear to be a couple of problems... 1) R5 (Sprite pointer) is not updated for skipping the clipped areas 2) Without testing the code myself, I'm not quite sure how it will handle clipping to the right edge of the screen Hope that helps |
|
[ Log in to reply ] |
|
Andrew |
Message #86226, posted by andreww at 19:37, 7/3/2002, in reply to message #86225 |
AA refugee
Posts: 555
|
Thanks Jeffrey. However, I am updating the sprite pointer with: ADD R5,R5,R6 ; R6 bytes to be clippedI didn't included the right-hand clipping routine. regards Andrew |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #86227, posted by Phlamethrower at 19:39, 7/3/2002, in reply to message #86226 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
However, I am updating the sprite pointer with: ADD R5,R5,R6 ; R6 bytes to be clipped
Ah, must have missed that bit. |
|
[ Log in to reply ] |
|
Andrew |
Message #86228, posted by andreww at 21:52, 7/3/2002, in reply to message #86227 |
AA refugee
Posts: 555
|
Hi again, The problem has been solved. The code was okay mostly but I was entering the clip calculation routine separately from the clipped plotting routine and expecting the x-pos register to stay the same as it was used as a test (if negative then enter 1st routine then clipped plotter as well). Of course the register was made positive to add to the sprite data pointer. Jeffrey - you've shown me a faster way of doing the calculations and I expect this will be much appreciated when it's used in the final program. You corrected my scan line counter at the end; however this is necessary as I couldn't get it to work the way you do it as this is how I think I tried initially. I don't know why. regards Andrew |
|
[ Log in to reply ] |
|
|
Acorn Arcade forums: Programming: Sprite clipping |