JSFiddle - React, Tailwind, and code Playground
HTML
<pre>
<script>
// See https://github.com/openMSX/openMSX/issues/1024
//
// Pr and Pb saturations are each in the range [0, 100].
// Output is a palette array with elements in CSS form
// minus the leading '#'.
function tmsPalette(saturationPr, saturationPb) {
const TMS99XXA_ANALOG_OUTPUT = eval(`
{{ 0.00, 0.47, 0.47 },
{ 0.00, 0.47, 0.47 },
{ 0.53, 0.07, 0.20 },
{ 0.67, 0.17, 0.27 },
{ 0.40, 0.40, 1.00 },
{ 0.53, 0.43, 0.93 },
{ 0.47, 0.83, 0.30 },
{ 0.73, 0.00, 0.70 },
{ 0.53, 0.93, 0.27 },
{ 0.67, 0.93, 0.27 },
{ 0.73, 0.57, 0.07 },
{ 0.80, 0.57, 0.17 },
{ 0.47, 0.13, 0.23 },
{ 0.53, 0.73, 0.67 },
{ 0.80, 0.47, 0.47 },
{ 1.00, 0.47, 0.47}}
`.split('{').join('[').split('}').join(']'));
var tmsPalette=[];
for (var color = 0; color < 16; color++) {
// convert from analog output to YPbPr
var Y = TMS99XXA_ANALOG_OUTPUT[color][0];
var Pr = TMS99XXA_ANALOG_OUTPUT[color][1] - 0.5;
var Pb = TMS99XXA_ANALOG_OUTPUT[color][2] - 0.5;
// apply the saturation
Pr *= (saturationPr/100.0);
Pb *= (saturationPb/100.0);
// convert to RGB as follows:
/*
|R| | 1 0 1.402 | |Y |
|G| = | 1 -0.344 -0.714 | x |Pb|
|B| | 1 1.722 0 | |Pr|
*/
var R = Y + 0.000 * Pb + 1.402 * Pr;
var G = Y - 0.344 * Pb - 0.714 * Pr;
var B = Y + 1.722 * Pb + 0.000 * Pr;
// blow up with factor of 255
R *= 255;
G *= 255;
B *= 255;
// the final result is that these values
// are clipped in the [0:255] range.
tmsPalette[color] = [R,G,B].map(i=>(Math.max(0, Math.min(255, Math.round(i))))|0).map(i=>(0x100+i).toString(16).substr(1)).join('');
}
return tmsPalette;
};
q='000 000 0a5 5f5 00f 55f a55 5ff f55 faa ff5 fa5 0a0 f5a aaa...
CSS
pre {font-size:xx-small}
hr {border:none;line-height:1px;height:1px;padding:0;margin:0;display:block}