Accurate Mapping of MD 9-bit to 24-bit Colour-Codes

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Accurate Mapping of MD 9-bit to 24-bit Colour-Codes

Post by MintyTheCat » Mon Mar 04, 2013 6:46 pm

Hello all,

at present I am trying to convert Megadrive-Palettes to 24-bit Bitmap-Palettes. I am having to do it this terrible way:

1. Load ROM in Gens-KMod, get to part of Game I am interested in.
2. Pause the Emulator, view the VDP Debug.
3. Save the CRAM-Dump to File.
4. Take a Screen-Grab of my Desktop to get the Colours in the Palettes.
5. Load the Screen-Grab in PSP6 then sample the Colours in the four Palettes.
6. Take the CRAM-Dump File then convert to C-Array and then include in my MD-Program.
7. Transform the CRAM-Dump to C-Array Dump Colour-Codes in the Palettes from MD 9-bit 'BGR' Format to standard 9-bit RGB Format.
8. I have a table of (at present) 512 Colour-Codes that act as Equivalents for MD 9-bit in standard RGB to 24-bit Bitmap. I update the Table Colour by Colour but it's a bit long-winded.

Is there a way to accurately calculate the equivalent MD 9-bit BGR/RGB Value's 24-bit Bitmap Colour-Code?

My intention is to have a full table to support all 512 Megadrive Colours in 'normal-Mode' and to then find all the Colour-Codes for a Table to store the entire range of 1536 (512 * 3) for 'Shadow/Hilight Mode'. If there is a simple method to calculate the 24-bit Bitmap Colour-Code then there would be no need to use a Table.

Does anyone have any Ideas at all?

Code: Select all


//******************************************************************
//  [Data Types]
//******************************************************************

//Basic-Types:

typedef unsigned char t_ubyte;
typedef unsigned int	t_uword;
typedef unsigned long t_ulong;

typedef char					t_byte;
typedef int						t_word;
typedef long					t_long;

typedef char					t_char;

typedef	t_uword				t_id;

.....

//24bit Colour-Bitmap Colour Union:
union t_bitmap_24bit_colour_u
{
	t_ulong													colourStd;
	struct t_bitmap_24bit_colour_st	colourRGB;
	t_ubyte													colourRaw[BM_24BITCOLOUR_RAWCOLOUR_LEN];
};
....

struct	t_bitmap_md_9bit_rgb_colour_st
{
	t_ubyte		red;
	t_ubyte		green;
	t_ubyte		blue;
};
....

/*
	The Megadrive's Colour-Code are represented using standard RGB:

	For Example:

	the raw Colour-Code for the MD =	0x0222, this would be represented in standard-RGB as:

	R	=	0x001
	G	=	0x001
	B	=	0x001

	or using the full unsigned Word = 0x0049.

	This would be mapped to the 24-bit Bitmap Colour-Code = 0x212021, padded for 4 Bytes = 0x00212021.
*/
union t_bitmap_md_colour_st
{
	t_uword																	raw;
	struct	t_bitmap_md_9bit_rgb_colour_st	part;
};


......
struct	t_bitmap_md_bmp_colour_equivalent_st
{
	union t_bitmap_md_colour_st						mdColour;
	union t_bitmap_24bit_colour_u						bmpColour;
};
.....


//******************************************************************
//  [Globals]
//******************************************************************

...

//******************************************************
//	[Megadrive to 24-bit Bitmap Colour-Code Equivalency Table]
//******************************************************
/*
 
	Status:	Table remains incomplete and has not been tested with an actual MD VRAM-Dump to 24-bit Bitmap-
	Conversion.
	Note:		Each Pair Entry has the Format: {	"MD-Colour-Code",	"24-bit-BMP Colour-Code"	}.
	The Md-Colour-Code in the Table doesn't use the standard MD 9-bit BGR-Format but instead uses standard RGB-
	Codes in the RGB-Format.  Conversion Functions/Macros are used to operate on the conversions between the-
	two Formats.

	For Example:

	the Raw MD Colour-Code for 0x0AA8 is represented as the Standard-RGB of 0x012D which maps to the 24-bit-
	Bitmap Colour-Code of 0x0084A2A5.
*/


static const struct	t_bitmap_md_bmp_colour_equivalent_st	g_mdColEquivTab[MD_COLOUREQUIVALENT_TAB_SIZE]	=
{
	{	{0x0000,	0x00000000}	},	{	{0x0001,	0x00000021}	},	{	{0x0002,	0x00000000}	},	{	{0x0003,	0x00000063}	},
	{	{0x0004,	0x00000000}	},	{	{0x0005,	0x00000000}	},	{	{0x0006,	0x00000000}	},	{	{0x0007,	0x000000E7}	},
..... the rest of the Colour-Code Equivalents .....
};
Any Ideas and useful Comments would be appreciated :)

Cheers.

Chilly Willy
Very interested
Posts: 2799
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Mon Mar 04, 2013 9:19 pm

The quickest way that looks decent is:

BGR => BBGGRR
shadow => (color >> 1)
hilite => (color >> 1) | 0x80

It's not quite accurate, but is what most emulators have used since forever.

TmEE co.(TM)
Very interested
Posts: 2378
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Mon Mar 04, 2013 9:20 pm

I personally use these to get good enough steps :
255 / 7 or 255 / 15

Normal : 0, 36, 72, 108, 144, 180, 216, 252/255
Shadow : 0, 18, 36, 54, 72, 90, 108, 126
Highlight : 126, 144, 162, 180, 198, 216, 234, 252/255

Notice how Highlight starts where Shadow ends.

Actual MD output has some non-linearities, but this scale gets close enough...
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post by sega16 » Mon Mar 04, 2013 9:49 pm

try this

Code: Select all

uint16_t rgb_to_genesis(uint8_t r,uint8_t g,uint8_t b)
{
	r=(r+18)/36;
	g=(g+18)/36;
	b=(b+18)/36;
	return (r<<1)|(g<<5)|(b<<9);
}
Edit I accidently posted RGB24 to genesis you want it the other way try this. Warning has not been tested

Code: Select all

uint32_t genToRgb(uint16_t pal)
{
 uint8_t r,g,b, * palP;
 b=(*palP++&14)*18
 g=((*palP&240)>>5)*36;//shifted more so more multiply
 r=(*palP&14)*18;
 return (b<<16)|(g<<8)|r;
}

HardWareMan
Very interested
Posts: 727
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Tue Mar 05, 2013 3:12 am

Here we go again. I surprised, how short your memory is. 3 years ago we already discover this topic. I'll remind you some pictures from that topic.
OK, here we go. My picture (connected thru RGB):
Image
Upper ladder:
Image
And lower ladder:
Image
This records taken directly from VDP, 1st channel (yellow) from RED and 2nd channel (cyan) from GREEN. I use "open" DC input, so all measurements are absolute. So, use this full records and see offset in Ultrascope. Is this enough for you?
On TV all gradients is good noticeable. Just matrix of the camera is overexposure and the black steps is disappear.
And Eke already done all dirty job for you:
i got correct results:

Image
HardWareMan wrote:You have Ultrascope. When you open waveform, you can turn on cursors. They will show you voltage. Then, you must make measurements and get delta from black level. If we assume black level as 0% and white level as 100%, you can calculate percentage of every color level and lay it on byte of computer's truecolor depth. Understand?
I measured this (in V):

Code: Select all

 Shadow   Highli    Normal 
-------- -------- ---------   
(0) 0.0             0.0 (0)
(1) 0.5            
(2) 0.9             0.9 (1)
(3) 1.3 
(4) 1.6             1.6 (2)
(5) 1.9 
(6) 2.2             2.2 (3)
(7) 2.4   (0) 2.4
          (1) 2.7   2.7 (4)
          (2) 2.9
          (3) 3.2   3.2 (5)
          (4) 3.5
          (5) 3.8   3.8 (6)
          (6) 4.2
          (7) 4.7   4.7 (7)
It seems quite symetrical steps to me, considering signal noise..

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Mar 05, 2013 11:03 pm

I'm interested in applying this information, but it seems like we're missing the critical information of how these voltage levels actually translate through to intensity. We know the VDP outputs 4.7v for maximum brightness, but how do we know what voltage level actually represents the true maximum brightness level as far as the next component is concerned?

After these lines leave the VDP, they get run through some resistors and a capacitor, then feed into the CXA-1145. We have the datasheet for the CXA-1145 ( http://www.datasheetarchive.com/CXA1145M-datasheet.html look at the 15 page english one). What I can't figure out, after looking at the Mega Drive schematics and reading this datasheet, is:
1. What will the voltage levels be for the R/G/B lines after they run through the input circuitry for the CXA-1145?
2. What input voltage level represents "maximum intensity" for the CXA-1145?

It seems if we had these two pieces of information, we should be able to determine how these output voltage levels actually relate to apparent brightness on the Mega Drive, but right now, I don't actually know what to do with them.

TmEE co.(TM)
Very interested
Posts: 2378
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Tue Mar 05, 2013 11:47 pm

The resistors form a divider to get the level to 0.7V range, rest is buffering by the chip.

This stuff is as good as volume adjustment... when it is too quiet or too loud you turn it up or down but relations in the sound still remain same. Same deal is with the output, when it is too dark you turn up brightness or when it is too bright you turn it down, the relations remain same none the less.

Relations are all that matter and they are solid in this case.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Post by MintyTheCat » Wed Mar 06, 2013 1:50 am

Cheers for the Replies, Guys.

Seems I've released your Collective Genies out of their respective 'Bottles'.

I was looking for Colour-Code Mapping but I like that we ended up fairly quickly at the Hardware :D

I hadn't read the Thread that Hardwareman referenced - cheers.

I need to do some further work but if I can forego having to manually complete that huge Table then it will save me one Hell of a lot of Time - cheers, all :)

Chilly Willy
Very interested
Posts: 2799
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Mar 06, 2013 1:54 am

What huge table? If you break it up into separate R, G, and B lookups, the table is 3 * 8 = 24 entries as shown by hardwareman's repost of eke's table.

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Post by MintyTheCat » Wed Mar 06, 2013 1:56 am

Chilly Willy wrote:What huge table? If you break it up into separate R, G, and B lookups, the table is 3 * 8 = 24 entries as shown by hardwareman's repost of eke's table.
My 'huge' Table: g_mdColEquivTab[MD_COLOUREQUIVALENT_TAB_SIZE], 'MD_COLOUREQUIVALENT_TAB_SIZE' was defined as 512 Entries. I'll take a look at his Table, thanks.

Chilly Willy
Very interested
Posts: 2799
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Mar 06, 2013 6:38 am

This table

Code: Select all

 Shadow   Highli    Normal
-------- -------- ---------   
(0) 0.0             0.0 (0)
(1) 0.5           
(2) 0.9             0.9 (1)
(3) 1.3
(4) 1.6             1.6 (2)
(5) 1.9
(6) 2.2             2.2 (3)
(7) 2.4   (0) 2.4
          (1) 2.7   2.7 (4)
          (2) 2.9
          (3) 3.2   3.2 (5)
          (4) 3.5
          (5) 3.8   3.8 (6)
          (6) 4.2
          (7) 4.7   4.7 (7)
There's only 8 levels per color for the MD palette entries. So you only need 8 entries for normal, shadow, and highlight, making 24 entries. You use the same tables for R, G, and B, just separately, then combine them together into a 24-bit color. You just need to convert the values in the above table from 0 to 4.7 into 0 to 255.

HardWareMan
Very interested
Posts: 727
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Wed Mar 06, 2013 7:02 am

Chilly Willy wrote:You just need to convert the values in the above table from 0 to 4.7 into 0 to 255.
I will add only that a scale can be taken 4.7v as maximum (ie, 4.7v to be 100% and equal to 255), or take the 5V as maximum (4.7 V is then a 4.7/5*100=94% and is to be 255*0,94 ~ 240).

TmEE co.(TM)
Very interested
Posts: 2378
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Wed Mar 06, 2013 10:59 am

One wants to take 4.7V as maximum as white is white afterall, not grey.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Eke
Very interested
Posts: 856
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Thu Apr 18, 2013 12:28 am

I recently spotted in the CXA1145 (RGB encoder) datasheet that RGB input lines "full level" was defined as 1Vpp. I think that the chip also does not only buffer RGB inputs but scale them down to 700mv RGB standard range.

Now, considering the VDP max output is 4.7 V and that, according to MD1 and MD2 schematics we have, there are voltage dividers with R1=4,7K and R2=1.2K, this would give a max value of 0.95V for RGB encoder input, while 5V would give approx. 1V, i.e "pure white".

This would also match with the fact that the VDP only outputs 15 different levels while a 4-bit DAC would have a sixteen one representing max level (5V input, being surely used as voltage reference by RGB DAC, would actually be that "full level"), which seems to indicate the VDP is not designed to output "pure white" either.

That's said, my PAL mega drive (french model) does not seem to have any RGB encoder but instead use a SCART cable with its own included attenuation circuit so maybe the output level (from TV input) are scaled differently to produce pure white here (though it still doesn't look like really that bright to me).

TmEE co.(TM)
Very interested
Posts: 2378
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Thu Apr 18, 2013 1:39 am

One french RGB MD I worked with had a CXA1145 in it, and basically only to buffer the RGB lines. I had to modify it a bit to make it compatible with standard 32X mixing cable.

Analog parts output maximum (supply voltage) very rarely. Those that do are called "rail to rail capable", such parts are a minority. When you go measure something like SNES or SMS or Saturn you'll also find that there's no 5V on any of the analog outputs, but slightly less.

One thing about the resistor values is that these are the values of "cheap" resistors in a certain value progression scale. They could have very well used 4.5K or something like 1.1K etc but such parts belong to the more expensive parts scale. I don't remember how these scales are called.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Post Reply