Jump to content
karri

sp65 changed - a lot

Recommended Posts

I spent some time with @Songbird looking at sprites. It appears that a lot of games are actually using the starting quadrant for drawing sprites that use only two quadrants. So I added this feature to sp65 as a new keyword.

 

sp65 -r image.pcx -c lynx-sprite,quad=1 -w image.c,ident=image

 

This would produce a literal sprite starting the draw from the 2nd quadrant.

717902742_Screenshotfrom2020-02-1216-33-18.png.9652f476cb2c527c145cc0dd0563e452.png

 

Or the 3rd quadrant

1815607492_Screenshotfrom2020-02-1216-34-51.png.4e8f637f3bb8977f02817c17e817db1c.png

 

4th quadrant

70720325_Screenshotfrom2020-02-1216-36-08.png.d953dce2cebdd64850b808f4d4f9a17e.png

 

All these images would be correct if the startup quadrant in the sprite structure is correct. These distorted draw were just to show the effects of a mismatch between the sprite and the starting quadrant.

 

Other changes is a little more intelligence in packing the sprites. The sp65 will now analyse the next 32 pixels to find the most cost effective way to pack the next chunk (literal or packed).

 

Another neat trick found in a few games is to 1st fill the screen with a giant pixel. Then you draw the title image on top of the pixel, but only as long as the line has other colours than the background pixel. This feature is also in the sp65 with the keyword shaped and edge.

 

sp65 -r image.pcx -c lynx-sprite,mode=shaped,edge=5 -w image.c,ident=image

 

In this case the background pixel would use pen 5 and we draw a packed sprite only until the end of the line consists of pixels=5 only.

 

Other planned development is to support the new pcx format that seems to be the new standard in Gimp and other paint programs. This is still wop.

 

Edit: Now there is also support for 1-plane, 4-bit compressed pcx-images that Gimp 2.10 and other modern software produces.

 

Edit2: I just compared the size of this packet title sprite. The previous version used 320 bytes more than this new optimized version.

Share this post


Link to post
Share on other sites
1 hour ago, Igor said:

Nice changes Karri. Is this in your version of cc65 or the github version?

Just my version. The github version is no longer backwards compatible with my code.

 

I also thought of adding a keyword for forcing a certain bit depth. And including the palette.

 

The reason I do this is to make hacking old stuff easier.

Share this post


Link to post
Share on other sites

Ah right and yes very different versions, maybe you should think about renaming your's to kk65 😅

Share this post


Link to post
Share on other sites

I cannot hijack cc65. This is a frozen version as the compiler, assembler and linker is concerned. But sp65 is independent from cc65. I could easily update that one to the mainstream cc65.

 

Share this post


Link to post
Share on other sites
3 hours ago, karri said:

I cannot hijack cc65. This is a frozen version as the compiler, assembler and linker is concerned. But sp65 is independent from cc65. I could easily update that one to the mainstream cc65.

 

Just came over here to ask if this could be PR'ed to the mainstream cc65.  Would love to see these awesome changes make their way into the main cc65 repo.  Happy to do the work if it's helpful!  Thanks for all of your efforts, karri!

  • Like 1

Share this post


Link to post
Share on other sites

Sure! But I still want to add one more keyword "bits" that would force the system to use a certain depth for the sprites.

 

Exporting palettes is also something I need to implement.

Share this post


Link to post
Share on other sites

A small question to current/future sp65 users. Here I try to explain the different command line options and possible future new ones.

 

sp65

-r image.pcx = read in image

-r image.pcx --slice 8,16,14,7 = read in a smaller area of the image at x=8,y=16,w=14,h=7

 

-c lynx-sprite = convert the data to a sprite (default literal)
-c lynx-sprite,mode=packed,ax=3,ay=4   = convert the data to a sprite (packed) with anchor point at (3,4)

-c lynx-sprite,mode=shaped,egde=5      = convert the data to a sprite (packed) but stop data creation when you find the edge

-c lynx-sprite,quad=1   = convert the data to a sprite starting at quadrant 1

 

Here I now wonder of a new feature. Would it make sense to have a way to extract a smaller sprite directly from a big image

 

-c lynx-sprite,pen=06ab    = convert the data a 2-bit sprite and map colours [06ab] -> [0123]

 

You could also use real transparent colour in the source image 'X' so that you don't have to sacrifice one colour while you design the graphics. Unfortunately the transparency is converted to the last colour in the image when you save it. So "x" has to wait for some better input image format.

 

-c lynx-sprite,pen=x0    = convert the data to a 1-bit sprite and map colours [X0] -> [01]

 

If you want to force an image to be 16 colours just use pen=0123456789abcdef

 

Also a new keyword for extracting the palette.

 

-p pal.c,lynx-palette

 

And finally the name of the output file for the sprite

 

-w hobbes.c,ident=hobbes,bytesperline=8

-w hobbes,format=asm

-w hobbes.bin

 

The system will automatically detect the correct format (c, asm, bin)

 

Opinions?

 

Share this post


Link to post
Share on other sites

It makes perfect sense extracting a small sprite from a big image. Just think of a font.

sprpck does it.

  • Like 1

Share this post


Link to post
Share on other sites

Yeah I agree, being able to have a sprite sheet would be very handy (ehehe). But seriously, having a tonne of small images as is the case now adds difficulty to maintenance, so I would welcome this feature very much.

Share this post


Link to post
Share on other sites

I almost got most of the things to work now. The new palette file that can be generated looks like:

/*
 * This file was generated by sp65 2.13.9 from
 * bg2.pcx (160x102, 16 colors, indexed)
 */

#define palette_COLORS       16
const unsigned char palette[] = {
    0x02,0x06,0x05,0x06,0x05,0x06,0x06,0x06,
    0x09,0x09,0x09,0x09,0x0A,0x0C,0x0C,0x0D,
    0x22,0x25,0x88,0x66,0x58,0xC5,0x96,0xAD,
    0xC6,0x98,0xC9,0x9C,0xDD,0x9E,0xCF,0xDD,
};


 

So I decided to have it compatible with the TGI library. You can just give it as an parameter to the

 

tgi_setpalette(palette);

To generate this from an image I did:

 

sp65 -r bg2.pcx -p lynx-palette,bg2pal.c,format=c,ident=palette,bytesperline=8

 

I will still make the auto detection work for the palette outputs also. As you can see you can choose to just do the palette extraction from a file. Or do both the palette extraction and the sprite conversion at the same time.

 

If you choose asm as an output format you end up with  a ca65 syntax asm file.


 

;
; This file was generated by sp65 2.13.9 from
; bg2.pcx (160x102, 16 colors, indexed)
;

.proc   palette
        COLORS = 16
        .byte   $02,$06,$05,$06,$05,$06,$06,$06
        .byte   $09,$09,$09,$09,$0A,$0C,$0C,$0D
        .byte   $22,$25,$88,$66,$58,$C5,$96,$AD
        .byte   $C6,$98,$C9,$9C,$DD,$9E,$CF,$DD
.endproc

 

Share this post


Link to post
Share on other sites
29 minutes ago, karri said:

I almost got most of the things to work now. The new palette file that can be generated looks like:

/*
 * This file was generated by sp65 2.13.9 from
 * bg2.pcx (160x102, 16 colors, indexed)
 */

#define palette_COLORS       16
const unsigned char palette[] = {
    0x02,0x06,0x05,0x06,0x05,0x06,0x06,0x06,
    0x09,0x09,0x09,0x09,0x0A,0x0C,0x0C,0x0D,
    0x22,0x25,0x88,0x66,0x58,0xC5,0x96,0xAD,
    0xC6,0x98,0xC9,0x9C,0xDD,0x9E,0xCF,0xDD,
};

You should consider to remove the last comma (for aestic reasons).
 

 

Share this post


Link to post
Share on other sites

The comma comes from the generic output routine that also exports stuff for other platforms. As I am not quite sure about how it is being used there may be a need for it. The same comma problem pops up with sprites. Fortunately this is for C-outputs only. The "bin" and "asm" formats are ok.

Share this post


Link to post
Share on other sites

I just pushed sp65 to https://bitbucket.com/atarilynx/lynx

 

Feel free to try it out. The packing algorithm is now as good as it gets. The sprites should be some 10% or 20% smaller.

 

When time permits I try to make a tutorial.

 

PS. already spotted an error. For 4-bit newer pcx files creating sprites with odd widths will produce extra pixel at end of sprite.

 

PPS. I just compiled "On Duty" with the new version of sp65. The size of the lnx file shrunk by 4k. But more importedly every graphics got smaller by at least one or two bytes. All levels were no longer tight. I now have hundreds of empty bytes in RAM during runtime. This makes a huge difference for gaming experience.

Share this post


Link to post
Share on other sites

Hi Kari,

 

To confirm, the -ax, -ay options refer to the reference point in the sprite, termed in sp65 as anchor point? So HFLIP and VFLIP will flip at those coords?

 

Petr

Share this post


Link to post
Share on other sites
1 hour ago, PetrS said:

Hi Kari,

 

To confirm, the -ax, -ay options refer to the reference point in the sprite, termed in sp65 as anchor point? So HFLIP and VFLIP will flip at those coords?

 

Petr

Correct!

Share this post


Link to post
Share on other sites
7 hours ago, karri said:

Correct!

Nice! One variation I'd like to see of the ax, ay option is to allow percentages as opposed to pixels. Something like -px50 which would automatically center the anchor point.

 

I'm finding that you need to figure out the dimensions of the source image (say via imagemagick) before being able to use ax,ay effectively or a lookup table.

 

Looking at the code, this looks like a relatively easy addition by supporting the new arguments and adding them to sp65/lynxsprite.c GenLynxSprite ().

 

What is the process for extending sp65 and getting those changes officially approved?

 

 

Share this post


Link to post
Share on other sites
5 minutes ago, PetrS said:

I'm finding that you need to figure out the dimensions of the source image (say via imagemagick) before being able to use ax,ay effectively or a lookup table.

 

You should know the dimension of your sprites anyway, shouldn't you?

Share this post


Link to post
Share on other sites

You can easily just add verbosity to print stuff. Like:

 

[email protected]:~/findaway/intro$ sp65 --verbose -r bg.pcx
File name:       bg.pcx
PCX Version:     3.0
Image type:      color
Compression:     RLE
Structure:       1 planes of 8 bits
Bounding box:    [0/0 - 159/101]
Resolution:      300/300 DPI
Screen size:     0/0
Bytes per plane: 160


 

Or ask for the palette dump:

 

[email protected]:~/findaway/intro$ sp65 -r bg.pcx --dump-palette
Entry     R      G      B      A     Combined
----------------------------------------------
   0     46     46     39      0    #00272E2E
   1     90    102     38      0    #0026665A
   2    134     85    138      0    #008A5586
   3    143     90     91      0    #005B5A8F
   4    101    102    100      0    #00646665
   5     83    101    202      0    #00CA6553
   6    101    101    150      0    #00966565
   7    212    111    160      0    #00A06FD4
   8     99    154    203      0    #00CB9A63
   9    142    154    152      0    #00989A8E
  10    150    154    207      0    #00CF9A96
  11    204    153    152      0    #009899CC
  12    213    160    210      0    #00D2A0D5
  13    228    203    149      0    #0095CBE4
  14    255    203    202      0    #00CACBFF
  15    215    217    213      0    #00D5D9D7

 

The procedure to get your changes accepted is a bit different.

 

I make everyone who wants to contribute admin for this repository. Then it is up to them to decide how to contribute.

 

Getting any of your ideas accepted in the main cc65 may be (im)possible. Depends on if you think the same way as the official maintainer or not. It has been ages since I tried to introduce new things to the main cc65.

Share this post


Link to post
Share on other sites

Actually, I don't know the sizes of the images, and they might change. I can definitely hack it in the makefile, but a cleaner solution within sp65 seems nicer.

 

I'm writing a generic interactive animation system for the Lynx, and flipping the image around the center of images is used quite frequently.

 

Maybe the question I should be asking is:

 

Can you set the anchor/reference point of a sprite in code?

Share this post


Link to post
Share on other sites
4 minutes ago, PetrS said:

Actually, I don't know the sizes of the images, and they might change. I can definitely hack it in the makefile, but a cleaner solution within sp65 seems nicer.

 

I'm writing a generic interactive animation system for the Lynx, and flipping the image around the center of images is used quite frequently.

 

Maybe the question I should be asking is:

 

Can you set the anchor/reference point of a sprite in code?

1) Depending on the size of the sprite, it might look ugly if your "center" is one pixel out of the middle due to rounding errors.

Means you need some hand-tuning.

2) No, the "action" point is defined the way the quadrants are encoded. Once done, it is fixed.

 

Share this post


Link to post
Share on other sites

It could be possible to use some names for ax and ay like

 

ax=left,ay=top

 

ax could be [ number, left, mid, right ]
ay could be [ number, top, mid, bottom ]

 

Would this be ok?

 

The value "mid" is (width / 2)  or (height / 2)

No fractions.

 

Edit:

Actually the choices should be:

 

ax = 0
ax = mid
ax = max

 

ay = 0

ay = mid

ay = max

 

 

Share this post


Link to post
Share on other sites
43 minutes ago, karri said:

ax = 0
ax = mid
ax = max

 

ay = 0

ay = mid

ay = max

 

 

That sounds great!

Share this post


Link to post
Share on other sites

I just pushed the new version.

 

The ay=mid, ax=max options are now available.

 

There is also a new option "pen" available.

 

The idea is that you can have a single graphics image that could be 4 bit deep (for 16 colours). When you slice and area you can map the colours into a 2-bit sprite by defining the option

 

-c lynx-sprite,pen=089a

 

This would greate the new sprite as a 4-colour sprite and map the colours as the "pen" says. The effect is the same in your code later. If you draw your 4-colour sprite with the penpal = {0x08, 0x9a} you will get the correct colours on screen.

 

The "pen" can also be to enforce a certaing depth for the sprite.

 

So if you have a 2-colour bitmap, but you want a 16-colour sprite.

 

-c lynx-sprite,pen=0123456789abcdef

 

This would save the sprite as a 4-bit sprite despite that the original bitmap is something else.

Share this post


Link to post
Share on other sites

sprpck has the -c option to compress the color table, which I found also helpful.

So if the part of your sprite (or portion of a bigger one) uses only 8 color it will use only 3 bit.

Not sure if that's what you mean with the pen option.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...