|
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. 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
|
just use a pointer Reading your code, it seems a little overcomplicated. Which is fine if you understand it. 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! 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
|
pointers are just variables with values as addresses in memory. int p; 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 "c = (c << 4) + h" is the same as "c = (c * 16) + h" |
|