Yeah, it's hard to get the light/dark balanced well. So, now I've tried making a list of all the RGB values for the ANSI colors in a client (PuTTY in this case) and picking whichever has the closest brightness. It's looking better. Decided to use a pixelation effect in Photoshop to see how the brightness looks. Didn't turn out well… think I'll just use unicode block characters next time.
I'm planning to release a snippet soon, I'm still working on a better 256 color to 16 color conversion algorithm.
The Web suggests that the best way to do that is to treat red, green and blue as points in a three-dimensional space, and determine closeness using the euclidean distance. So, once you've collated the RGB values of 256-colour, and the same of 16-colour, then it should be relatively trivial to brute force a lookup table for the closest 16-colour points to each 256-colour point, creating a better match all round.
(Edit: I think that's what Quix did in his example above? Not sure)
24 Jun, 2011, quixadhal wrote in the 24th comment:
Votes: 0
Yep, that's pretty much what I did Kaz. As an added bonus, you can map arbitrary 24-bit color to xterm256 if you're willing to take the CPU hit (can't cache 2^24 entries very nicely). You can map down to 16 colors nicely, and you can map from the full 256 color palette to the 24 entry greyscale palette to provide a monochrome display for color-blind folks too.
A brief observation, after playing a bit with extended colours:
Although it's useful to have an automatic conversion algorithm, in many cases I find I'd rather provide an explicit alternative. For example, orange is nice for brick walls on my ASCII maps, but if the user only supports standard ANSI colour then I'd rather use magenta, as it stands out better. Similarly for channels - I use different colours to differentiate between them, so it would be undesirable for two channels to be converted to the same ANSI colour.
The automatic conversion seems to be more appropriate for user-customised colours, or for cosmetic things like unicorn-puke titles and ASCII art.
Yep, that's pretty much what I did Kaz. As an added bonus, you can map arbitrary 24-bit color to xterm256 if you're willing to take the CPU hit (can't cache 2^24 entries very nicely). You can map down to 16 colors nicely, and you can map from the full 256 color palette to the 24 entry greyscale palette to provide a monochrome display for color-blind folks too.
*nod* For the 16m-256 conversion, it might be more efficient to pre-compute the entire lot into a file and either load that (and hold the 16MB in memory) or just mmap the file and read an offset out of it when you want the quantized value. Or something like that.
The automatic conversion seems to be more appropriate for user-customised colours, or for cosmetic things like unicorn-puke titles and ASCII art.
I suppose there's no reason you couldn't have different quantization techniques at different times. For artwork (I think my GUI would count on this: I might prefer a nice pastel blue to show that a field has focus, but bright cyan works just as well on less capable clients.), then using euclidean distance would be an appropriate method. For tiled maps carrying specific semantic information, then having a short lookup table of preferred 16m, 256 and 16 colour entries is probably superior.
I ended up settling for a conversion method that is fairly balanced between dim, bold, primary, and secondary colors. Here's the output:
25 Jun, 2011, Rarva.Riendf wrote in the 28th comment:
Votes: 0
Wow nice work
26 Jun, 2011, Rarva.Riendf wrote in the 29th comment:
Votes: 0
I just came into some problems that were triggered by lots of color code in a buffer, (Rom pager problem) so I will also ask it here: Has any of you coded something to remove useless color codes in buffers ? Because when you dynamically build (in my case by generating a colored map) a buffer you can have things like color a text1 color a text 2 colora text 3 etc when jsut one color a would be well enough.
27 Jun, 2011, quixadhal wrote in the 30th comment:
Votes: 0
No, I chose to make my DikuMUD's pager less stupid (IE: break the string up into lines and allocate buffers for each line, held in a fifo queue). I suggest fixing the problem (fixed length buffers), rather than the symptom (things that actually exceed those buffers).
27 Jun, 2011, Rarva.Riendf wrote in the 31st comment:
No, I chose to make my DikuMUD's pager less stupid (IE: break the string up into lines and allocate buffers for each line, held in a fifo queue). I suggest fixing the problem (fixed length buffers), rather than the symptom (things that actually exceed those buffers).
Well fixing the problem was easy, the sympton would still need to be enhancedso the pager is less used(for player convenience, hitting return is bothersome if it can be avoided) And I have a question, I could break the string into lines, but then how do you send them without disconnecting the client ? (because that is the pager main goal in the first place) without blocking more important info (usually very large string are helps maps etc, nothing vital)
No, I chose to make my DikuMUD's pager less stupid (IE: break the string up into lines and allocate buffers for each line, held in a fifo queue). I suggest fixing the problem (fixed length buffers), rather than the symptom (things that actually exceed those buffers).
Well fixing the problem was easy, the sympton would still need to be enhancedso the pager is less used(for player convenience, hitting return is bothersome if it can be avoided) And I have a question, I could break the string into lines, but then how do you send them without disconnecting the client ? (because that is the pager main goal in the first place) without blocking more important info (usually very large string are helps maps etc, nothing vital)
I may be not understanding you but… I think the main goal of the pager isn't to prevent disconnecting the person on the other end (that's dependent on the quality of the client). Rather, I think it's just to ensure that text on terminals with limited terminal height and no scrollback don't lose information.
So as I see it the only thing you can do is send less text so you don't need to page, or just send it all at once without paging and hope their client can handle it.
27 Jun, 2011, Rarva.Riendf wrote in the 33rd comment:
Votes: 0
Quote
I may be not understanding you but… I think the main goal of the pager isn't to prevent disconnecting the person on the other end (that's dependent on the quality of the client). Rather, I think it's just to ensure that text on terminals with limited terminal height and no scrollback don't lose information.
It achieves kinda both goals. I made a lot of work to limit fights output (if the player wish so) as an example so the client does not get disconnected as soon as you have 7 or 8 people fighting in the same place (it can happen pretty fast with jut a few players as they can all get charmies/pet)
Pager for me is to both output large piece of text that you know will disconnect the client if you send it all at once AND allow for limited output screen to be able to read it without scrolling back. I wish all client could use compression as it would make the life of everyone a lot easier :)
If no one did it, that is fine by me, was just asking so I dont go reinvent the wheel.
Not all all, only for text larger than 600 atm. So it does not block more vital info that shoudl be displayed as soon as they are send. Typically I have no text that could be larger than that for any info that can affect the player. Anything bigger is just stats/helps/maps etc, not something the player would need asap. I still suffer from some disconnection sometimes, but I tend to then give an option to limit the ouput. Basically an option that will not show the amage your charmies are doing to your opponent. Or one that regroup every attack damage and only show it once (You had 4 attacks landing, instead of showing all of them, only shows the cumulated dam) etc
Because when you dynamically build (in my case by generating a colored map) a buffer you can have things like color a text1 color a text 2 colora text 3 etc when jsut one color a would be well enough.
Don't insert them in the first place.
last_color = NONE while iterating over terrain map if last_color not equal this_color insert this_color last_color = this_color end insert terrain end
27 Jun, 2011, Rarva.Riendf wrote in the 38th comment:
last_color = NONE while iterating over terrain map if last_color not equal this_color insert this_color last_color = this_color end insert terrain end
Chuckle I may sound sarcastic, but I did not need you to write the algorithm. Now write me an actual C working version and I will thank you heathily ;p
Chuckle I may sound sarcastic, but I did not need you to write the algorithm. Now write me an actual C working version and I will thank you heathily ;p
Sorry I must have confused you with someone else. Rarva: "(I worked as a coder professionally for 9 years…Stock ROM code made me cry at how it was badly designed)"
Why don't you ask that chap to code this trivial function for you?
Because when you dynamically build (in my case by generating a colored map) a buffer you can have things like color a text1 color a text 2 colora text 3 etc when jsut one color a would be well enough.
Don't insert them in the first place.
last_color = NONE while iterating over terrain map if last_color not equal this_color insert this_color last_color = this_color end insert terrain end
i actually had something similar to this in my send_to_char or w/e function.