News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Compressed sprites

Started by ssr86, 21:37, 26 August 13

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ssr86

Could someone give me an example (with source code) compressed sprites?

When is this type of sprites best to use (and for what)?


Edit: Changed topic's title and corrected a word

fano

#1
That changes all  :laugh:


There are a lot of method to compress a sprite, i have sadly no source code as CPC is not fast enough on my point to use on the fly compressed sprites.After , that depends , what would you do with compressed sprites ? for what type of project ? can you accept some reduction in colors for example ?
"NOP" is the perfect program : short , fast and (known) bug free

Follow Easter Egg products on Facebook !

ssr86

#2
For now I'm asking just out of curiosity.
I would like to know when they would be the most useful and with what restrictions.
So reduction of colours is acceptable.

About this type of sprites I know only what I've read in Unofficial Amstrad WWW Resource but I've never seen a complete code example (with a drawing routine)...

andycadley

Well there isn't really that much of a difference between a "compressed" sprite routine and an ordinary one. Ultimately any sprite routine is about taking data from one place, possibly manipulating it slightly, then writing it somewhere else. The only real difference in one using compressed data is they'll do slightly more manipulation work to get the data into the form they want to write to the display. That said, it's not all that common to do really, unless memory is extremely tight. It's often better to do the decompression on any sprites you're going to be using just once into a temporary buffer, then use that for every draw you do.

Even when memory is really tight, you'll normally only use the most simplistic form of RLE that you can, because you don't really want to be doing too much work when drawing to the display (it's probably going to be quite a "hot" part of your game code).

The following example, plucked straight out of the JSW+ source code, for example, unpacks a single colour 4*8 bitmap (representing an "item") and turns it into a "screen" compatible tile in a single ink colour. This decompressed image is then used when actually drawing stuff. Called with HL pointing at the compressed data and DE pointing to a temporary buffer location.


GetItemImage ;    Items are stored as a packed bitmap
  ;    and then expanded as necessary
  LD B,4;   Each image is four bytes
_Loop  LD C,(HL);   C = byte to decompress
  XOR A
  RLC C
  JR NC,_Skip1;  Zero bits are ignored
  OR 10000000b;  Set left pixel
_Skip1  RLC C
  JR NC,_Skip2
  OR 01000000b;  Set right pixel
_Skip2  LD (DE),A
  XOR A
  INC DE
  RLC C
  JR NC,_Skip3;  Zero bits are ignored
  OR 10000000b;  Set left pixel
_Skip3  RLC C
  JR NC,_Skip4
  OR 01000000b;  Set right pixel
_Skip4  LD (DE),A
  XOR A
  INC DE
  RLC C
  JR NC,_Skip5;  Zero bits are ignored
  OR 10000000b;  Set left pixel
_Skip5  RLC C
  JR NC,_Skip6
  OR 01000000b;  Set right pixel
_Skip6  LD (DE),A
  XOR A
  INC DE
  RLC C
  JR NC,_Skip7;  Zero bits are ignored
  OR 10000000b;  Set left pixel
_Skip7  RLC C
  JR NC,_Skip8
  OR 01000000b;  Set right pixel
_Skip8  LD (DE),A
  XOR A
  INC DE
  INC HL
  DJNZ _Loop
  RET

arnoldemu

Quote from: ssr86 on 22:28, 26 August 13
For now I'm asking just from curiosity.
I would like to know when they would be the most useful and with what restrictions.
So reduction of colours is acceptable.

About this type of sprites I know only what I've read in Unofficial Amstrad WWW Resource but I've never seen a complete code example (with a drawing routine)...
I will write an example at the end of this week when I have some time :)
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ssr86

Thank you very much arnoldemu for the new examples on sprites :) . [I haven't noticed them before:)].

So the compressed type is best for big sprites when no clipping to be done?

I'm trying to write something in 160x128 16 color software mode (160x256 with double height pixels).
My main sprite is about 32x40 pixels (so really 32x80 but I'm doubling the lines so it's a bit faster to draw the odd lines than normally).
Compiled sprites are the fastest but take much memory and I don't think I will have that much...
Compressed type seems to be a compromise between speed and memory (is it?).

On average (for a big sprite) - how much faster/slower are the 3 types (normal, compressed and compiled) when comparing them (I am aware that it's hard to say but maybe someone has some experience in using all the types)?




arnoldemu

Andy shows another form of the compressed sprite. This one works by putting the data into less ram at the expense of more cpu time for uncompressing.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ssr86

Has someone got a simple crossdev converter for compressed sprites that he could share with source code (java, c/c++) for modifcations?


ssr86

It took a year of my life (and needs much more) but I've written my own... It's still buggy as even seen in the attached example (although there was no such problem with my test sprite...)....
I promised to myself that I will release what I'll have accomplished untill end of october so... here it is...

CPCEPsprites RELEASE 0.0

MacDeath

#9
Many games use graphics in lower bit per pixels than actual video mode displayed.

yeah =  speccy port... but also games like Barbarian or some C64 inspired games.
DJ Puffs volcanic eruption as well... mode1 graphics for sprites.

This may not be proper compression, but is a way to store stuff with less RAM/Datas anyway.
It then convert the graphics into proper mode but retains the lower number of colours from other modes.

Antiriad may use this method, heavy use of software colour swaps then and redundant Black, sprites are not really masked actually, they use whole octets/bytes level masks so you may have slight black lines around coloured parts, this enable to get masks using half space than pixel wise masks I guess.

Those games in Mode0 would use Mode1 sprites hence 3colours + transparency for sprites.
you can recognise them because you can see the sprites in Mode1 graphics with "find graphics" functions from emulators, or see that the palette is often divided into 4x 4 palettes with black+3 other colours (most of time).


Those in Mode1 (often speccy ports) would use Mode2 sprites hence 1 colour + transparency, or use 1bpp sprites + 1bpp mask hence 2 colours + transparency.

Otherwise those "lovely" speccy's 2 colour backgrounds can be also used (but you were asking about sprites only I guess)


As I told, not sure if this can be considered compression in the proper or traditional computer's way, but it is de facto compression in result.


QuoteI'm trying to write something in 160x128 16 color software mode (160x256 with double height pixels).
My main sprite is about 32x40 pixels (so really 32x80 but I'm doubling the lines so it's a bit faster to draw the odd lines than normally).
Compiled sprites are the fastest but take much memory and I don't think I will have that much...
Compressed type seems to be a compromise between speed and memory (is it?).
I was thinking often about this sort of thing.

Talked a bit about it with Overflow recently, but he was a bit sceptical.
Cool way to have large suface in mode0 with graphics weighting half, as you get magnified pixels.

not sure if best way is to copy each lines into the RAM used as VRAM, or to trick on CRTC when it reads scanline so it would read each scanlines twice, this would perhaps need massive amount of interruptions.
In each case, CPU would be used so need to check what is best/fastest way.

There is also another method : the double layer or dual playfield.
it was quite often used actually.
Ghost and Goblins or ghouls and ghosts and many others ... mission genocide.
this mode0 "software mode" enable a background of 4 colours and a foreground (sprites) or 3 colours + transparency.
Yeah only 7 colours on screen.
But it can be fast and smooth and graphics would then weight half Memory.


simpler thing : code for 128K machines at least. :laugh:
Or get an X-MEM with those lovely extra 512K. ;D


Jokes appart :
May depend on many other aspects of the game/engine itself.
Does it have to scroll ? Numerous sprites everywhere of simple 1vs1 thing ?

ssr86

#10
The "compressed sprites" (don't know if it's a proper name for them) are "compressed" in the sense that you store their type - transparent byte, masked byte or opaque. And so for transparent type you don't store pixel data, for masked you store mask and pixel byte and for opaque you store only the pixel byte. So you save memory if there's a lot of transparent pixels, and save time if there's a lot of opaque or transparent pixels, because you don;t mask theme like in a "standard sprite".

Quote
Those games in Mode0 would use Mode1 sprites hence 3colours + transparency for sprites.
you can recognise them because you can see the sprites in Mode1 graphics with "find graphics" functions from emulators, or see that the palette is often divided into 4x 4 palettes with black+3 other colours (most of time).
[...]
There is also another method : the double layer or dual playfield.
it was quite often used actually.
Ghost and Goblins or ghouls and ghosts and many others ... mission genocide.
this mode0 "software mode" enable a background of 4 colours and a foreground (sprites) or 3 colours + transparency.
Yeah only 7 colours on screen.
But it can be fast and smooth and graphics would then weight half Memory.

I implemented that as "dual playfield mode 0" (based on an article by arnoldemu) - don't really know how you all call it.
The graphics don't really weight half I think... But because of the way you can draw them - using "or" for drawing  and then an "and" for erasing, you don't need a to store the background so no need for a buffer for the it (oh, so you actually save half the memory for the sprite) and it's faster also because you don't have to mask every byte.

Quote
I'm trying to write something in 160x128 16 color software mode (160x256 with double height pixels).
My main sprite is about 32x40 pixels (so really 32x80 but I'm doubling the lines so it's a bit faster to draw the odd lines than normally).
Compiled sprites are the fastest but take much memory and I don't think I will have that much...
Compressed type seems to be a compromise between speed and memory (is it?).
I was thinking often about this sort of thing.

Talked a bit about it with Overflow recently, but he was a bit sceptical.
Cool way to have large suface in mode0 with graphics weighting half, as you get magnified pixels.

not sure if best way is to copy each lines into the RAM used as VRAM, or to trick on CRTC when it reads scanline so it would read each scanlines twice, this would perhaps need massive amount of interruptions.
In each case, CPU would be used so need to check what is best/fastest way.

Enterprise can do that easily - it can repeat lines of display how many times you want. So modes like 160x144x16 or 80x72x256 with square pixels are easily to implement and use. At the cost of some memory - you need to have a long Line Pointer Table for that, because every pixel line (if you want to have it repeated) has to have it's own modeline in the table (one modeline is 16bytes, so for 160x144 you need 144*16=2304 bytes + 80 bytes for the sync block). But think how much more memory and cputime you save! Oh, and you set your own pointer for every line. So you could make the screen memory layout so that, a simple inc vmem_pointer_hi or set /res 4,vmem_pointer_hi will take you to the next line or the second screen buffer. And you set the palette at every modeline, so you can use more colors on the screen. It's a great machine with a very flexible graphic chip. Shame it didn't make it commercially 30 years ago...

I implemented a "dual line mode" in my program. This is somewhat faster than just drawing one line two times. But is slow nonetheless. It draws pixels like this:

ld a,pixel_byte1
ld (vmem_pointer),a
set 3,vmem_pointer_hi
ld (vmem_pointer),a
inc vmem_pointer_lo
ld a,pixel_byte2
ld (vmem_pointer),a
res 3,vmem_pointer_hi
ld (vmem_pointer),a
inc vmem_pointer_lo
...
...

The only advantage (I think) is that you only have to load the pixel_byte, mask it once...

Powered by SMFPacks Menu Editor Mod