News:

SimuTranslator
Make Simutrans speak your language.

Colour tables

Started by Max-Max, July 12, 2013, 11:22:42 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Max-Max

As I understand there are two kind of colours, 8bit COLOR_VAL and 16bit PLAYER_COLOR_VAL.
Both of them are indexes into a colour table with predefined colours.

I don't find it very user friendly to select a colour by its index (in GUI and .tab file). I would like to be able to use an 24bit RGB (RGB888) value in the .tab file for various theme colours, such as text, backgrounds, highlight etc.

Example: text_colour = #AA12C3

This format is widely used in both web design and paint programs, I don't think it would be any problems for a PAK artist or user to figure out the colour.

I don't see any difference in performance to use a RGB colour from a table compared to an RGB value in a 32bit variable. I'm not suggesting to change the whole colour system, but theme colours maybe can have its own table with 32bit values, read from the PAK or .tab file. Since a 24bit RGB888 has to be stored in a 32bit variable anyway, we could prepare it for alpha as well; RGBA8888.

Or does this go deeper? Is the drawing routines not capable of handling RGB888?
- My code doesn't have bugs. It develops random features...

kierongreen

For now if you want to select a colour in such a way I suggest you load/input 24bit values then convert these to 16bit values to use internally in game. All drawing routines in simutrans are coded for 16bit only and it would be a huge change to move away from this (that's not to say never, but there are various implications and it's a step for another day).

Max-Max

I suspected that there was a good reason why we still used RGB555 :)

Okay, converting to RGB555 seems to be the best way. I found a type PIXVAL (RGB1555), I guess that would be the preferred type to use.
- My code doesn't have bugs. It develops random features...

kierongreen

Yes that sounds right.

Max-Max

#4
Hmm, I found that PIXVAL is defined in 4 different files.

bild_besch.cc(9)
grund_besch.cc(31)
simgraph16.cc(65)
simsys_w.cc(46)


Shouldn't it be defined in one place; simgraph.h only?
- My code doesn't have bugs. It develops random features...

kierongreen

#5
Would make sense...

Edit: incorporated suggestion into trunk
r6586 | kierongreen | 2013-07-12 14:56:57 +0100 (Fri, 12 Jul 2013) | 1 line

PIXVAL typedef moved to simgraph.h

Ters

It would also make sense for get_system_color() to return this type.

Max-Max

I have actually started to sketch on a color_t class that can do all the conversions, lookup, blending etc...

But this is only on the drawing board so far. I will try to send a patch today that makes it possible to set some colours (indexed so far) through the new themes.tab file. When I have the color_t class ready you can specify a color as (hex) #RRGGBB or (decimal) r,g,b or index.

I take it as kierongreen has taken care of the PIXVAL definition and return type.

I'm missing a colour index for NO_COLOR (or COL_DEFAULT, COL_INVALID) which can be used to specify that default colour should be used or no colour (transparent).

Since the COLOR_VAL is an unsigned we can't use the old trusty -1, but as I understand, there can only be 224 colours in the indexed colour table. Maybe we can pick an index a bit higher up for this purpose?

Suggestions?
- My code doesn't have bugs. It develops random features...

Ters

If you keep going the way you're going, you'll end up rewriting the entire graphics system. I advice you to return to your original goal.

Simutrans actually has 65536 indexed colors. The first 32768 change with the day/night cycle. Then there are a player colors, which change depending on active player, and color for lights, which change discontinuously with the day/night cycle. The remaining over 30000 indexes are unused. But this is only used for rendering the world as far as I know. The GUI operates on a the smaller color table which is defined by the pak set. These colors have special meaning, which should be referred to, but not be defined by, the GUI theme.

Makeobj has certain color values reserved for mapping to these indexed colors, as well as transparent. It might be a good idea to reuse them for consistency, though tab files could use a special token instead of an RGB triple. The magic color values should be documented somewhere for the artists. Yet artists sometimes inadvertently use these colors, resulting in objects that glow in the dark.

kierongreen

I've just removed all the typedefs from the individual cc files and put one in simgraph.h that's all.

Max-Max

I was only looking for an easier way to define a colour for highlight, shadow, text etc... An index number doesn't say much and the limited index table doesn't offer to many colours either.

I was just looking for a way to define an arbitrary (not reserved) colour.
The COL_DEFAULT (or similar) is just a way to say that the default colour should be used where a function call needs a colour parameter,  such in buttons, labels etc...
- My code doesn't have bugs. It develops random features...

prissi

You could match the RGB value with the index. I added a get_color to the tabfile, which will always return an index, but internally handles also #AABBCC .

Ters

Quote from: Max-Max on July 12, 2013, 10:03:15 PM
I was only looking for an easier way to define a colour for highlight, shadow, text etc... An index number doesn't say much and the limited index table doesn't offer to many colours either.

It depends on what you want to highlight or give a shadow (not cast a shadow). For things colored according to player, like station and vehicle window title bars, one would have to use indexes or pseudo-colors. Not the real indexes in the 256 color specialcolormap, but ones that are remapped according to player. There are 32 such colors per player, divided in two 16 color ranges that each are variations of the two base colors for a player.

For colors that should be the same in all windows, specific RGB values should be used. I see no need to stick to indexed colors.

As for special values to indicate default color and transparency, I think PIXVAL values up near 0xFFFF is free. For specifying "use default color" in a tab file, I would suggest not specifying a color at all.

Max-Max

I'm a little bit confused here :o I will try explain what I want to do:

When I draw the images for a theme (only GUI related images) in for example photoshop I use any color I want in RGB888.

1) In simutrans I want the same coulours to be used as I chose in photoshop (oviosly converted to RGB555 by simutrans) not converted to nerest indexed system/predefined/special palette colour.

2) In the case of a missing theme element a fallback representation will be drawn. The draw routine needs a COLOR_VAL and this is an index, not a RGB555 value.

I don't see any reasons why the GUI should respond to any night/day coulours only player coulours would do. Currently there is no reserved index for system coulours, such as button highlight, button shadow, button face, static text, disabled text to mention a few. These coulours are a part of the theme and needs to be specified in the theme.

Have I understood right that it is possible to use a separate colour table (or space in the it table) where we could read in the RGB coulours from the theme file?

Or can this be solved in another way?
- My code doesn't have bugs. It develops random features...

Ters

I believe GUI colors should work like regular image colors, except that the special color values for lights should preferably not be used (they would still work, for now). For images, that means it stays as it is now. When specifying colors in the theme file, rather than painting them directly in images, it would be better to use symbolic names for these colors rather than magic RGB codes. This is on an assumption that the theme doesn't need to specify particular colors for a particular player, just the single active player for the particular GUI element.

Or is it really necessary for GUI images to be recolored by the theme tab file?

When reading in a theme that doesn't define a particular color for a theme element, a default color should be assigned for it during loading of the theme, so no special color value is needed for this further in.

Max-Max

QuoteI believe GUI colors should work like regular image colors...
Ok, That was my understanding too...  :thumbsup:

QuoteWhen specifying colors in the theme file, rather than painting them directly in images...
No, this isn't what I mean.

If you are happy with the gui look built into Simutrans (fallback code) you must be able to define what colour highlight, shadow, text, backgrounds should be painted in. I might want to have a dark background and then I must be able to define a matching RGB colour to draw the text with. In this way I can create colour theme by only redefining the gui system colours in the theme.tab file.

in the theme.tab file I can define the colours for the elements.

gui_static_text  = #AABBCC
gui_face         = #000022
gui_disable_text = #777777


These colours needs to be stored in the colour table so we can refer to them by index. But we want this index to have the specified colour from the theme.tab file.

Today we don't have reserved colour indexes for gui system colours (text, disabled, highlight, shadow, face etc...).
As Prissi mentioned before, this colour can be defined either as RGB or by index. If it is by index the indexed colour's RGB value is simply copied to the gui color table.

QuoteWhen reading in a theme that doesn't define a particular color for a theme element, a default color should be assigned for it during loading of the theme...
Yes, this is already how it works now. All gui elements have both fallback drawing and colours.

QuoteOr is it really necessary for GUI images to be recolored by the theme tab file?
No, you use the player colour and transparent colour as usual when designing the theme graphic images (for now). I haven't looked at the blending possibilities yet. I guess we can do quite interesting stuff with them as well, but maybe later down the road, who knows ;)

So what I understand of this is:
1) No we have no indexed system colours for gui.
2) It is possible to reserve indexes for these gui system colours (we have space).

Prissi
I guess you can give a hand here if you have time. I think it is an excellent idea to be able to refer to an indexed colour by name in the theme.tab file. In this way I could, for example, define the background to be the player colour. I don't think we need all of them, but at least the player colours.
- My code doesn't have bugs. It develops random features...

Ters

Why is it necessary to store the element colors in the index table when there is no need for image recoloring? That's what the index tables primarily are for, from my understanding. The GUI could just store the colors in its own table, and send the actual colors to the drawing routines. I'm unsure if there are any drawing routines that can either accept a real color or a indexed color, except for some related to images.

Max-Max

But how do you send an RGB colour value to the display_XXX functions?

display_text_proportional_len_clip()
display_fillbox_wh_clip()
display_vline_wh_clip()
display_ddd_box_clip
etc...


Doesn't these functions need a colour index?
- My code doesn't have bugs. It develops random features...

Ters

We can always write new functions if it makes sense to do so. It is important to think through how it best should work and then write the code to support that, not make strange solutions based on what functions are available.

Max-Max

This is why I'm asking. I haven't been digging enough in the low level graphic routines to make this decision by myself.

What is it you propose, new display_xxx routines that takes an RGB value as colour?
- My code doesn't have bugs. It develops random features...

kierongreen

That would certainly give more flexibility in future.

Max-Max

Isn't it easier to just add some more system indexed colours, load the RGB values from themes.tab into the colour table?

We have to store the RGB values in a system colour variable anyway, so I don't see what the difference is from reading the RGB values or passing the index of the RGB value.

If we are to rewrite all display_XXX routines to take RGB insted of index, we will end up in a lot of rewriting. It feels like a separate project in itself.
- My code doesn't have bugs. It develops random features...

Ters

What should refer to these special colors? Only code?

Max-Max

Yes, code only.

The user defines the colours in theme.tab, for example:

gui_static_text  = #AABBCC
gui_face         = #000022
gui_disable_text = #777777


These user defined colours are used internally in all display_xxx.
- My code doesn't have bugs. It develops random features...

kierongreen

I can look into the routines when I get home in a couple of days.

Max-Max

Splendid!

The system colours are now stored as COLOR_VAL in simskin.cc and handy defines in simcolor.h
themes_init() in simwin.cc are reading in them from theme.tab file.

The system works with indexes now and if we go for the expanded index table themes_init() should read the RGB values into the colour table.

I guess you will see what needs to be done ;)
- My code doesn't have bugs. It develops random features...

Ters

I think a new color table and therefore new functions are needed in any case. The player color table is a player color table, so it can't be used for new colors. The other one is tied to the day/night cycle. Even if the latter might be used by the current GUI, I think it's best to make a clear distinction between colors used for lights and colors used for the user interface. The former is specified in pak/simuconf.tab while the latter would belong in theme.tab.

Edit:
Didn't see the last post before posting.

prissi

As for now, the RGB is just translated into the best matching color index. Why is this not enough for the moment?

Also, as stated, the player colro table (the one with the 248 indexed colors) must not be touched, or player colors and factory colors and a lot of other hardcoded stuff in many routines which uses index will be wrong. But as also mentioned, a routine to draw a line/box with an RGB color is quite straight forward. Most of the current code just lookup the color from the inex anyway before drawing.

Recoloring images will be different though.

Max-Max

That was why I suggested to expand the current colour table and no, the default colours aren't enough. If you design a theme in photoshop, you are quite picky with the colours, especially if they are translated to RGB555 in Simutrans.

This is why I feel the need of a separate colour table that reads in RGB colours from the theme.tab file.
Each index in this table will become a GUI system colour such as Highlight, shadow, face, text, disabled text, static text, focus colour etc...

I think it would be good to create a colour class with member functions for colour manipulation. You could for example add two colours with a simple operator+(), get the index of nearest matching colour in the special colour table, blend a colour with alpha from another colour etc...

With an RGB/HSV colour dialogue the user could for example pick his player colour.
- My code doesn't have bugs. It develops random features...

Ters

Quote from: prissi on July 28, 2013, 10:56:57 PM
As for now, the RGB is just translated into the best matching color index. Why is this not enough for the moment?

I imagine that the best matching color could be very different.

Quote from: Max-Max on July 28, 2013, 11:45:57 PM
I think it would be good to create a colour class with member functions for colour manipulation. You could for example add two colours with a simple operator+(), get the index of nearest matching colour in the special colour table, blend a colour with alpha from another colour etc...

I don't think one should ever go from a color to an index, only the other way. You never know what index you end up with, what that index is for, and that index might stand for a very different color at different times.

Max-Max

QuoteI don't think one should ever go from a color to an index, only the other way. You never know what index you end up with, what that index is for, and that index might stand for a very different color at different times.
Makes sense, you might end up with a night colour ;)

What I meant was that we should try to encapsulate the colour manipulation/handling in a class.

The class can function as an adaptor between current system and "new" system to gradually replace the index system.
Each colour table can be an class instance and return a colour object for the requested system colour.

This colour object can be added, assigned, manipulated etc through member functions and operators like.

MyColor = "FFAADD";                // Assign from a Hex string
MyColor = RGB8(234,211,34);  // Assign from an RGB888 valaue (converted to RGB555)
MyColor = ThatColor;               // Assign from another colour object
MyColor = ThatColor + RGB8(1,3,6); // Assign from ThatColor + an RGB888 to RGB555 converted colour
MyColor.Blend(50);                  // Blend MyColor 50%
MyColor.Blend(30,ThatColor);  // Blend MyColor 30% with That colour

And so on...

A System color manager can handle the table of system colours.

ColManager[SYSCOL_TEXT] = RGB(0,0,0); // Assigna system colour
ColManager[SYSCOL_FACE].Blend(20,"AAAAAA"); Blend the system colour 20% with the Hex string colour
MyColor = ColManager[PLAYER_COL1]; Get the color of PLAYER_COL1

You get what I mean....
- My code doesn't have bugs. It develops random features...

Ters

Doing blending a color_t at a time is not an efficient way of doing it large scale, so while such a member function might be useful, it is likely that most blending will not use it.

One thing here is that Simutrans' architecture is made to support different color depths, though only "0" and 16-bit is currently used. Should we keep this feature, or drop it for simplicity? 8-bit support is likely pointless.

A single manager for all indexed colors might be difficult, because the different color tables behave differently. It might be better to have one manager for each color table.

Max-Max

If I could get a Christmas present It would definitely be 32bit (RGBA8888) :)

The benefit of having one colour manager is that you don't need to know anything about colour tables, night colours, player colours etc... The manager will pick the right values from the right table for you. You don't need to know how colours are stored or managed and access them all in the same way through the same interface.

If you really want to have separated managers, define a common interface in an ADT and derive each manager from it.

I'm just brain storming here, but with a manager we are no longer bound to a fixed colour space because the manager will store and maintain all colours for us.

One cool thing that might be possible is animated colour palettes. The PAK designer could define a colour ramp that will be used as a function of time over a day/night cycle. The colour manager would return colours from the ramp depending on the day/night time. The PAK designer could also define what colours should be replaced by such function and would not be bound to use any specific colours for night and day.

A color.dat file might define these special colours and maybe how they change. Depending on the complexity we could for example say that the ramp should be distributed over day or night cycle or at a specific time.

As I said, I'm just brainstorming and I see great potential here to add more tools for the artists to work with...
- My code doesn't have bugs. It develops random features...

prissi

Allmost any gui elements will be/is derived from PNGs (at least for title bars, icons, buttons ,... ) The old thing from a color index are font colors and the outline of a box (a 1 px thin line). For those an index seems ok.

Also the current code does not use adding two colors at all. The only thing are lighter and darker player colors. But as said previously, almost any function (like text drawing etc.) that takes an index concerts it into an rgb555. It will be very easy to have a function with index which just calls then the main function with rgb (888 of course).

32 bit is quite easy. But the larger the screens nowadys make even a larger hit to the performance. It was substancial slower the last time I played around (You could easily compile a 32 bit version, at least for GDI by setting the right defines in simsys_w32.cc imho).

Ters

Quote from: Max-Max on July 29, 2013, 09:24:44 PM
The benefit of having one colour manager is that you don't need to know anything about colour tables, night colours, player colours etc...

But you need to anyway. If it's a player color, the cached pre-remapped image must be regenerated or disregarded when you're drawing something belonging to another player than the one that was cached. If it's a night color, the same must be done when the day-night cycle changes.

When accessing a player color, you must also say for which player. This parameter would be useless for everything else. The internal logic is also very different, so you'd have lots of external code that just calls into one function, that in turn branches out to corresponding internal code.

GUI code shouldn't use special colors (lights). Nothing but the user interface should use theme colors. Everything uses player colors, though.

Max-Max

I was thinking that when an image asks for a colour it doesn't need to know if it is a special colour, the manager will know this from the requested colour and return whatever colour it should be replaced with because the manager knows what colours should be mapped to a colour ramp or not (from the PAK colour definition).

Today we use special RGB values to indicate a special colour and these (I guess) are replaced when drawn depending on day/night cycle. The Idea was to let the PAK designer define these RGB special colours by himself and then also let him define how these colours are switched.

The difference here is that instead of having a hard coded RGB definition of each special colour, the PAK designer can define them. These are read in and used instead of the hard coded RGB values and matched in the same way as now to change night/day colours.

Instead of having only a day/night colour, the PAK designer could provide a colour ramp so the day night defined colour is switched to a different colour depending on the day/night/season cycle...

I will try to illustrate a practical example:

The day colour 0xC1B1D1 is replaced with the colour 0xD3C380 during the night (regarding to the Wiki). These colours are hard coded.

What I mean is that the artist can define an arbitrary colour to be replaced with another arbitrary colour, isn't it how it works now? Except that these colours are hard coded?. The colours would be defined in the PAK file and read into the colour manager.

format Color[n] = <SpecialColourTrigger>, <type>, <colour> [, <colour> ...]

<SpecialColourTrigger> is the colour in the image that will be replaced.
<type> decides how this colour is replaced.
<colour> [, <colour> ...] are one or more colour parameters defined by the <type>

# define RGB color #000001 to be a Day/Night colour, alternating between Day #8888FF and Night #111144
color[0] = #000001, DN, #8888FF, #111144

# define RGB colour #000002 to be a time triggered colour changing at hours 06, 07, 09, 12, 17, 18, 20, 21
color[1] = #000002, T, 06:#222266, 07:#333388, 09:#5555CC, 12:#8888FF, 17:#5555CC, 18:#333388, 20:#222266, 21:#111144


The type can be anything we can imagine :)

With this concept we are not bound to a limited predefined set of day/night colours and it doesn't has to be just one colour change (day/night) but different colours at different times of the day (if the PAK designer wants to). It can also be used to switch on "lights" in different windows at different time.

For theme primitives an SYSCOL_XXXX enum is mapped against a preloaded RGB table.
If an artist which, a theme image could also use this scheme to get darker and glow during night time.

A theme must in some way be able to show a player colour and this can be defined in the same way by using a <type> for player colours.
With this concept we only need to distinguish between indexed SYSCOL_XXXX (to colour primitives and text) and image special image colours.
If the Indexed system colour's RGB value is checked against the special colour table, well then you can have text to glow in the dark too :)

All this is handled by the manager. If the manager builds a sorted list of hours when to change a colour it only needs to be called once every hour and to execute the change, then the colour request doesn't need any logic in the moment we use a colour.

(you get the picture, there are a number of ways to optimize this for performance).

I have no idea of how the colour stuff works now, but it was just a thought...
- My code doesn't have bugs. It develops random features...

Ters

Quote from: Max-Max on July 29, 2013, 11:45:38 PM
I was thinking that when an image asks for a colour it doesn't need to know if it is a special colour, the manager will know this from the requested colour and return whatever colour it should be replaced with because the manager knows what colours should be mapped to a colour ramp or not (from the PAK colour definition).

This happens when running makeobj, which is a somewhat different thing from Simutrans itself, though some code is shared. There are no magic RGB values in images as far as Simutrans itself is concerned. Day/night colors are not hard coded (except the defaults), but configurable by simuconf.tab for each pak set.

Max-Max

Why do we have hard coded day/night colours if they can be configured in the pack set? (more than for backward compatibility?)

I didn't find this information in the English Wiki, but if I understand you right; already now a PAK designer can define what colours should be day/night colours and what colour they should be replaced with? (pretty mush as I suggested above)
- My code doesn't have bugs. It develops random features...

Ters

The number of indexes are hard coded, but the actual colors are not. Hard coded defaults are likely for compatibility and convenience.

The color values mapped to indexes by makeobj is also hard coded, likely because there is little reason for doing otherwise. Flexible colors here has the drawback that you can't reuse images across pak sets without replacing these colors.

wlindley

Can we unite the "industry colors" (see the MapColor parameter here) into the global color table?  In the same way we can draw player objects with primary-and-secondary color-scale values, it would be quite nice if one could draw factories with primary-and-secondary industry-colors, using the same two sets of "player" colors.  In that way, one could draw a single shop that would inherit whatever industry colors were assigned to it in the dat file -- a single set of images (four rotations, plus four snow rotations) would suffice for the butcher, the baker, the candle-stick maker, and so on, with only a mapcolor= parameter in the dat file (and a new mapcolor2= parameter, i suppose, for the secondary color).

Ters

More special colors makes it easier for the artist to inadvertently use a special color. Just doing such simple color replacements in the image editor might be the lesser evil.

Regarding my former post, I was mostly thinking of transparency and player colors. Color for lights has some merit in that one could use the same color both in and out, and these aren't fully interchangeable between pak sets anyway. There is still the issue that a color that works normally in one pak set has a special meaning in another, which can be confusing.

Max-Max

We are talking about artists here and we can assume they know one or two things about colours. Just assuming that something is confusing is like a farmer would tell me that a piece of code is to confusing for me to understand (unless the farmer happen to be programmer as well) :o

It is our job to make complex things easy for the novice, meaning we handle the complexity, not the artist :) I'm pretty sure we can do quite amazing things with colours under the hood and provide the artists with rich possibilities...

For example, I made a swatch palette with all the special colours (named and everything) ready to use in Photoshop. These small things may be all the artist need to understand the concept.
- My code doesn't have bugs. It develops random features...

Ters

Artists often get into trouble with the special colors we already have, using them when they shouldn't. That is very easy in image editors and 3D programs, as they don't know which colors makeobj treats specially, nor have logic to avoid certain colors. I also think most artists are amateurs, or more used to that colors are just colors.

Quote from: Max-Max on July 30, 2013, 10:50:12 PM
It is our job to make complex things easy for the novice, meaning we handle the complexity, not the artist :)
It's just that to me, you're suggesting making thing more complex for the artists.

Fabio

one idea if/when going rgb32 (with alpha) would be to remove special colors altogether and use 1 or 2 bw image masks to tell makeobj which areas should glow at night and which should be player-re-colored.

wlindley

I was hoping to use the already-reserved "player colors" (in the .png files), but have them handled differently for factories.  Currently, because all factories are owned by the public player, those colors just become grey (or was it orange; it has been some time since I checked). My suggestion was that they be translated to a higher range in the 65K color table, but still treated as group-of-8-color-scales like the player colors but for the industry MapColor.

As for masks -- can we at least use .png's transparency instead of a reserved background color?

Ters

Quote from: Fabio on July 31, 2013, 08:09:11 AM
one idea if/when going rgb32 (with alpha) would be to remove special colors altogether and use 1 or 2 bw image masks to tell makeobj which areas should glow at night and which should be player-re-colored.

I've been thinking at alternative solutions, and I don't think this will work. A mask for player color could be possible, but not for day/night colors. Not without losing the feature that day and night colors are different. Windows are blackish at day and lit at night. One would need many sets of images then: one image with base colors, one image with mask for player colors, one image with day colored light and one image with night colored lights. It might be possible to merge day colored lights with base colors. That would give lots of freedom, but at the cost of having to keep the sets aligned and matching. I don't know what artists think of this. As these images are just different aspects of the same thing, it would count as one image internally.

Quote from: wlindley on July 31, 2013, 08:33:01 AM
I was hoping to use the already-reserved "player colors" (in the .png files), but have them handled differently for factories.

There might be issues with caching of player-recolored images, but perhaps not much worse than a game with multiple players anyway. As a player, I'd prefer that simple color swaps only indicate ownership, and not to tell different industries apart.

Max-Max

#46
I think I will go back to the original request of this thread to try reserving some system colours in a new sys_color array.
Now we have a bunch of COLOR_VAL variables defining what color index should be used for various system colours:

COLOR_VAL gui_theme_t::theme_color_highlight           = MN_GREY4;
COLOR_VAL gui_theme_t::theme_color_shadow              = MN_GREY0;
COLOR_VAL gui_theme_t::theme_color_face                = MN_GREY2;
COLOR_VAL gui_theme_t::theme_color_button_text         = COL_BLACK;
COLOR_VAL gui_theme_t::theme_color_text                = COL_BLACK;
COLOR_VAL gui_theme_t::theme_color_text_highlite       = COL_WHITE;
COLOR_VAL gui_theme_t::theme_color_selected_text       = COL_WHITE;
COLOR_VAL gui_theme_t::theme_color_selected_background = COL_BLUE;
COLOR_VAL gui_theme_t::theme_color_static_text         = COL_BLACK;
COLOR_VAL gui_theme_t::theme_color_disabled_text       = MN_GREY4;
COLOR_VAL gui_theme_t::button_color_text               = COL_BLACK;
COLOR_VAL gui_theme_t::button_color_disabled_text      = MN_GREY0;
COLOR_VAL gui_theme_t::button_color_focus              = COL_WHITE;


The artist/user can override these values through the themes.tab file, but only redirect them to a new index not a specific colour.
This is quite frustrating because you need precisely that RGB colour to go with your theme, and it isn't available!

My thought was to create a system colour table (array) where the index is a specific system colour (such as color_shadow, or color_text_highlite). This table is of PIXVAL type (RGB1555) so the RGB colour can be loaded from the themes.tab file. In this way the artist/player can control the system colours a bit better.

As every one can see, these system colours are mainly text colours, an important part to control if you make a light or dark theme.
It looks trivial in my mind  :::) but I have not been in that part so much yet to truly understand how much work there is. I can say that these colours are not recoloured, nor accessible through the artists images (no mapping as we do for special colours).

enum sys_colors_et {
  SYSCOL_HIGHLIGHT = 0x<some suitable value>,
  SYSCOL_SHADOW,
  SYSCOL_FACE.
  SYSCOL_BUTTON_TEXT,
     ...
     ...
  SYS_COL_END_LIST
};

PIXVAL sys_colors[SYS_COL_END_LIST];
load_sys_colors();
display_proportional_clip(a,b,"bla bla",  ALIGN_LEFT | DT_DIRTY | DT_CLIP, SYSCOL_BUTTON_TEXT);


Any one up for the task?
- My code doesn't have bugs. It develops random features...

prissi

You can request any color by using #AB12CF in simuconf.tab. Despite any change you make later, simucponf.tab can use this already. As there are already too much construction areas with the themeable GUI (i.e. dialogue need to work with different sizes) and we need to release a stable version before the end of the year, I would not consider this top priority. The lookup tables are anyway needed for the factory and player color.

The color system is somethign I woudl suggest to renovate on its own at a later stage.

Max-Max

Alright, I complete renovation of the colours system is highly welcomed. I sooo want 24bit RGB/A (RGBA8888) :)
- My code doesn't have bugs. It develops random features...

Max-Max

#49
I think we need to address this issue again.

If the artist has the full RGB1555 range when designing the theme, he must also have the same range when setting the system colours.
In the current implementation he can set a RGB888 value, but  instead of converting it to a RGB1555 value, just as his images are, it its mapped to an indexed colour. This may end up as something very different than the same RGB888 value he used in the theme.

The two rgbmap_day_night and rgbmap_all_day colour tables are of the size 0x8000+LIGHT_COUNT+16 and there must be an index range available for system colours.

Can some one point out a block free colours indexes that I can use for system colours? I will have the theme manager to load RGB888 from the theme.tab, convert to RGB1555 and put them in the list  so they can be used with the normal colour index oriented display_xxx routines.

maybe 0x8F00 - 0x8FFF ?

***EDIT
After some more digging it seems like the primitive draw functions use specialcolormap_day_night[] and specialcolormap_all_day[] both the size of 256 entries. Maybe I should increase this to 512 so we get another 256 user defined system colours.

System colours are for example The highlight and shadow colours of "3D" rectangles, text colours etc...
- My code doesn't have bugs. It develops random features...

prissi

OpenTTD uses 216 color and never had much a trouble with those colors. The actual difference of colors on a monitor will much larger than the differences on the screen. At least no artist complained so far.

Ters

Quote from: Max-Max on October 05, 2013, 06:28:22 PM
In the current implementation he can set a RGB888 value, but  instead of converting it to a RGB1555 value, just as his images are, it its mapped to an indexed colour. This may end up as something very different than the same RGB888 value he used in the theme.

This not how it should be in my opinion. The variable that now holds the indexed color should hold the RGB555/565 color value, not an index. Indexed colors are only needed if images need to refer to them. Is that the case?

Max-Max

Quote from: prissi on October 05, 2013, 07:59:04 PMOpenTTD uses 216 color and never had much a trouble with those colors. The actual difference of colors on a monitor will much larger than the differences on the screen. At least no artist complained so far.
Maybe that is because the artist has never been able to set text colours, highlight etc. before. I found it quite annoying when I started to make the theme-paks, so I'm complaining ;)

Quote from: Ters on October 05, 2013, 08:05:07 PM
This not how it should be in my opinion. The variable that now holds the indexed color should hold the RGB555/565 color value, not an index.
I totally agree with you, but since no one is remaking this now the simplest solution was to extend the current system.
Quote from: Ters on October 05, 2013, 08:05:07 PMIndexed colors are only needed if images need to refer to them. Is that the case?
No, all basic drawing and text drawing are using an index into specialcolormap_all_day[]. Images are using direct PIXVAL.




I have already a working mock-up now. It turned out it was enough to increase the specialcolormap_all_day[] to make it work. Now the RGB1555 version of the RGB888 will be used and are stored at index 256 and up.

Now we can get rid of all the variables holding the system colour indexes.
- My code doesn't have bugs. It develops random features...

Ters

Quote from: Max-Max on October 05, 2013, 08:46:21 PM
I totally agree with you, but since no one is remaking this now the simplest solution was to extend the current system.

Touching the special colors, especially as a hack, is the last option. It affects way too many things. There should be half a dozen easier and better solutions.

Max-Max

Quote from: Ters on October 05, 2013, 09:54:07 PM
Touching the special colors, especially as a hack, is the last option. It affects way too many things. There should be half a dozen easier and better solutions.
I have not touch the special colours at all, they are exactly as before. I have only extended the array and placed the system colours on top of them. In this way I can use indexes > special colours and all the display_xxx primitives like, lines, boxes and text can now benefit from the extra system colours without any modifications.

Images are not using this indexed table and all the image related functions, used to recolour with special colours are unaffected.

In what way is this a hack? See it like we have expanded the list of special colours, but these are only used by the GUI system.
How would you have done it to not be considered a hack?

Since no one is working on a new colour solution on this side of the moon, I think this is the most clean way to do it, with a minimum impact of what we already have.
- My code doesn't have bugs. It develops random features...

Ters

I don't like it because it widens the gap between the special indexed colors available for drawing primitives and the indexed colors used in images. All these indexed tables, somewhat related yet somewhat different is confusing.

Building more functionality upon it makes it more difficult to change later. It's a hack because it's a small tweak that makes something kind of do what you want in a roundabout way, rather than doing it properly. And it's roundabout because it's pointless and overkill to have to allocate a handle (index) for something a trivial as a color value. The only thing justifying that is the ability to recolor images at runtime.

Maybe I can make some proper primitive drawing functions during the day. simgraph16.cc is a part of the code I know. But that might be the wrong choice if it turns out that recoloring GUI images at runtime is something we need later.

Max-Max

We do need player colours in the GUI so the artist can indicate the player somehow and in the end I can imagine that also factory colours would be handy. I have seen some requests on factory colours from the artists.

I brought up the idea of a colour manager earlier, to handle animated colours, such as day/night changes, colour conversions etc...
The artist would have a lot more freedom if he could chose the RGB values for these colours as well. This can easily be done by simply modify the special colour table. In my implementation I limited it to only be system colours, but it could go for all of them.
- My code doesn't have bugs. It develops random features...

Ters

The special colors table has a layout designed for player colors, where one can go one index up or down within a block to get a brighter or darker player color. Generic colors don't fit into this structure. They would fit into rgbmap_all_day, but that's only used for recoding images, not the primitive drawing functions.

Max-Max

Quote from: Ters on October 06, 2013, 02:42:43 PM
The special colors table has a layout designed for player colors, where one can go one index up or down within a block to get a brighter or darker player color. Generic colors don't fit into this structure. They would fit into rgbmap_all_day, but that's only used for recoding images, not the primitive drawing functions.
The Artist could set the Primary and Secondary colour and Simutrans can calculate the shades. This would give the artist/user more freedom. I have an idea of replacing the Player Color pick dialogue with an RGB colour picker. This may cause collisions in multilayer games, but it can be handled either by using the old colour picker for multilayer games or to just have the player to chose another colour if the one he selected is to close another player's colour.

There is always a solution to every problem ;)

PS. Wouldn't it be a good idea to move all colour related code to simcolor.h and a Simcolor.cc ?? DS.
- My code doesn't have bugs. It develops random features...

Ters

Quote from: Max-Max on October 06, 2013, 03:43:32 PM
PS. Wouldn't it be a good idea to move all colour related code to simcolor.h and a Simcolor.cc ?? DS.

It would be nice if it atleast was all collected together in one part of simgraph16.cc. The possibly main argument for keeping it in simgraph16.cc is that the color code is tied to 16-bit graphics. While we don't have 8-bit graphics anymore, there is still the 0-bit graphics.

Max-Max

So what approach would you recomed to implement the customized system colours.
Obviously we need to store them somewhere and they need to be fetched somehow, probably indexed.

I could create a color_list class where each color can be accessed through the operator[]. This could be the base class for colour lists in general. In the future it could also handle animated colour palettes so the system wouldn't have to keep track of when to switch colours.

Or I could just add another PIXVAL system_colormap[xxx];

I would prefer the class solution because it encapsulates colour handling, such as colour conversion, animation, loading etc...
It can also be derived into different types of colour lists.
- My code doesn't have bugs. It develops random features...

Fabio

If one day we moved to full RGBA32 would we have a concurrent simgraph32 or would we simply update existing files?

Max-Max

QuoteIf one day we moved to full RGBA32 would we have a concurrent simgraph32 or would we simply update existing files?
If we encapsulate colour handling into objects it would be easier to add new formats, such as RGBA32 and have the correct conversion in the object.
The use of a canvas concept would encapsulate the differences in low level drawing.

However there is a design pattern for this kind of problem, the Bridge pattern that allows a logical structure evolve independent of the hardware capabilities. They even don't need to use the same interface.

The canvas provide a public logical interface with primitives and use a separate class for the low level drawing. By switching this low level class, we can switch between many different platforms and/or graphical formats. We already have some sort of similar structure today, but they aren't encapsulated and separated.

In the theme manager there is a candidate for a canvas class, currently working on low level raw bitmaps, but can be the starting point for a canvas design.
- My code doesn't have bugs. It develops random features...

Ters

Quote from: Max-Max on October 06, 2013, 04:11:01 PM
So what approach would you recomed to implement the customized system colours.
Obviously we need to store them somewhere and they need to be fetched somehow, probably indexed.

How are they to be used? The advantage of indexed colors in Simutrans is that you can either encode them in color values (as images do) or do arithmetic on the indexes to get related colors (as for player color).

Quote from: Max-Max on October 06, 2013, 04:28:36 PM
If we encapsulate colour handling into objects it would be easier to add new formats, such as RGBA32 and have the correct conversion in the object.

If we encapsulate colour handling into files it would be easier to add new formats, such as RGBA32 and have the correct conversion in the file.

It's the same concept of modularization. The only real difference is that with objects, you can in theory switch them at runtime. (It can be done with file modules as well, but then it gets really ugly.)