Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do this expression mean? (SetConsoleTextAttribute function in C)

Tags:

c++

c

windows

I'm in a the middle of creating a console based small game for our C programming class assignment and I decided to make it more presentable and unique by adding text colors and text backgrounds.

While I was on my quest searching for a solution, I've found this handy function that will do just the way I wanted for my project but the problem is that there is this part I do not understand:

WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);

Where, BackC and ForgC are given integers and the data type WORD is just a typedef for an unsigned short int. Specifically, what I don't understand is the ((BackC & 0x0F) << 4) + (ForgC & 0x0F) part. Can anyone help me with this? I know that I can just use the function but I really want to know how the function works...Thanks!

Here is the full source code (colorExample.c)

#include <windows.h>
#include <stdio.h>
void SetColorAndBackground(int ForgC, int BackC);
int main()
{
    SetColorAndBackground(10,1);   //color value range 0 up-to 256
    printf("what is text background color \n");
    SetColorAndBackground(11,1);
    printf("how about this?");
    getch();
    return 0;
}
void SetColorAndBackground(int ForgC, int BackC)
{
     WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
     return;
}
like image 427
Raven Avatar asked Oct 09 '22 22:10

Raven


1 Answers

ForgC and BackC are two values that can really only expand to take up of 4 bits each (you can tell this because they are being bitwise ANDed with 0x0F, which clears all but the last 4 bits of the first operand).

So if we look at them as 8-bit wide values, they would be of the form

ForgC      0000xxxx
BackC      0000yyyy

Then you bitwise shift ForgC 4 bits to the left, making

ForgC      xxxx0000
BackC      0000yyyy

And then you add them together¹, making

ForgC      xxxx0000
BackC      0000yyyy
Result     xxxxyyyy

So what this does in effect is "combine" both values into one. SetConsoleTextAttribute might then separate them again, or it might use the combined value as-is.


¹ Technically this should be a bitwise OR instead of integer addition. Although in this specific case (where the two operands are guaranteed to not have an 1-bit in the same position) both operations will produce the same result, bitwise OR makes the intent clearer.

like image 52
Jon Avatar answered Oct 13 '22 10:10

Jon