I think I got a better idea, that optimises the usage of all 4 unused bits (counting the priority bit as unused).
I forgot the idea to predict the attribute byte, as it would be very easy to screw up and end in an infinite loop.
Just remember, as I said in my 1st post :
- Attribute byte is always present
- X, Y and tile # bytes are either predicted from the previous sprite, or present
- Prediction data for sprite N+1 is stored in the data of sprite N
- The first sprite is never compressed (always 4 bytes)
Code: Select all
yyyyyyyy --- Sprite Y coordinate (if required)
vhtyxxpp --- Attribute byte (always)
||||||++---- Sprite Colour
||||++------ X position of next sprite (00 : required, 01 : X pos of this sprite + 8,
|||| 10 : X pos of the fist sprite, 11 : Escape code for last sprite)
|||+-------- Y position of next sprite (0 : required, 1 : Y pos of this sprite + 8)
||+--------- Tile number of next sprite (0: required, 1 : Tile number of this sprite + 1)
|+---------- Horizontal flipping
+----------- Vertical flipping
tttttttt --- Tile number (if required)
xxxxxxxx --- Sprite X coordinate (if required)
The enthropy of the 4 unused bits are not fully used, as 4 of the 16 possible shemes have the same effect (finishing the meta sprite), but there is still 12 predictions available.
As opposed to my first idea for the codec, it makes it possible for tiles which are gird aligned in a direction but not the other to be still compressed efficiently. Those are pretty common, every time an enemy has a tail I use this, so the tail is in the middle of the sprite but still takes only 1 tile of width/height, so I move it 4 pixels apart the "gird".
Again, this is fully compatible with uncompressed sprites, except that you have to OR the attributes of the last sprite with $0c for it to work.
I also should point out that EORing palette bits wouldn't work so well if you use more than one palette in the same metasprite... for example, say that an enemy is green and wears a white shirt, so it uses different palettes for the green and white parts. If you want to recolor that enemy so that it's blue but still wears a white shirt, that wouldn't work, since the palette of the shirt would be changed as well. One solution would be to use OR or AND instead of XOR, so that you can use palette 0 (%00) or 3 (%11) for the one you don't want to change. That would require more careful planning of the palettes.
Mmh, you got a point !
The problem with the AND/OR approach is that it's then impossible to access all 4 palettes by the means of palette swapping unless you use palette 3/0 (respectively). However it will fix the problem you issused, which is a good thing.
Flipping is not as trivial since you also need to modify the coordinates of the sprites. It's a good starting point for that goal, though.
Yes, usually you also need to negate (XOR with $ff) the X coordinate.
You could also do that vertically, but unless you have a level like Gravity Man's, I doubt it will be very useful.