Advertisement

clipping compressed sprites

Started by February 08, 2001 09:52 PM
2 comments, last by Matthew02 24 years ago
I'm using compressed 16-bit sprites in my game and I am wanting some opinions on the best way to store/display/clip them. I have two types of compressed items. 1)44x44 tiles rotated 45°  &nbspstored linearly as 2048 bytes (1024 pixels)  &nbspthe first three runs of pixels are stored like this...    _ _ _ _ _ _ _ _ _ _ _ _  |1|1|2|2|2|2|3|3|3|3|3|3| &nbspand displayed like this...        _ _     _|1|1|_  _|2|2|2|2|_ |3|3|3|3|3|3| 2)textured quads and sprites  &nbspstored linearly like so...  &nbspbyte -> offset  &nbspbyte -> runlength  &nbspshort[runlength] -> pixels  &nbspbyte -> offset  &nbspbyte -> runlength  &nbspshort[runlength] -> pixels  &nbspetc...  &nbspsomething stored like this...  &nbsp2&nbsp5&nbspa&nbspa&nbspa&nbspa&nbspa&nbsp1&nbsp5&nbspb&nbspb&nbspb&nbspb&nbspb&nbsp0&nbsp6&nbspc&nbspc&nbspc&nbspc&nbspc&nbspc  &nbspwould be displayed like this         _ _ _ _ _       |a|a|a|a|a|    |b|b|b|b|b| |c|c|c|c|c|c| I am currently storing them in their compressed form. It takes less memory because all of the transparent pixels are not stored. Also, it's easier to display them because I can just use an optimized memcpy to copy complete runs of pixels. The only problem is that clipping them this way is a pain and I'm not sure it's fast enough. I thought about storing them decompressed using one value to represent all transparent pixels and then masking them out when drawing the item. This way the items would be stored in a two-dimensional array, so clipping them would be much easier. But drawing them seems like it would be substantially slower because each pixel would have to be masked out or drawn individually. Also, much more memory would be required to store them. If anyone has any opinions on which method would be better, or if anyone has any other methods (excluding using blt and bltfast), please let me know. If this post seems too obscure, tell me what part and I'll try to explain it better. Thanks. well... I can't quite get those diagrams to look right, but I think they convey the basic idea Edited by - Matthew02 on February 8, 2001 11:25:16 PM
(Note that I use the term "blitter object" (or BOB) rather than "sprite" as sprites don't technically exist on the PC. I'll use that term when I talk Nintendo and C64s.)

I use a custom made (8bpp)RLE BOB blitter like yours... My are store very similar like so:

DWORD offset
DWORD run_length
BYTE data[run_length] (+ dword padding)

I have 9 different blit functions for the various clipping cases. These are: None, clip left;right;up;down, and those in the 4 corners. I separated the functions into ones that only performed the clipping that was required; obviously a performance issue. I didn't write clipping function for objects that need clipped on left and right, and top and bottom, because I have never (nor will) use a BOB that is larger than the viewport. So, this limits my sprites to the dimensions of the screen. No big fuss.

I think the main difference in our data definitions is that you allow one run per line, and then jump down a line; while my offset specifies the jump in memory to the next run. I used this method to allow sprites to have transparent pixels in between runs that exist on the same vertical line. Without it, BOBs would be severely limited... Mario couldn't punch blocks because of the space between his head an arm. He would have to keep his limbs bound to his torso, and hop along.

On to clipping...

I use a pointer that points to the destination in buffer to copy the run.

Horizontal clipping (along the top and bottom) is a breeze. In the case of clipping by top, perform a loop that checks the pointer if it is past the beginning of the buffer you are blitting to. If not, skip the run of pixels and check the next. Once (if) found, you can copy the rest of the runs without checking. Clipping by the bottom is just about the opposite... Draw each run, and check if pointer if off of buffer (beginning of buffer + buffer length).

Vertical clipping is a little tougher. The problem stems from not knowing where the pointer is in the buffer in a 2d (x,y)sense without calculating each time. For clipping on the left side I have been performing [pointer (- buffer pointer) mod screen width] to get the X position of the run. I then used this to determine if the run was on the right side of the screen (due to linear buffer) and thus needed to be clipped. (This limits the BOBs to having runs start within half a screen length.) The difference from the start to the right side of the screen equals how many pixels to skip in the run, if not skipping all pixel when skip > run length.

(I am (very lazily) looking for a better solution, as a modulus requires a div, and I don't like performing one each run.)

Hope this gives you a start.

.travois.

<br><br><br>Edited by - tv on February 9, 2001 5:16:35 PM
Advertisement
As a matter of fact, I use some sprites er... bobs defined similar to what you use. As you pointed out, having multiple runs and transparencies per line is quite important. I just didn''t mention them because I didn''t want to complicate the post.
I also have no bobs which are wider or taller than the viewing area, so that is no problem.

The method you use to clip the sprites seems great. How long have you been doing it this way? You have observed good performance with it, huh?

I would be interested in seeing the source that you mentioned. Perhaps you can e-mail it or ICQ it to me.

I have some other questions also. Would you mind if I sent you an e-mail or added you to my ICQ list? Thanks for your help.
Either way (or both) is fine... Maybe this will give me the motivation to button these functions up!

Down with BltFast! Down with bitmaps!

.travois.

This topic is closed to new replies.

Advertisement