log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- Elsear brings super-fast Networking to Risc PC/A7000/A7000+ (News:)
- Latest hardware upgrade from RISCOSbits (News:)
- Announcing the TIB 2024 Advent Calendar (News:1)
- Code GCC produces that makes you cry #12684 (Prog:39)
- RISCOSbits releases a new laptop solution (News:)
- Rougol November 2024 meeting on monday (News:)
- Drag'n'Drop 14i1 edition reviewed (News:)
- WROCC November 2024 talk o...ay - Andrew Rawnsley (ROD) (News:2)
- October 2024 News Summary (News:3)
- RISC OS London Show Report 2024 (News:1)
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
 
View on Mastodon
@www.iconbar.com@rss-parrot.net
Site Search
 
Article archives
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
PhlamethrowerHot 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
madbanHa 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 wink 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 wink 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 wink 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
madbanHa 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 wink )

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
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
*pieces together code*

(Amendmended lines are marked with monkey's)


monkey ; Entry data:
monkey ; Screen (Presumably) 640x?, 16bpp
monkey ; R1 = screen base ptr
monkey ; R2 = sprite height
monkey ; R3 = sprite width in words
monkey ; R4 = sprite y pos
monkey ; R7 = position on the scanline in bytes, therefore the
monkey ; first position offscreen will be -4 as it moves in steps of 4.
monkey ; 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
monkey ; MOV R7,#255
monkey ; ORR R7,R7,#65280 ;R7=&FFFF
monkey ; AND R9,R4,R7 ; get lower two bytes of word
monkey ; CMP R9,#0
monkey MOV R9,R4,LSL #16 ; Clear top bits
monkey 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

monkey ; MOV R7,#255
monkey ; ORR R7,R7,#65280 ;R7=&FFFF
monkey ; MOV R4,R4,LSR#16
monkey ; AND R9,R4,R7 ; get lower two bytes of word
monkey 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

monkey ; ADD R12,R12,#1
monkey ; MOV R11,#1280
monkey ; MUL R11,R12,R11
monkey ; ADD R1,R10,R11
monkey 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 wink

  ^[ 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 clipped

I 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
PhlamethrowerHot 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