Page 1 of 4

PNGCodec

Posted: 22 Jun 2007 12:20
by TrueBrain
What is PNGCodec?

PNGCodec is a small application to add meta-data to PNG files. This is needed for 32bpp, as each image needs a x_offs and y_offs. With this program, you can add that very simple.

WARNING: editing your png in any editing program mostly results in the loss of this meta-data. This is not something we can help, those editing programs are just a bit stupid.

Where can I get it?

http://www.openttd.org/download-pngcodec

Usage?

Run 'pngcodec' and you get a help list. For correct workings of 32bpp in OpenTTD you need to set x_offs and y_offs. All other tags are ignored.

What is this x_offs and y_offs?

When OpenTTD draws a sprite, it does this at the top-center of the tile. Most images do not want to have their top-left corner (0,0) there. So you need to indicate the offset from the top-center of the tile to your top-left corner. For instance, a normal flat landscape tile has a x_offs of -31, indicating that the tile should be drawn 31 pixels more to the left then the top-center of the tile.

Posted: 22 Jun 2007 15:20
by Jupix
I took the liberty of copying this post over to the wiki.

Posted: 26 Jun 2007 17:00
by GeekToo
An x-offset of -31 does work correctly, but I was just wondering, why shouldn't it be -32, as would make sense for the center of a 64 px tile?
In other words, is it (width x)/2 - 1 or floor((width x -1)/2)

Posted: 26 Jun 2007 17:22
by Rubidium
Tiles are 63x31

Posted: 26 Jun 2007 18:50
by GeekToo
Hmm, got it from:
http://blog.openttd.org/?p=15
The 32bpp graphics have to be in the same dimension as the grf graphics. The blitter does no scaling, and it doesn’t know how to handle zoom-in 2x rescaling or anything. So the dimensions for a plain tile has to be 64×31.

Posted: 26 Jun 2007 19:01
by Rubidium
At least it has to do with the fact that the sprites aren't 64x32; don't know exactly and I'm not in the mood to go funting for it. However, I guess the dark edges have to do something with it.

Posted: 26 Jun 2007 20:04
by XeryusTC
My best guess would be that it is for the same reason as why 2 octaves have 15 notes and not 16, you already counted 1 note (or one pixel row in this case). If you take the height of a tile you need 16 rows of pixels for the upper half but the bottom half only needs 15 rows because you already have the "middle" and the widest part of the tile (sprite wise).

Posted: 26 Jun 2007 20:05
by GeekToo
Rubidium wrote:At least it has to do with the fact that the sprites aren't 64x32;
I didn't say that, the 32 was referring to the x-offset
Rubidium wrote: don't know exactly and I'm not in the mood to go funting for it.
I was, and did some more searching:
from the original trg1r nfo:

3981 sprites/trg1r.pcx 162 12968 09 31 64 -31 0

So I suppose the official size is 64 x 31 with an x offset of -31.

This implies my question stays: does anybody know how to calculate the 'correct' offset?

edit: sorry XeryusTC: crossposting.
Does this mean that the tiles overlap?

Posted: 26 Jun 2007 20:30
by zombie
Hi.

If you have plain tiles only (PNGs dimensions of exactly 64x31) the offset is always -31/0. If you have a tile with a building or something else (dimension of 64 by 31+x) the offset should be roughly -31/-x. In this case the tile for the sprites has to be at the bottom of the PNG without any frames or empty lines. This "formula" is quite accurate by only +/-1 pixel of deviation for the PNGs I got from Sergej's page.

I guess you always have to try and finetune the offset values.

EDIT: I guess I know why the x_offs is -31. If each sprite is 64 pixel wide the center of the image is between two pixels. Therefore the developers had to choose which pixel to use as a reference and they just chose the left one. If the sprites were 63 pixels wide it would still be -31.

Kind regards

Zombie

Posted: 26 Jun 2007 21:13
by GeekToo
Hi Zombie,
Thanks for the input and the formulas. I'll start experimenting with it.
I guess I know why the x_offs is -31. If each sprite is 64 pixel wide the center of the image is between two pixels.
Correct, but the centre is between pixel 32 and 33. That why I found this kind of odd that the offset is -31.
Sure you can get it right with trial and error, but that takes time, so I was looking for a way to do it 'the first time right'
[/quote]

Posted: 26 Jun 2007 21:19
by zombie
Hi.

You are right, the center is between pixels 32 and 33. If x_offs is set to -31 and pixel 32 is the defined center of the sprite you get pixel 1 (center pixel + x_offs). The graphic engine starts painting the sprite at pixel 1 and that's perfect.

EDIT: I just rechecked the PNGs from Sergej I included in OpenTTD and found out that the deviation of +/- 1 pixel is necessary if the sprites use anti aliasing. In this case the ground tiles are a bit higher or lower and I had to fine tune the offset values. If the ground tiles have clear borders according to the original sprites the formula should always work.

Kind regards

Zombie

Posted: 26 Jun 2007 21:20
by peter1138
Incorrect. The centre is between 31 and 32. That leaves 32 pixels between 0 and 31, and 32 pixels between 32 and 63 (all inclusive).

Posted: 26 Jun 2007 21:21
by Rubidium
GeekToo wrote:Correct, but the centre is between pixel 32 and 33.
Pixels have 0 as base, i.e. the x pixels are numbered 0..63 when it is 64 pixels wide, so -31 puts pixel 31 in the "center", which would be the 32nd pixel.

Posted: 26 Jun 2007 21:41
by zombie
Hi.

I just made a zoomed screenshot of the base landscape tile from the temperate set. The image shows the tile with the grid from MS paint and I added some numbers to make things a bit easier to explain.

When OpenTTD draws the map the engine recognizes pixel 31/0 as the origin of a tile. If you don't provide any offsets the OpenTTD engine paints the sprites starting at this coordinate. This way the sprite does not align to the grid of the map array. The map is not properly rendered.

If you provide proper offsets of -31/0 the engine starts painting the sprite at coordinate 0/0. The sprite is alligned to the grid.

Kind regards

Zombie

Posted: 26 Jun 2007 21:51
by zombie
Hi again ;)

I just verified the formula against some original sprites from trg1r.grf and the formula is correct for PNGs with a width of 64 pixels:

x_offs = -31
y_offs = png.height - 31

Kind regards

Zombie

Posted: 26 Jun 2007 21:52
by GeekToo
Ok zombie and rubidium. Though this makes sense for a pixel index and not for an offset, it is implemented the way it is, and the formula for calculating the x-offset is probably:

-floor((width x -1)/2)
(for non-C programmers: floor (31.5) would result in 31)

Posted: 27 Jun 2007 01:33
by athanasios
Why couldn't we have a nice GUI program to do these calculations by just placing the sprite on a base tile and help many artists use their time in a more productive way?

Posted: 27 Jun 2007 01:59
by DaleStan
Because you haven't written it yet, of course.

Posted: 30 Jun 2007 13:38
by PouncingAnt
You say png Codec is a program? I just downloaded the version for win32, and my system is pretty sure its a "file" :roll:
is this my laptop, windowsXP, or something wrong with the compile? (of course I couldn't possibly be at fault? :twisted: )

Posted: 30 Jun 2007 22:55
by athanasios
This shows how correct I was for my previous post. Finally someone got into the trouble to run that program and what a pity: it is broken. :roll: