Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » makecol() with hexadecimal

This thread is locked; no one can reply to it. rss feed Print
makecol() with hexadecimal
Lox Chatterbox
Member #20,176
May 2021

Hey, I'm using Allegro 4.4.2 and C for a uni project, and learning the functions. I'm aware we can define a color as an int with the function makecol(r,g,b), however I could not find a version of it compatible with hexadecimal numbers, so I decided to make one.

I made two functions to serve this purpose, one is hexcol(hex), which is compatible with a hex color in a string (works with no capital letters, capital letters, numbers, with or without a # at the front).

I've had an issue sending a string into a function however, and need to copy it into a new string with a defined size. I'm wondering if there's a way to copy an array into another one, aside from string.h's strcpy(destination,source).

Here's the code, i did it in a heartbeat so I'd appreciate if anyone has any feedback on it aside from the array to array copy.

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#include <allegro.h> 6 7void hex_to_dec(char color[],int *red,int *green, int *blue) 8{ 9 10 char hex[8]; 11 12 strcpy(hex,color); //this array copy uses string.h 13 14 int hash=0; //# 15 16 int r[2]; 17 int g[2]; 18 int b[2]; 19 20 if(hex[0]=='#') hash++; //if #, add 1 to i 21 22 for (int i=0+hash; i<6+hash; i++) 23 { 24 if(hex[i]>=65 && hex[i]<=70) hex[i]-=55; //caps 25 if(hex[i]>=97&&hex[i]<=102) hex[i]-=87; //no caps 26 if(hex[i]>=48&&hex[i]<=57) hex[i]-=48; //numbers 27 28 if(i<2) r[i-hash]=hex[i]; //r 29 if(i>=2 && i<4) g[i-2-hash]=hex[i]; //g 30 if(i>=4) b[i-4-hash]=hex[i]; //b 31 } 32 33 *red=r[0]*16+r[1]; ///hex to decimal math 34 *green=g[0]*16 +g[1]; 35 *blue=b[0]*16+b[1]; 36} 37 38int hexcol(char color[]) 39{ 40 int r,g,b; 41 42 int couleur; 43 44 hex_to_dec(color,&r,&g,&b); //call hex to decimal converter 45 46 couleur=makecol(r,g,b); //stores rgb in couleur 47 48 return couleur; //returns rgb 49} 50 51int main() 52{ 53 54 allegro_init(); //init allegro 55 56 install_keyboard(); 57 58 //graphic init 59 set_color_depth(desktop_color_depth()); 60 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,1200,700,0,0)!=0) 61 { 62 allegro_message("probleme mode graphique : %s", allegro_error); 63 allegro_exit(); 64 exit(EXIT_FAILURE); 65 } 66 ///===========================================================/// 67 68 textout(screen,font,"test",0,0,hexcol("#ff00ff")); 69 70 71 while(!key[KEY_ESC]) 72 { 73 74 } 75 76 allegro_exit(); // exit 77 78 return 0; 79} 80END_OF_MAIN()

DanielH
Member #934
January 2001
avatar

just use a pointer
Why do you need to copy it?

Reading your code, it seems a little overcomplicated. Which is fine if you understand it.

#SelectExpand
1// no error checking, assumes string is correct at "rrggbb" or "#rrggbb" 2int color(const char *string, int *r, int *g, int *b) 3{ 4 int c = 0; 5 if (*string == '#') string++; 6 7 while (*string) 8 { 9 int h = 0; 10 if (*string >= 'A' && *string <= 'F') h = *string - 'A' + 10; 11 if (*string >= 'a' && *string <= 'f') h = *string - 'a' + 10; 12 if (*string >= '0' && *string <= '9') h = *string - '0'; 13 14 c = (c << 4) + h; 15 string++; 16 } 17 18 *r = (c & 0xff0000) >> 4; 19 *g = (c & 0x00ff00) >> 2; 20 *b = (c & 0x0000ff); 21 22 return c; 23}

Lox Chatterbox
Member #20,176
May 2021

Wow, that's much more simple than i thought.

I started learning C in October, still don't completely understand pointers and I didn't learn left/right shift operations yet. That pointer method is really useful though, thank you!

Edit: I found a way to implement the pointer into the code that I understand, avoiding string.h. thank you!

#SelectExpand
1void hex_to_dec( char *string, int *red, int *green, int *blue) 2{ 3 4 int r[2],g[2],b[2]; 5 6 int hex[6]; 7 8 9 if (*string == '#') string++; 10 11 for (int i=0; i<6; i++) 12 { 13 if(*string>='A' && *string<='F') hex[i]=(int)*string -'A'+10; 14 if(*string>='a' && *string<='f') hex[i]=(int)*string -'a'+10; 15 if(*string>='0' && *string<='9') hex[i]=(int)*string -'0'; 16 17 if(i<2) r[i]=hex[i]; //r 18 if(i>=2 && i<4) g[i-2]=hex[i]; //g 19 if(i>=4) b[i-4]=hex[i]; //b 20 21 string++; 22 } 23 24 25 *red=r[0]*16+r[1]; ///hex to decimal math 26 *green=g[0]*16 +g[1]; 27 *blue=b[0]*16+b[1]; 28 29}

DanielH
Member #934
January 2001
avatar

pointers are just variables with values as addresses in memory.

int p;
int a[10];
int *v;

all 3 of these are pointers. The only difference is 2 are created on the stack. The other is created on the heap.

left/right shifts are just ways to multiply and divide factors of 2. It's just slightly faster. For something small like this it's trivial. Most compilers will convert it in the background anyway.

a << x is multiplying a by 2^x
a >> x is dividing a by 2^x

"c = (c << 4) + h" is the same as "c = (c * 16) + h"

Go to: