Previous Thread
Next Thread
Print Thread
Page 1 of 2 1 2
#86896 03/16/13 12:54 PM
Joined: Oct 2005
Posts: 52
N
Member
OP Offline
Member
N
Joined: Oct 2005
Posts: 52
I noticed that the PCE driver never displays white as RGB 255/255/255, but as 224/224/224. Looking at the source code (src\emu\video\huc6260.c), line 33), the following passage seems to be the culprit:

int r = ( ( i >> 3 ) & 7 ) << 5;
int g = ( ( i >> 6 ) & 7 ) << 5;
int b = ( ( i ) & 7 ) << 5;

The proper way to convert from an 3-bit to an 8-bit value is not to just shift by 5 bits, but to multiply by 255 and then divide by 7. Then maximum white from 3 bits (7) will not improperly become 224 (7*2^5), but 255 (7*255/7). "Proper" assuming you want white to be white and not light gray. The same applies to the SMS and possibly other drivers.

Last edited by NewRisingSun; 03/16/13 01:01 PM.
Joined: Jul 2007
Posts: 4,625
A
Very Senior Member
Offline
Very Senior Member
A
Joined: Jul 2007
Posts: 4,625
A nice find, NewRisingSun. smile

Joined: Feb 2004
Posts: 2,557
Likes: 255
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,557
Likes: 255
Multiply/divide is inefficient - faster to do:
Code
int eightbit = (threebit << 5) | (threebit << 2) | (threebit >> 1)
This will get the desired effect.

Joined: May 2004
Posts: 993
Likes: 93
D
Senior Member
Offline
Senior Member
D
Joined: May 2004
Posts: 993
Likes: 93

Joined: Feb 2004
Posts: 2,557
Likes: 255
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,557
Likes: 255
Cool, a suitable helper function. If I only had SVN commit access wink
And Duke, you are twisty!

Joined: Mar 2001
Posts: 17,144
Likes: 177
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 17,144
Likes: 177
Since we don't run on PDP-8s ;-) there's a very good chance the 3 shift + 2 OR version will lose to the multiply+divide. But since it's in PALETTE_INIT() it only runs once on driver startup and doesn't matter anyway.

Joined: Aug 2009
Posts: 1,230
Likes: 114
Very Senior Member
Offline
Very Senior Member
Joined: Aug 2009
Posts: 1,230
Likes: 114
I'm on it, btw

Joined: Oct 2005
Posts: 52
N
Member
OP Offline
Member
N
Joined: Oct 2005
Posts: 52
Other drivers where the same point applies:
src\emu\video\315_5124.c lines 100, 130
src\emu\video\pc_cga.c, line 302
src\emu\video\pc_vga.c, lines 814, 875
src\mess\drivers\supracan.c, line 1354
src\mess\drivers\wswan.c, line 114

Joined: May 2009
Posts: 2,188
Likes: 285
J
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 2,188
Likes: 285
Originally Posted by R. Belmont
Since we don't run on PDP-8s ;-) there's a very good chance the 3 shift + 2 OR version will lose to the multiply+divide. But since it's in PALETTE_INIT() it only runs once on driver startup and doesn't matter anyway.

I would also argue it's much more likely that the hardware operates in a shift/OR manner. I know for a fact that on the GameCube, the documentation states that it converts 444 to 888 by "duplicating the upper four bits into the lower four bits", and it's far more functionally apparent what it's actually doing if you use shift/OR.

Joined: Feb 2004
Posts: 2,557
Likes: 255
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,557
Likes: 255
Originally Posted by R. Belmont
Since we don't run on PDP-8s ;-) there's a very good chance the 3 shift + 2 OR version will lose to the multiply+divide. But since it's in PALETTE_INIT() it only runs once on driver startup and doesn't matter anyway.
I'm never going to live this down, am I? I bet I'll be the PDP-8 "expert" when people start playing with the MESS driver, too. That will be a fun machine to do artwork for - lots of blinkenlights and switches.

If you want to do it with multiply and you have space for a 9-bit intermediate (as we do because we use int), you can save doing a real divide and let it degenerate to a shift like this (compiler automatically turns divide by power of two into a right-shift these days, and a single shift is definitely faster than a divide). This produces the same effect as the three shift + 2 OR version.
Code
 int eightbit = (threebit * 0x49) / 2;

I'd agree with JD that the hardware more likely behaves this way than by effectively doing x * 255 / 7. It's a lot simpler to do in silicon as it only needs selection logic. It does produces different results for some values - e.g. 6 becomes 218 if you multiply by 255 and divide by 7, but it becomes 219 if you use bit repetition.

Page 1 of 2 1 2

Link Copied to Clipboard
Who's Online Now
3 members (nerd4gw, 2 invisible), 147 guests, and 4 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,282
Posts121,430
Members5,064
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com