Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PALETTE: why does it take "BGR" colour instead of "RGB"?
#1
It just seems a little odd that you can't apply colours that you would get via _RGB32() in the PALETTE statement.

Is there some history to explain the second parameter for colour?
Reply
#2
Now there's a topic I'd like to see in Word For Day!

I went from 16 color to RGB missing a whole decade or so of Palette. Now of course you don't need but the history of Palette would be interesting.
b = b + ...
Reply
#3
(01-17-2023, 04:05 AM)bplus Wrote: Now there's a topic I'd like to see in Word For Day!

I went from 16 color to RGB missing a whole decade or so of Palette. Now of course you don't need but the history of Palette would be interesting.

And my question because looking at a bunch of old QBasic code lately, I'm running into a bunch of samples that use SCREEN 13 and use a lot of PALETTE.

Of course, I looked up PALETTE at the QB64pe Wiki and thought: huh, would you look at that.
Reply
#4
(01-17-2023, 03:59 AM)CharlieJV Wrote: It just seems a little odd that you can't apply colours that you would get via _RGB32() in the PALETTE statement.

Is there some history to explain the second parameter for colour?

Use the https://qb64phoenix.com/qb64wiki/index.php/PALETTECOLOR statement, rather than the old QB45 PALETTE command.  Smile


As for the major difference in the commands, the biggest change is https://en.wikipedia.org/wiki/Endianness.   QB45 stored the values as BGR, while QB64 stores them as ARGB values.  In QB45, they followed the https://qb64phoenix.com/qb64wiki/index.php/DAC format, rather than our modern ARGB format.  

You need to be aware of which command, and which format style you're making use of, so that you can format your colors properly with the two commands.  Smile
Reply
#5
(01-17-2023, 03:59 AM)CharlieJV Wrote: It just seems a little odd that you can't apply colours that you would get via _RGB32() in the PALETTE statement.

Is there some history to explain the second parameter for colour?

Remember that QuickBASIC's "best" was either 640x480 with 16 colors, or the "MCGA" mode of 320x200 with 256 colors. With either it was possible to set red, green and blue attributes, but there was no such thing as alpha channel. In addition, the second parameter to "PALETTE" could only hold an INTEGER, not LONG. That's why "PALETTE" is meant these days for emulations and should not be used in new QB64(PE) programs.

Otherwise it would be easy to remap a register from 0-255 for "_RGB32" to 0-63 for "PALETTE", just divide by four. But have to ignore alpha channel which is a bummer for some applications. The extended display modes for "PUT" graphics statement don't make up.
Reply
#6
(01-17-2023, 09:41 AM)mnrvovrfc Wrote: Otherwise it would be easy to remap a register from 0-255 for "_RGB32" to 0-63 for "PALETTE", just divide by four.

Divide by 4 doesn't quite do it.
0 * 4 = 0
63 * 4 = 252

A change by 4 only gives you a color range from 0 to 252, making color values with 253, 254, 255, impossible to account for properly.

What you'd have to do is multiply by 63/255 (or 255/63 to go in the other direction).

0 * (255 / 63) = 0
63 * (255 /63) = 255
Full range of 0 to 255 RGB colors.

And going in reverse:
0 * (63/255) = 0
255 * (63/255) = 63
Full range of 0 to 63 DAC color values.
Reply
#7
(01-17-2023, 08:39 AM)SMcNeill Wrote:
(01-17-2023, 03:59 AM)CharlieJV Wrote: It just seems a little odd that you can't apply colours that you would get via _RGB32() in the PALETTE statement.

Is there some history to explain the second parameter for colour?

Use the https://qb64phoenix.com/qb64wiki/index.php/PALETTECOLOR statement, rather than the old QB45 PALETTE command.  Smile


As for the major difference in the commands, the biggest change is https://en.wikipedia.org/wiki/Endianness.   QB45 stored the values as BGR, while QB64 stores them as ARGB values.  In QB45, they followed the https://qb64phoenix.com/qb64wiki/index.php/DAC format, rather than our modern ARGB format.  

You need to be aware of which command, and which format style you're making use of, so that you can format your colors properly with the two commands.  Smile

Now what I've seen in wwwBASIC makes sense.  The contributors to that project seemingly had QB45 (and/or earlier) compatibility-ish in mind.  (colours stored as BGR values for screen modes with defined colour maps.

Thanks for the info !
Reply
#8
(01-17-2023, 10:40 AM)SMcNeill Wrote:
(01-17-2023, 09:41 AM)mnrvovrfc Wrote: Otherwise it would be easy to remap a register from 0-255 for "_RGB32" to 0-63 for "PALETTE", just divide by four.

Divide by 4 doesn't quite do it.

I meant from "_RGB32" to "PALETTE", not the way around, but anyway... it has to do with the limitations of the older equipment (VGA and MCGA). The 0-63 for each register was looked up from the Wiki page about "PALETTE", the first syntax.

Quote:Syntax

PALETTE [attribute%, red% + (green% * 256) + (blue% * 65536)]
PALETTE [existingAttribute%, newAttribute%]


Description

red%, green% and blue% values can range from 0 to 63. Many color shades are possible in non-DAC color attributes.

from:
https://qb64phoenix.com/qb64wiki/index.php/PALETTE
Reply
#9
Let me show you really fast how the divide or multiply by 4 method doesn't quite hold true:

Code: (Select All)
TYPE Color_Type
    AS INTEGER red, green, blue
END TYPE

DIM AS Color_Type Unchanged(15), Changed(15), Changed2(15)
SCREEN 12

FOR i = 0 TO 15
    Unchanged(i).red = _RED(i)
    Unchanged(i).green = _GREEN(i)
    Unchanged(i).blue = _BLUE(i)
NEXT


PRINT , "Original"; TAB(35); "Changed * 4"; TAB(60); "Changed * 255 / 63"
FOR i = 0 TO 15
    OUT &H3C7, i 'set color attribute to read
    red$ = HEX$(INP(&H3C9) * 4) 'convert port setting to 32 bit values
    grn$ = HEX$(INP(&H3C9) * 4)
    blu$ = HEX$(INP(&H3C9) * 4)
    IF LEN(red$) = 1 THEN red$ = "0" + red$ '2 hex digits required
    IF LEN(grn$) = 1 THEN grn$ = "0" + grn$ 'for low or zero hex values
    IF LEN(blu$) = 1 THEN blu$ = "0" + blu$
    hex32$ = "&HFF" + red$ + grn$ + blu$
    _PALETTECOLOR i, VAL(hex32$) 'VAL converts hex string to a LONG 32 bit value
    Changed(i).red = _RED(i)
    Changed(i).green = _GREEN(i)
    Changed(i).blue = _BLUE(i)
NEXT

FOR i = 0 TO 15
    OUT &H3C7, i 'set color attribute to read
    red$ = HEX$(INP(&H3C9) * 255 / 63) 'convert port setting to 32 bit values
    grn$ = HEX$(INP(&H3C9) * 255 / 63)
    blu$ = HEX$(INP(&H3C9) * 255 / 63)
    IF LEN(red$) = 1 THEN red$ = "0" + red$ '2 hex digits required
    IF LEN(grn$) = 1 THEN grn$ = "0" + grn$ 'for low or zero hex values
    IF LEN(blu$) = 1 THEN blu$ = "0" + blu$
    hex32$ = "&HFF" + red$ + grn$ + blu$
    _PALETTECOLOR i, VAL(hex32$) 'VAL converts hex string to a LONG 32 bit value
    Changed2(i).red = _RED(i)
    Changed2(i).green = _GREEN(i)
    Changed2(i).blue = _BLUE(i)
NEXT




FOR i = 0 TO 15
    PRINT i, Unchanged(i).red; Unchanged(i).blue; Unchanged(i).green;
    PRINT TAB(35); Changed(i).red; Changed(i).blue; Changed(i).green;
    PRINT TAB(60); Changed2(i).red; Changed2(i).blue; Changed2(i).green
NEXT


The above creates a table for us with the Red, Green, Blue values for our 16 colors (from 0 to 15).  The first table is the original, untouched values.  The middle table is the color shades which we'd get if we just used the DAC * 4 color value.  The right table is the color shades which we'd get if we used DAC * 255 / 63 color values.

I think the values speak for themselves.  DAC * 4 or _RGB / 4 isn't going to get you the full range of color which is available for you, nor is it going to match the existing values which our color tables hold for us for the 16 default colors.  Wink
Reply




Users browsing this thread: 4 Guest(s)