How to retrieve background color in 32 bits?
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
How to retrieve background color in 32 bits?
Hi,
The documentation is quite clear, the hi/lo-Word(color()) command would only return foreground color in 32 bits color mode (in this case loWord only can be useful). This is normal as far as I understand the deal, since a word is 32 bits and splitting it in high and low wouldn't help to retrieve twice full 32 bits data.Edit: Even worse if a WORD in fb is only 16 bits as it seems to be.
Whatever, what is the workaround then? Or is it in the oven some extension of the color() function such that it would deal with QWord, and then hiQWord would be implemented? In one final 'word', what's going on here, and is there anything to do?
I need this in the context of setting automatically and at any time a contrasted foreground color according to the current background one.
Thanks by advance.
The documentation is quite clear, the hi/lo-Word(color()) command would only return foreground color in 32 bits color mode (in this case loWord only can be useful). This is normal as far as I understand the deal, since a word is 32 bits and splitting it in high and low wouldn't help to retrieve twice full 32 bits data.Edit: Even worse if a WORD in fb is only 16 bits as it seems to be.
Whatever, what is the workaround then? Or is it in the oven some extension of the color() function such that it would deal with QWord, and then hiQWord would be implemented? In one final 'word', what's going on here, and is there anything to do?
I need this in the context of setting automatically and at any time a contrasted foreground color according to the current background one.
Thanks by advance.
Last edited by Tourist Trap on Nov 19, 2015 14:24, edited 1 time in total.
Re: How to retrieve background color in 32 bits?
Looking at the 1.04.0 source, in fb_gfx_private.h, the FB_GFXCTX (fb_gfx context) structure stores the foreground and background colors as separate 32-bit unsigned integers:
So the data appears to be there, but the problem is in accessing it.
Code: Select all
typedef struct FB_GFXCTX {
int id;
int work_page;
unsigned char **line;
int max_h;
int target_bpp;
int target_pitch;
void *last_target;
float last_x, last_y;
union {
struct {
int view_x, view_y, view_w, view_h;
};
int view[4];
};
union {
struct {
int old_view_x, old_view_y, old_view_w, old_view_h;
};
int old_view[4];
};
float win_x, win_y, win_w, win_h;
unsigned int fg_color, bg_color;
void (*put_pixel)(struct FB_GFXCTX *ctx, int x, int y, unsigned int color);
unsigned int (*get_pixel)(struct FB_GFXCTX *ctx, int x, int y);
void *(*pixel_set)(void *dest, int color, size_t size);
PUTTER **putter[PUT_MODES];
int flags;
} FB_GFXCTX;
Re: How to retrieve background color in 32 bits?
screencontrol 13 yields the foreground and background colours.
They are passed as uinteger.
You can extract the colour components via a pointer, or use the macros (from the help file):
#define RGBA_R( c ) ( CUInt( c ) Shr 16 And 255 )
#define RGBA_G( c ) ( CUInt( c ) Shr 8 And 255 )
#define RGBA_B( c ) ( CUInt( c ) And 255 )
#define RGBA_A( c ) ( CUInt( c ) Shr 24 )
Example:
Maybe I am missing something here, do you want something else.
What's with hiword/loword ??
They are passed as uinteger.
You can extract the colour components via a pointer, or use the macros (from the help file):
#define RGBA_R( c ) ( CUInt( c ) Shr 16 And 255 )
#define RGBA_G( c ) ( CUInt( c ) Shr 8 And 255 )
#define RGBA_B( c ) ( CUInt( c ) And 255 )
#define RGBA_A( c ) ( CUInt( c ) Shr 24 )
Example:
Code: Select all
dim as uinteger fore,back
screenres 500,300,32
color rgb(255,200,12),rgb(50,90,245)
screencontrol 13,fore,back
var forepointer=cptr(ubyte ptr,@fore),backpointer=cptr(ubyte ptr,@back)
print fore,back
do
screenlock
cls
locate 5,1
print fore,back
print
print
' red green blue
print forepointer[2],forepointer[1],forepointer[0],"foreground"
print
print backpointer[2],backpointer[1],backpointer[0],"background"
screenunlock
sleep 1,1
loop until len(inkey)
What's with hiword/loword ??
Re: How to retrieve background color in 32 bits?
@Tourist Trap,
your description of word is wrong, a word = short = 16bits = 2x Byte ...
@dodicat,
and I'm positive that is, what CUInt means. A 32bit unsigned INT.
UInteger becomes 64bit unsigned INT in 64bit code, which is wrong!
your description of word is wrong, a word = short = 16bits = 2x Byte ...
@dodicat,
Your code is only in 32bit correct, it is far better to use ULong for Colordodicat wrote:They are passed as uinteger. -- NO as ULong (in FB)
Maybe I am missing something here ... What's with hiword/loword ??
and I'm positive that is, what CUInt means. A 32bit unsigned INT.
UInteger becomes 64bit unsigned INT in 64bit code, which is wrong!
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: How to retrieve background color in 32 bits?
Thanks dodicat!dodicat wrote:screencontrol 13 yields the foreground and background colours.
What I wanted to do is simply something like:
Code: Select all
#define _R(c) ( cUint(c) shr 16 and 255 )
#define _G(c) ( cUint(c) shr 08 and 255 )
#define _B(c) ( cUint(c) shr 00 and 255 )
dim as ulong bckgcolor = hiWord(color())
dim as ulong fgndcolor
fgndcolor = rgb( iif(_R(bckgcolor )<128, 255, 0), _
iif(_G(bckgcolor )<128, 255, 0), _
iif(_B(bckgcolor )<128, 255, 0) )
print "Hello in a contrasted way!"
sleep
I'll try what you've posted in few hours. But if screenControl is abble to return colors why color() built-in funct doesn't simply wrap it? What exactly does color() in particular compared to this?
Yes in fb you are right, seems that DWORD is the type holding 32 bits. But in general, what a WORD means exactly varies very much, and most often corresponds to the system integers.MrSwiss wrote:@Tourist Trap,
your description of word is wrong, a word = short = 16bits = 2x Byte ...
Re: How to retrieve background color in 32 bits?
Interesting to find a foreground and background colour guaranteed to be noticeablly different.
I cannot think of anything remotely clever, just a brute force way.
Here 100 bytes at least are between reds,greens,and blues.
(Left mouse click to change colours)
I cannot think of anything remotely clever, just a brute force way.
Here 100 bytes at least are between reds,greens,and blues.
(Left mouse click to change colours)
Code: Select all
Dim As Ulong fore,back
Screenres 500,300,32
Color Rgb(255,200,12),Rgb(50,90,245)
Screencontrol 13,fore,back
Var forepointer=Cptr(Ubyte Ptr,@fore),backpointer=Cptr(Ubyte Ptr,@back)
Dim As Long m,button,flag,counter
Do
Getmouse m,m,,button
If button=1 And flag=0 Then
flag=1
counter=0
Do
counter+=1
'Get new foreground colour from new background colour:
back=Rgb(Rnd*255,Rnd*255,Rnd*255)
fore=Rgb(Rnd*255,Rnd*255,Rnd*255)
Loop Until Abs(forepointer[2]-backpointer[2])>100 And _
Abs(forepointer[1]-backpointer[1])>100 And _
Abs(forepointer[0]-backpointer[0])>100
Color fore,back
End If
Screenlock
Cls
Locate 5,1
Print "foreground",fore
Print
Print "background",back
Print
Print "iterations",counter
Print
Print
' red green blue
Print forepointer[2],forepointer[1],forepointer[0],"foreground"
Print
Print backpointer[2],backpointer[1],backpointer[0],"background"
Circle(250,200),50,,,,,f
Screenunlock
Sleep 1,1
flag=button
Loop Until Len(Inkey)
Re: How to retrieve background color in 32 bits?
@Tourist Trap,
in particular Intel ASM, where there are:
This is not to be confused with all the HLL definitions, which can be very misleading!
As MichaelW already pointed out:
Color(FG, BG) ' where FG = ULong and BG = ULong
I'm NOT talking about any HLL (high level language) here, but ASSEMBLYTourist Trap wrote:Yes in fb you are right, seems that DWORD is the type holding 32 bits. But in general, what a WORD means exactly varies very much, and most often corresponds to the system integers.MrSwiss wrote:@Tourist Trap,
your description of word is wrong, a word = short = 16bits = 2x Byte ...
in particular Intel ASM, where there are:
- Byte = 8bits (Byte/UByte - FB)
Word = 16bits (Short/UShort - FB)
DWord = 32bits (Long/ULong - FB ++ Integer/UInteger, in 32bit FBC only)
QWord = 64bits (LongInt/ULongInt - FB ++ Integer/UInteger, in 64bit FBC only)
This is not to be confused with all the HLL definitions, which can be very misleading!
As MichaelW already pointed out:
Color(FG, BG) ' where FG = ULong and BG = ULong
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: How to retrieve background color in 32 bits?
Ok, I see now.MrSwiss wrote:I'm NOT talking about any HLL (high level language) here, but ASSEMBLY
in particular Intel ASM, where there are:This has, so far, never changed and probably never will.
- Byte = 8bits (Byte/UByte - FB)
Word = 16bits (Short/UShort - FB)
DWord = 32bits (Long/ULong - FB ++ Integer/UInteger, in 32bit FBC only)
QWord = 64bits (LongInt/ULongInt - FB ++ Integer/UInteger, in 64bit FBC only)
But for the color function things are melted a little. Arguments are ulong as you've recalled, but we need lo/hi-word to decypher the return. And finally we still need two 32 bits placeholders to get both foreground and background color in 32 bits mode, which placeholders, color function doesn't seem to provide (at present day at least).
Hey dodicat. I agree perfectly and I have been searching the web for a formula that encloses a given color in rgb boundaries. Unfortunately that seems not to be something that has been done. Rather there are some enumerations like pantone variations for a huge example.dodicat wrote:Interesting to find a foreground and background colour guaranteed to be noticeablly different.
I cannot think of anything remotely clever, just a brute force way.
I've done this below to give an example of something I would find doable to seek by hand such boundaries for a color. In the code below (not the most general for this version) I say that I'm searching all variations around the red color. For instance of course rgb(r,0,0) will always be ok, but we dont leave the red scope immediatly when adding the 2 other components. It is still quite reddish if we set rgb(150, 60, 80).
This question of course can get generalized. Given any color as rgb(rc,gc,bc) what are the boundaries so that rgb(rc+r0,gc-g0,bc+b0) is still the same color (yet a variant)....
Code: Select all
'tool to study the full range of a color
'without overlapping when r, g, b vary
screenRes 600, 450, 32
color , rgb(60,60,90)
dim as uInteger r, g, b
dim as uInteger rCursorBox_xMin, rCursorBox_xMax
dim as uInteger rCursorBox_yMin, rCursorBox_yMax
dim as uInteger rCursorValue
dim as uInteger gCursorBox_xMin, gCursorBox_xMax
dim as uInteger gCursorBox_yMin, gCursorBox_yMax
dim as uInteger gCursorValue
dim as uInteger bCursorBox_xMin, bCursorBox_xMax
dim as uInteger bCursorBox_yMin, bCursorBox_yMax
dim as uInteger bCursorValue
rCursorBox_xMin => 60 - 2
rCursorBox_xMax => 60 + 2
rCursorBox_yMin => 42
rCursorBox_yMax => 46
gCursorBox_xMin => 82
gCursorBox_xMax => 86
gCursorBox_yMin => 60 - 2
gCursorBox_yMax => 60 + 2
bCursorBox_xMin => 222
bCursorBox_xMax => 226
bCursorBox_yMin => 60 - 2
bCursorBox_yMax => 60 + 2
dim as integer gmX, gmY, gmBtn1
dim as boolean rCursorDragStarted
dim as boolean gCursorDragStarted
dim as boolean bCursorDragStarted
dim as integer dsGmX, dsGmY
do
'_____________display______________________________________________
screenLock
cls
'*rBox*************************************************************
line (59,19)-(60 + 256,41), rgb(255,255,255), bf
draw string (60 + 256 + 20, 15), " main color is RED"
draw string (60 + 256 + 20, 28), " <- RED full variation"
draw string (60 + 256 + 20, 40), " <- rCursorValue = "& _
(rCursorValue mod 255)
for r = 0 to 255
line (60 + r,20)-(60 + r,40), rgb(r,0,0)
next r
'*rCursor
line (rCursorBox_xMin - 1, rCursorBox_yMin - 1)- _
(rCursorBox_xMax + 1, rCursorBox_yMax + 1), _
, _
bf
line (rCursorBox_xMin, rCursorBox_yMin)-(rCursorBox_xMax, rCursorBox_yMax), _
rgb(rCursorValue,0,0), _
bf
'*gBox*************************************************************
line (59,59)-(81,60 + 256), rgb(255,255,255), bf
for g = 0 to 255
line (60,60 + g)-(80,60 + g), rgb(0,g,0)
next g
'*gCursor
draw string (88, 58 + gCursorValue), str(gCursorValue mod 255)
line (gCursorBox_xMin - 1, gCursorBox_yMin - 1)- _
(gCursorBox_xMax + 1, gCursorBox_yMax + 1), _
, _
bf
line (gCursorBox_xMin, gCursorBox_yMin)-(gCursorBox_xMax, gCursorBox_yMax), _
rgb(0,gCursorValue,0), _
bf
'*bBox*************************************************************
line (199,59)-(221,60 + 256), rgb(255,255,255), bf
for b = 0 to 255
line (200,60 + b)-(220,60 + b), rgb(0,0,b)
next b
'*bCursor
draw string (228, 58 + bCursorValue), str(bCursorValue mod 255)
line (bCursorBox_xMin - 1, bCursorBox_yMin - 1)- _
(bCursorBox_xMax + 1, bCursorBox_yMax + 1), _
, _
bf
line (bCursorBox_xMin, bCursorBox_yMin)-(bCursorBox_xMax, bCursorBox_yMax), _
rgb(0,0,bCursorValue), _
bf
'**(r,g,b) resultant**********************************************
draw string (340,240), _
str("("& cUbyte(rCursorValue) & _
","& cUbyte(gCursorValue) & _
","& cUbyte(bCursorValue) &")")
line (339,259)-(441,361), ,b
line (340,260)-(440,360), _
rgb(rCursorValue,gCursorValue,bCursorValue), _
bf
screenUnlock
'___mouse interaction______________________________________________
'*rCursor
if rCursorDragStarted then
getMouse dsGmX, gmY, , gmBtn1
if dsGmX<rCursorBox_xMin then dsGmX = rCursorBox_xMin + 2
if dsGmX>rCursorBox_xMax then dsGmX = rCursorBox_xMax - 2
if gmY<rCursorBox_yMin then gmY = rCursorBox_yMin + 2
if gmY>rCursorBox_yMax then gmY = rCursorBox_yMax - 2
else
if not gCursorDragStarted and _
not bCursorDragStarted then
getMouse gmX, gmY, , gmBtn1
end if
end if
if gmX>=rCursorBox_xMin and _
gmX<=rCursorBox_xMax and _
gmY>=rCursorBox_yMin and _
gmY<=rCursorBox_yMax then
if gmBtn1=+1 then
if rCursorDragStarted then
getMouse dsGmX, dsGmY
rCursorBox_xMin += dsGmX - gmX
rCursorBox_xMax += dsGmX - gmX
gmX = rCursorBox_xMin + 2
else
rCursorDragStarted = TRUE
end if
else
rCursorDragStarted = FALSE
end if
end if
rCursorValue => rCursorBox_xMin - 58
'*gCursor
if gCursorDragStarted then
getMouse gmX, dsGmY, , gmBtn1
if gmX<gCursorBox_xMin then gmX = gCursorBox_xMin + 2
if gmX>gCursorBox_xMax then gmX = gCursorBox_xMax - 2
if dsGmY<gCursorBox_yMin then dsGmY = gCursorBox_yMin + 2
if dsGmY>gCursorBox_yMax then dsGmY = gCursorBox_yMax - 2
else
if not rCursorDragStarted and _
not bCursorDragStarted then
getMouse gmX, gmY, , gmBtn1
end if
end if
if gmX>=gCursorBox_xMin and _
gmX<=gCursorBox_xMax and _
gmY>=gCursorBox_yMin and _
gmY<=gCursorBox_yMax then
if gmBtn1=+1 then
if gCursorDragStarted then
getMouse dsGmX, dsGmY
gCursorBox_yMin += dsGmy - gmY
gCursorBox_yMax += dsGmY - gmY
gmY = gCursorBox_yMin + 2
else
gCursorDragStarted = TRUE
end if
else
gCursorDragStarted = FALSE
end if
end if
gCursorValue => gCursorBox_yMin - 58
'*bCursor
if bCursorDragStarted then
getMouse gmX, dsGmY, , gmBtn1
if gmX<bCursorBox_xMin then gmX = bCursorBox_xMin + 2
if gmX>bCursorBox_xMax then gmX = bCursorBox_xMax - 2
if dsGmY<bCursorBox_yMin then dsGmY = bCursorBox_yMin + 2
if dsGmY>bCursorBox_yMax then dsGmY = bCursorBox_yMax - 2
else
getMouse gmX, gmY, , gmBtn1
end if
if gmX>=bCursorBox_xMin and _
gmX<=bCursorBox_xMax and _
gmY>=bCursorBox_yMin and _
gmY<=bCursorBox_yMax then
if gmBtn1=+1 then
if bCursorDragStarted then
getMouse dsGmX, dsGmY
bCursorBox_yMin += dsGmy - gmY
bCursorBox_yMax += dsGmY - gmY
gmY = bCursorBox_yMin + 2
else
bCursorDragStarted = TRUE
end if
else
bCursorDragStarted = FALSE
end if
end if
bCursorValue => bCursorBox_yMin - 58
''''''''
sleep 15
loop until inkey=chr(27)
sleep
'[eof]
An other interesting approach is to get the dark side of a given bright color, and the inverse. And many other nice things allowing to ensure good color display.
Re: How to retrieve background color in 32 bits?
Please forgive my ignorance - just an old quickbasic coder - and not very good...
This code posted from dodicat:
dim as ulong fore,back
screenres 500,300,32
color rgb(255,200,12),rgb(50,90,245)
screencontrol 13,fore,back
var forepointer=cptr(ubyte ptr,@fore),backpointer=cptr(ubyte ptr,@back)
print fore,back
<more code not included>
The compiler does not like using ulong(s) with screencontrol ?? Is there more code or libraries I should use to make this work? Sometimes I will grab code on the forum just to see how things are done.
Thanks,
Darren
I'm using Windows 7 64bit
C:\Program Files\FreeBASIC-1.02.0-win64>fbc -version
FreeBASIC Compiler - Version 1.02.0 (04-05-2015), built for win64 (64bit)
Copyright (C) 2004-2015 The FreeBASIC development team.
standalone
C:\Program Files\FreeBASIC-1.02.0-win64>fbc -lang fb d:\FB_code\fore_back_colors.bas
d:\FB_code\fore_back_colors.bas(5) error 57: Type mismatch, at parameter 2 of SCREENCONTROL() in 'screencontrol 13,fore,
back'
This code posted from dodicat:
dim as ulong fore,back
screenres 500,300,32
color rgb(255,200,12),rgb(50,90,245)
screencontrol 13,fore,back
var forepointer=cptr(ubyte ptr,@fore),backpointer=cptr(ubyte ptr,@back)
print fore,back
<more code not included>
The compiler does not like using ulong(s) with screencontrol ?? Is there more code or libraries I should use to make this work? Sometimes I will grab code on the forum just to see how things are done.
Thanks,
Darren
I'm using Windows 7 64bit
C:\Program Files\FreeBASIC-1.02.0-win64>fbc -version
FreeBASIC Compiler - Version 1.02.0 (04-05-2015), built for win64 (64bit)
Copyright (C) 2004-2015 The FreeBASIC development team.
standalone
C:\Program Files\FreeBASIC-1.02.0-win64>fbc -lang fb d:\FB_code\fore_back_colors.bas
d:\FB_code\fore_back_colors.bas(5) error 57: Type mismatch, at parameter 2 of SCREENCONTROL() in 'screencontrol 13,fore,
back'
Re: How to retrieve background color in 32 bits?
A little example:
Code: Select all
#Ifdef __FB_64BIT__
Dim As ULongInt FG, BG
#Else
Dim As ULong FG, BG
#EndIf ' UInteger behaviour: emulated ... idiotically needed
ScreenRes 400, 200, 32
Color(&hFFFFFFFF, &hFF000000) ' setter is clearly an ULong
ScreenControl 13, FG, BG ' getter has to be UInteger (vomiting!)
' were is the much beloved, discussed etc. consistency of FreeBASIC ???
Draw String (10, 10), "Retrieving COLORS (without FBGFX includes)", &hFF0080FF
Draw String (10, 26), "2015 by MrSwiss", &hFF0040FF
Draw String (10, 60), "Foreground Color: " & Hex(FG, 16) ' 4-8 Bytes ???
Draw String (10, 76), "Background Color: " & Hex(BG, 16)
Draw String (10,120), "Clear to see: half the used MEMORY is wasted!", &hFFFF0000
Draw String (10,136), "Reason: it will never be used anyway!", &hFFFFC000
Draw String (10,180), "Any user action QUIT's prog. ...", &hFFC0C0C0
Sleep : End