News:

The Forum Rules and Guidelines
Our forum has Rules and Guidelines. Please, be kind and read them ;).

Support 24-bit / 32-bit Colour Depth

Started by THLeaderH, July 07, 2026, 09:42:57 AM

Previous topic - Next topic

0 Members and 6 Guests are viewing this topic.

THLeaderH

Hello,

I would like to raise a proposal regarding Simutrans' internal colour depth and the image format used in pak files.

Currently, Simutrans renders graphics in a 16-bit RGB565 colour space. However, in the Japanese Simutrans community, there has been increasing demand for higher-quality graphical expression. In response to this, Simutrans OTRP, a Japanese fork of Simutrans, is planning to support 24-bit colour depth, or 32-bit colour depth for images with an alpha channel.

With the current 16-bit colour representation, colour degradation caused by colour reduction is especially noticeable for images that contain alpha channel information. This has become a practical issue for creators who want to use more detailed or higher-quality images.

To support higher colour depth, the image format inside pak files would also need to be changed. In OTRP, we have a policy of avoiding differences between Standard and OTRP in the add-on format as much as possible. The reason is that if "OTRP-only add-ons" become common, add-ons created by the community may no longer be usable by Standard players, which could divide the community.

For this reason, I would like to propose that Simutrans Standard also consider supporting 24-bit colour depth.

One possible approach would be to increase the version of the `obj_image` node in pak files from the current version 3 to version 4. In version 4, image data could be stored using 24-bit colour depth, or 32-bit colour depth when an alpha channel is present.

Even if Standard does not support actual 24-bit rendering for the time being, another possible approach would be for Standard to support loading 24-bit or 32-bit image data from pak files, while still converting it to the existing 16-bit RGB565 colour space for rendering. This would at least allow the same pak files and add-ons to be used in both Standard and OTRP, while leaving the rendering implementation in Standard unchanged or mostly unchanged.

On the OTRP side, we have already started working on 24-bit colour depth support. We are currently implementing it for the Windows GDI and SDL2 backends. Based on the work so far, it seems that this feature can be implemented with a reasonable amount of code changes.

If Simutrans Standard is also interested in supporting 24-bit colour depth, or at least supporting the loading of higher-colour-depth image data, we would be willing to contribute our work upstream.

Thank you for joining the discussion.

makie

That would be nice; I would very much welcome that.

prissi

#2
Simutrans 124.5 introduced a flexible render backend, so it can change the depth during execution even ... The only routines inside the program that had not been outsourced and need to change are the blending of ground tiles which for now assume 16 bit images. Everything else is hidden by the external layer. Also, this was made in preparation for a Hardware OpenGL renderer, which becomes more urgent with twice the data to process at each frame.

This render change went with a consistent renaming of nearly all graphical functions which means, however, that the changes will need to be ported manually (unless OPTR applies the flexible render approach too). SO I guess the low hanging fruit is first to support loading of similar images for both. (This will, of course, slow down the loading of larger sizes again dramatically ...)

One important question is of how to handle player colours. In OpenTTD, player colours use another 8 bit mask inside the sprite for recolouring. That would require a different approach for makeobj dat files syntax.

Then the question of how to encode this in the pak files. One option could be, that version 4 has alpha channel and version 5 has player colors as 8 bit information, with bits 0.127 for player color 1 blending and 128...255 for player color2 blending.

The changes to GDI and SDL are very small compared to the changes of the graphic routines. Rendering at higher depth will be mostly affecting high zoom levels.

EDIT: I looked at the OTPR source code but I saw no 32 bit code yet. Where should I fook for? Otherwise, maybe I should do the next release first before starting something as big as this.

THLeaderH

I agree that we should start from supporting loading the same format images.

For the player colors and other special colors, I am thinking of reusing the existing pre-defined colors. These special colors are encoded as it is drawn in the source png file. The descriptor reader can convert the pre-defined special colors to the internal expression.

However, we may add some more special colors for 24/32bit images. With the current special color table, the primary player color can be expressed only in 8 levels, but this may be increased. We may add other lighting colors as well.

makie

Quote from: THLeaderH on July 08, 2026, 03:17:07 PMHowever, we may add some more special colors for 24/32bit images. With the current special color table, the primary player color can be expressed only in 8 levels, but this may be increased. We may add other lighting colors as well.
No, that lead to many lighting pixel in old graphics.
All the old PNG files would then have to be reworked.
The glowing pixels are a real nuisance.

Just leave it as it is.

---
Or split it into two files. One for the graphics an the other for the mask.
All other tricks makes it incompatible with normal graphics programs like gimp.

prissi

I think a mask file with different colors could do the trick even better. Like Blue for player color 1, Red for player color 2 and several greens for special colors. (And then black for transparent mask ... )

Then, if makeobj finds extra text after the image definition, if will assume that is the mask to that image and encode the mask accordingly.

THLeaderH

Mask file sounds good for ensuring the backward compatibility. However, it adds one extra single image to each image, which increases the pak file size almost twice. Is it acceptable?

makie

One of the biggest paks is pak128.german and this one has no player colors.
If pak64 doubles its size it doesn't matter.

Buildings, factories and trees has no player colors. This are the biggest images. 

THLeaderH

@prissi

QuoteI looked at the OTPR source code but I saw no 32 bit code yet. Where should I fook for? Otherwise, maybe I should do the next release first before starting something as big as this.

I have just pushed my working branch at https://github.com/teamhimeh/simutrans/commits/24-bit-color/ . But this implementation assumes that the special colors (light colors, player colors) are written directly to the same source png image as the original.

Converting the internal pixel value type to 32bit integer was implemented with a reasonable implementation amount. However, it increased the memory consumption to twice for holding the loaded addon images even though all the loaded images are 16bit color depth. Keeping the 16bit color images in 16bit color pixel value made the implementation quite complicated...

prissi

We could use a simgraph32.cc for the main branch that is switched on load time.

And for images that do not specify a mask, the old plazer colors and special colours would be converted to new colours.
And the overlay images needed for 32 bit with the special and player colors are usually quite empty, so it would not add much extra memory.