Why "Preview" you might ask... ;-)
Well... I'm really busy currently with other stuff, but I wanted to get the main-information released, so this is kind of a preview of what is to come. I will update this page in the "not-so-distant" future with more detailed descriptions, better illustrations, coverage of other members of the VIC-family (like the one in the VIC-20 and the C=16 / Plus 4 -- John 'Graham' Selck will probably help a lot with this as he owns all of those machines) and oh so much else... everything you ever wanted to know about the colors those great old Commodore-machines spit out.
The update-process will most probably launch shortly after the Mekka Symposium 2001 Party (I hope to meet some of you there).
I do know that the whole issue isn't described here in the most streamlined and optimized way. What I wanted to do first, is get all the information together and release it in order to beautify, optimize, streamline and make everything more complete later (You don't need as much numbers after the Komma as I use here currently -- this will also be changed later to tidy everything up). I will begin doing this in the near future for sure, but right now I really don't have any more time to work on this for the next couple of weeks.
The whole issue of VIC-II color-emulation is so mis-guiding and irritating, because every c64-emulator uses different palettes and these have been created by using cheap frame-grabbers/digitizers with strange color-behaviour or by moving around some rgb-sliders until it looks quite right. Many people have forgotten how the colors on a real C64 look, because they use emulators for a long time. Some people like DeeKay/Crest or Cyclone/Haujobb (he's also a member of Crest nowadays if I remember correctly) were able to create pretty good palettes by moving around rgb-sliders and comparing to a real C64, but the system described on this page gets even closer than this. Most probably you won't come much closer to the real thing, than this at all.
But let's come to the C=64 colors which will be featured here first...
The C=64 (with its VIC-II chip) features a palette of 16 colors.
# | name |
---|---|
0 | black |
1 | white |
2 | red |
3 | cyan |
4 | purple |
5 | green |
6 | blue |
7 | yellow |
8 | orange |
9 | brown |
A | light red |
B | dark grey |
C | grey |
D | light green |
E | light blue |
F | light grey |
Black, White and the three Greys are no colors and the "light"-versions of Red, Green and Blue are just brighter versions of Red, Green and Blue. That leaves us with eight unique colors.
Since the color-palette of the VIC-II has been made for the TV-system, we aren't talking a RGB-color-space, but a YUV-one (for PAL-TV that is), that we can convert to RGB later.
"Y" in the YUV-color-space is the Luma-signal which is just the "black&white-part" (the brightness) of the colors. "U" and "V" are color-difference signals, which together describe the hue and the saturation of the colors.
If you just measure the "Y" signal with an oscilloscope, you'll notice, that few of the very early VIC's just had 4 different luma-levels (excluding black) and the majority of VIC's (called the "late" ones here) have 8 different luma-levels (excluding black). They doubled them, because quite some people still had black&white TV-sets, where many colors looked exactly the same. With the "late" version, only two colors share the same brightness.
Here's a table of both of those luma-versions, ordered from darkest to brightest color (top to bottom):
early VIC-II luma |
---|
0 |
2, 6, 9, B |
4, 5, 8, A, C, E |
3, 7, D, F |
1 |
late VIC-II luma |
---|
0 |
6, 9 |
2, B |
4, 8 |
C, E |
5, A |
3, F |
7, D |
1 |
You can of course also verify this by minimizing color-saturation on your monitor, or just plugging "Y" in, or using a black&white monitor/tv.
However if you measure the luma-levels with an oscilloscope (Marko Mäkelä did so in 1996), you are able to see, that all of those levels are perfectly dividable by 32. I made a little Illustration here:
As we need to stuff the luma-values into 8 bits (0 to 255) for later calculation, we just divide 255 by 32 and get 7,96875. Now we just need to multiply the values in the Illustration with 7,96875 and round the results. Of course you may just use 8 instead of 7,96875, but as I'm quite a perfectionist I'll use 7,96875 for now and maybe change it later. ;-)
8 * 7,96875 = 63,75 = 64 |
10 * 7,96875 = 79,6875 = 80 |
12 * 7,96875 = 95,625 = 96 |
15 * 7,96875 = 119,53125 = 120 |
16 * 7,96875 = 127,5 = 128 |
20 * 7,96875 = 159,375 = 159 |
24 * 7,96875 = 191,25 = 191 |
32 * 7,96875 = 255,0 = 255 |
So... That's it for the brightness of the colors, let's come to the hue...
If you measure the chroma-signal ("u" & "v") with a vectorscope (I did so in 1999), you'll recognize, that all of the colors are on a perfect circle around the crossing-point of the "U" and "V" axis and so have exactly the same saturation (at least speaking in terms of video-language). That's why you don't need to note down the color-difference-signals by "U" and "V" coordinates, but you can use one value (degrees). All these angles are perfectly dividable by 22,5° (which is a quarter of 90°). The VIC-II creates all angles just with 4 voltage-levels being send positive and negative on "U" and "V". You can see those voltage-levels clearly in the next Illustration.
(light) blue | 0,0° | 22,5° * 0 |
purple | 45,0° | 22,5° * 2 |
(light) red | 112,5° | 22,5° * 5 |
orange | 135,0° | 22,5° * 6 |
brown | 157,5° | 22,5° * 7 |
The missing three angles are on the opposite side of the color-wheel from above mentioned angles. Yellow is "blue + 180°", (light) green is "purple + 180°" and cyan is "(light) red + 180°". This is also clearly visible in the next Illustration. You can of course also take (light) red, (light) green, (light) blue, orange and brown as the base-colors and say that the missing ones are on opposite sides of them, but for now I have it written down the above mentioned way. This will be maybe changed later (no time to change it right now). Thanks again to John 'Graham' Selck's Test-Program, which helped to find the angles a bit more exact than the vectorscope was able to do.
If you want to calculate "U" and "V" coordinates from these angles in percent, you just use this formula:
U = 100 * cos(angle)In order to calculate the 4 voltage-levels in percent, calculate "V" from Brown, Purple and Red and "U" from Blue:
100 * sin(157,5°) = 38,26834323650897719%Now "Y", "U" and "V" are known and in order to convert to the RGB-color-space, you just have to find out how much saturation is possible without getting "out of gamut"/"invalid" rgb-values. Brown is the peak-color of the VIC-II color-palette. It is the first color to produce a negative blue-value when converting from YUV to RGB with too much saturation.
I found out the desired value with the brute force method by calculating around with different values in order to more and more close up to the needed value which produces Brown's Blue-Channel to be very little above 0 when converting from YUV to RGB. The value I came up with is 34,0081334493.
Please note however, that monitors/tv's also do clipping (out of gamut colors), when saturation, brightness or contrast is set too high. Really every C64-User has set-up his monitor/tv in a different way. Most people I personally know have set up their equipment to show a normalized palette though, because I think that this looks the best to the eye. This is a matter of taste. If you want a more saturated palette or higher brightness/contrast, you'll have to calculate with greater values (before gamma-correction -- more on this later). The palette I'm calculating here is normalized in every aspect (brightness, contrast and saturation) and this is also the way I have set up my original C64 with its 1084-monitor.
What is maybe interesting for you to know is, that John 'Graham' Selck is currently coding a routine for the new CCS64-Beta (it will probably be included in other emulators later) which lets you modify contrast, brightness saturation and gamma in realtime while emulating, based on the color-logic described on this page. This is the most cool way to emulate your equipment, as you'll be able to modify the settings on the fly, as you do with real equipment. Additionally Graham emulates the short-comings of the PAL-TV-system (for example by using only half the resolution of the Y-layer for the U and V-layer -- like in a real PAL-system) which will also come closer to the look of a real C64 connected to a real 1084 monitor. Make sure to watch out for the new CCS64-Beta.
But let's continue with the calculation... ;-)
# | name | angle | y ("late" luma) | u | v |
---|---|---|---|---|---|
0 | black | n/a | 0 * ( 255 : 32 ) | 0 | 0 |
1 | white | n/a | 32 * ( 255 : 32 ) | 0 | 0 |
2 | red | 5 * ( 360° : 16 ) | 10 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
3 | cyan | 5 * ( 360° : 16 ) + 180° | 20 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
4 | purple | 2 * ( 360° : 16 ) | 12 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
5 | green | 2 * ( 360° : 16 ) + 180° | 16 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
6 | blue | 0 * ( 360° : 16 ) | 8 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
7 | yellow | 0 * ( 360° : 16 ) + 180° | 24 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
8 | orange | 6 * ( 360° : 16 ) | 12 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
9 | brown | 7 * ( 360° : 16 ) | 8 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
A | light red | 5 * ( 360° : 16 ) | 16 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
B | dark grey | n/a | 10 * ( 255 : 32 ) | 0 | 0 |
C | grey | n/a | 15 * ( 255 : 32 ) | 0 | 0 |
D | light green | 2 * ( 360° : 16 ) + 180° | 24 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
E | light blue | 0 * ( 360° : 16 ) | 15 * ( 255 : 32 ) | peak * cos(angle) | peak * sin(angle) |
F | light grey | n/a | 20 * ( 255 : 32 ) | 0 | 0 |
...and the result of this calculation is:
# | name | angle | y (late) | u | v |
---|---|---|---|---|---|
0 | black | n/a | 0,0 | 0 | 0 |
1 | white | n/a | 255,0 | 0 | 0 |
2 | red | 112,5° | 79,6875 | -13,01434923670814368 | +31,41941843272073796 |
3 | cyan | 292,5° | 159,375 | +13,01434923670814368 | -31,41941843272073796 |
4 | purple | 45,0° | 95,625 | +24,04738177749708281 | +24,04738177749708281 |
5 | green | 225,0° | 127,5 | -24,04738177749708281 | -24,04738177749708281 |
6 | blue | 0,0° | 63,75 | +34,0081334493 | 0 |
7 | yellow | 180,0° | 191,25 | -34,0081334493 | 0 |
8 | orange | 135,0° | 95,625 | -24,04738177749708281 | +24,04738177749708281 |
9 | brown | 157,5° | 63,75 | -31,41941843272073796 | +13,01434923670814368 |
A | light red | 112,5° | 127,5 | -13,01434923670814368 | +31,41941843272073796 |
B | dark grey | n/a | 79,6875 | 0 | 0 |
C | grey | n/a | 119,53125 | 0 | 0 |
D | light green | 225,0° | 191,25 | -24,04738177749708281 | -24,04738177749708281 |
E | light blue | 0,0° | 119,53125 | +34,0081334493 | 0 |
F | light grey | n/a | 159,375 | 0 | 0 |
Now we need to convert YUV to RGB. Here's the formula:
R = Y + 1,140 * V...and here's the result:
# | name | r | g | b |
---|---|---|---|---|
0 | black | 0,0 ( 0) | 0,0 ( 0) | 0,0 ( 0) |
1 | white | 255,0 (255) | 255,0 (255) | 255,0 (255) |
2 | red | 115,5056370133016413 (116) | 66,58650018832567614 ( 67) | 53,28138539871917648 ( 53) |
3 | cyan | 123,5568629866983587 (124) | 172,4759998116743239 (172) | 185,7811146012808235 (186) |
4 | purple | 123,0390152263466744 (123) | 72,13070800338535009 ( 72) | 144,417137626541581 (144) |
5 | green | 100,0859847736533256 (100) | 150,9942919966146499 (151) | 78,70786237345841898 ( 79) |
6 | blue | 63,75 ( 64) | 50,2827791540772 ( 50) | 132,7525027686297 (133) |
7 | yellow | 191,25 (191) | 204,7172208459228 (205) | 122,2474972313703 (122) |
8 | orange | 123,0390152263466744 (123) | 91,17623437116303968 ( 91) | 46,83286237345841898 ( 47) |
9 | brown | 78,5863581298472838 ( 79) | 68,63075279282998076 ( 69) | 0,00000000000962268 ( 0) |
A | light red | 163,3181370133016413 (163) | 114,3990001883256761 (114) | 101,0938853987191765 (101) |
B | dark grey | 79,6875 ( 80) | 79,6875 ( 80) | 79,6875 ( 80) |
C | grey | 119,53125 (120) | 119,53125 (120) | 119,53125 (120) |
D | light green | 163,8359847736533256 (164) | 214,7442919966146499 (215) | 142,457862373458419 (142) |
E | light blue | 119,53125 (120) | 106,0640291540772 (106) | 188,5337527686297 (189) |
F | light grey | 159,375 (159) | 159,375 (159) | 159,375 (159) |
Now you need to gamma-correct the rgb-colors. Please note, that the gamma-correction is always the last thing you do to the palette. If you want to change brightness, contrast, saturation, mix-colors for interlace-emu, rotate hue or anything else, you have to do this before the gamma-correction.
I'm not 100% sure about the used gamma-values in the following calculation, but I'm working on it and it's probably right. This page will be updated in the future with the right values in case the one I'm using now are wrong. If you feel like a gamma-expert, please get in touch with me at pepto@pepto.de, while I keep on investigating the matter. ;-)
In order to correct the PAL-Gamma for VGA-Output you need to calculate each r, g and b value with an exponent of "2,5 : 2,2" (which is 1,136) and stretch the results back proportionaly to 8 bit valid values (between 0 and 255). There's a lot of false and irritating information about gamma around, but I'll fix the right value in the future. Maybe 1,136 is even right and because it should theoretically and it does look correct, I'll use it for the moment (Thanks to John 'Graham' Selck for a little help with the gamma-values by just deciding which ones to use, while I was still thinking about which one to choose from the ones talked about in the gamma-faq's.). Theoretically Gamma is 2,5, but most people use 2,2 and PAL is officially noted with a gamma of 2,8. PeeCee's use a gamma of 2,2. Macintosh-computers have a gamma of 1,8 by default, but you're able to change it system-wide with the control-pannel "adobe-gamma" or "monitors" to the more common 2,2. Programs like Adobe Photoshop are also able to emulate the gamma for you in the "color-preferences". More Information about this will be added here later. I also don't know much about the gamma of Amiga-computers (ECS and AGA), even if I would love to as they are my computers of choice. Please get in touch with me if you know more about this.
Here are the results, after the gamma-correction:
# | name | r | g | b |
---|---|---|---|---|
0 | black | 0,0 ( 0) | 0,0 ( 0) | 0,0 ( 0) |
1 | white | 254,999999878 (255) | 254,999999878 (255) | 254,999999878 (255) |
2 | red | 103,681836072 (104) | 55,445357742 ( 55) | 43,038096345 ( 43) |
3 | cyan | 111,932673473 (112) | 163,520631667 (164) | 177,928819803 (178) |
4 | purple | 111,399725075 (111) | 60,720543693 ( 61) | 133,643433983 (134) |
5 | green | 88,102223525 ( 88) | 140,581101312 (141) | 67,050415368 ( 67) |
6 | blue | 52,769271594 ( 53) | 40,296416104 ( 40) | 121,446211753 (121) |
7 | yellow | 183,892638117 (184) | 198,676829993 (199) | 110,585717385 (111) |
8 | orange | 111,399725075 (111) | 79,245328562 ( 79) | 37,169652483 ( 37) |
9 | brown | 66,932804788 ( 67) | 57,383702891 ( 57) | 0,0 ( 0) |
A | light red | 153,690586380 (154) | 102,553762644 (103) | 89,111118307 ( 89) |
B | dark grey | 67,999561813 ( 68) | 67,999561813 ( 68) | 67,999561813 ( 68) |
C | grey | 107,797780127 (108) | 107,797780127 (108) | 107,797780127 (108) |
D | light green | 154,244479632 (154) | 209,771445903 (210) | 131,584994128 (132) |
E | light blue | 107,797780127 (108) | 94,106015515 ( 94) | 180,927622164 (181) |
F | light grey | 149,480882981 (149) | 149,480882981 (149) | 149,480882981 (149) |
Finished... Now here's a comparison of how some c64-pics look with the palette which is included in ccs64 v2.0 beta (this is just an example) and with the palette we just calculated...
ccs64 v2.0b | my palette |
And here's the palette in hex-format for easier usage in certain emulators:
00 00 00P.S.: Here's an interesting eMail which Bob Yannes (co-developer of the VIC-II) sent to me. Please note that I can't disclose Bob's eMail address to you, as he's very concerned about his privacy and the only way to get in touch with him myself, was through a third person, who forwarded our mails to eachother. In other words, I don't have his eMail-address myself, so don't ask. Additionally please note that Bob talks about the NTSC color wheel. NTSC uses YIQ instead of PAL's YUV, but in order to convert from YIQ to YUV you just have to rotate everything by 33° and exchange the color-difference axis. This is what they probably did in hardware in order to make the VIC-II work with PAL and so NTSC and PAL-VIC's probably have the same colors.
-///----------------------------- --- -- -