Skip to content

Commit

Permalink
Moved stuff
Browse files Browse the repository at this point in the history
- moved stuff into libqb/graphics.h/.cpp as per suggestion by @a740g
  • Loading branch information
RhoSigma-QB64 committed Feb 2, 2025
1 parent 583c0d6 commit f06961e
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 131 deletions.
14 changes: 0 additions & 14 deletions internal/c/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,6 @@ struct onkey_struct {
qbs *text;
};

// used by color conversion routines
struct hsb_color
{
double h; // [0,360] hue
double s; // [0,1] saturation
double b; // [0,1] brightness
};
struct rgb_color
{
double r; // [0,1] red
double g; // [0,1] green
double b; // [0,1] blue
};

struct byte_element_struct {
uint64 offset;
int32 length;
Expand Down
112 changes: 0 additions & 112 deletions internal/c/libqb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20495,118 +20495,6 @@ int32 func__printmode(int32 i, int32 passed) {
return img[i].print_mode;
}

void hsb2rgb(hsb_color *hsb, rgb_color *rgb) {
double hu, hi, hf, pv, qv, tv;

if (hsb->s == 0.0) {
rgb->r = hsb->b; rgb->g = hsb->b; rgb->b = hsb->b; // no saturation = grayscale
} else {
hu = hsb->h / 60.0; // to sixtant [0,5]
if (hu >= 6.0) hu = hu - 6.0;
hf = modf(hu, &hi); // int/frac parts of hue
pv = hsb->b * (1.0 - hsb->s);
qv = hsb->b * (1.0 - (hsb->s * hf));
tv = hsb->b * (1.0 - (hsb->s * (1.0 - hf)));
switch (lround(hi)) {
case 0: {rgb->r = hsb->b; rgb->g = tv; rgb->b = pv; break;} // 0- 60 = Red->Yellow
case 1: {rgb->r = qv; rgb->g = hsb->b; rgb->b = pv; break;} // 60-120 = Yellow->Green
case 2: {rgb->r = pv; rgb->g = hsb->b; rgb->b = tv; break;} // 120-180 = Green->Cyan
case 3: {rgb->r = pv; rgb->g = qv; rgb->b = hsb->b; break;} // 180-240 = Cyan->Blue
case 4: {rgb->r = tv; rgb->g = pv; rgb->b = hsb->b; break;} // 240-300 = Blue->Magenta
case 5: {rgb->r = hsb->b; rgb->g = pv; rgb->b = qv; break;} // 300-360 = Magenta->Red
}
}
}

void rgb2hsb(rgb_color *rgb, hsb_color *hsb) {
double mini, maxi, diff, hu;
// --- find min/max and difference ---
mini = fmin(fmin(rgb->r, rgb->g), rgb->b);
maxi = fmax(fmax(rgb->r, rgb->g), rgb->b);
diff = maxi - mini;
// --- brightness ---
hsb->b = maxi;
// --- saturation (avoid division by zero) ---
maxi != 0.0 ? hsb->s = diff / maxi : hsb->s = 0.0;
// --- hue in degrees ---
if (hsb->s != 0.0) {
if (rgb->r == maxi) {
hu = ((rgb->g - rgb->b) / diff); // between Yellow & Magenta
if (hu < 0.0) hu = hu + 6.0;
} else if (rgb->g == maxi) {
hu = 2.0 + ((rgb->b - rgb->r) / diff); // between Cyan & Yellow
} else {
hu = 4.0 + ((rgb->r - rgb->g) / diff); // between Magenta & Cyan
}
hsb->h = hu * 60.0; // to degrees
} else {
hsb->h = 0.0; // technically there's no hue w/o saturation, commonly used is 0 (red)
}
}

uint32_t func__hsb32(double hue, double sat, double bri) {
hsb_color hsb; rgb_color rgb;
// --- prepare values for conversion ---
(hue < 0.0) ? hsb.h = 0.0 : ((hue > 360.0) ? hsb.h = 360.0 : hsb.h = hue);
(sat < 0.0) ? hsb.s = 0.0 : ((sat > 100.0) ? hsb.s = 100.0 : hsb.s = sat);
(bri < 0.0) ? hsb.b = 0.0 : ((bri > 100.0) ? hsb.b = 100.0 : hsb.b = bri);
hsb.s /= 100.0; hsb.b /= 100.0; // range [0,1]
// --- convert colorspace ---
hsb2rgb(&hsb, &rgb);
// --- build result ---
return ((lround(rgb.r * 255.0) << 16) + (lround(rgb.g * 255.0) << 8) + lround(rgb.b * 255.0)) | 0xFF000000;
}

uint32_t func__hsba32(double hue, double sat, double bri, double alf) {
hsb_color hsb; rgb_color rgb; double alpha;
// --- prepare values for conversion ---
(hue < 0.0) ? hsb.h = 0.0 : ((hue > 360.0) ? hsb.h = 360.0 : hsb.h = hue);
(sat < 0.0) ? hsb.s = 0.0 : ((sat > 100.0) ? hsb.s = 100.0 : hsb.s = sat);
(bri < 0.0) ? hsb.b = 0.0 : ((bri > 100.0) ? hsb.b = 100.0 : hsb.b = bri);
(alf < 0.0) ? alpha = 0.0 : ((alf > 100.0) ? alpha = 100.0 : alpha = alf);
hsb.s /= 100.0; hsb.b /= 100.0; alpha /= 100.0; // range [0,1]
// --- convert colorspace ---
hsb2rgb(&hsb, &rgb);
// --- build result ---
return (lround(alpha * 255.0) << 24) + (lround(rgb.r * 255.0) << 16) + (lround(rgb.g * 255.0) << 8) + lround(rgb.b * 255.0);
}

double func__hue32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.h;
}

double func__sat32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.s * 100.0;
}

double func__bri32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.b * 100.0;
}

uint32 matchcol(int32 r, int32 g, int32 b) {
static int32 v, v2, n, n2, best, c;
static int32 *p;
Expand Down
20 changes: 20 additions & 0 deletions internal/c/libqb/include/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ struct img_struct {
#define IMG_SCREEN 2 // img is linked to other screen pages
#define IMG_FREEMEM 4 // if set, it means memory must be freed

// used by HSB/RGB color conversion routines
struct hsb_color
{
double h; // [0,360] hue
double s; // [0,1] saturation
double b; // [0,1] brightness
};
struct rgb_color
{
double r; // [0,1] red
double g; // [0,1] green
double b; // [0,1] blue
};

/********** Render State **********/
/*
Apart from 'glTexParameter' based settings (with are texture specific)
Expand Down Expand Up @@ -176,6 +190,12 @@ struct hardware_graphics_command_struct {
#define HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D 5
#define HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER 6

uint32_t func__hsb32(double hue, double sat, double bri);
uint32_t func__hsba32(double hue, double sat, double bri, double alf);
double func__hue32(uint32_t argb);
double func__sat32(uint32_t argb);
double func__bri32(uint32_t argb);

void sub__depthbuffer(int32_t options, int32_t dst, int32_t passed);
void sub__maptriangle(int32_t cull_options, float sx1, float sy1, float sx2, float sy2, float sx3, float sy3, int32_t si, float dx1, float dy1, float dz1,
float dx2, float dy2, float dz2, float dx3, float dy3, float dz3, int32_t di, int32_t smooth_options, int32_t passed);
112 changes: 112 additions & 0 deletions internal/c/libqb/src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,118 @@ extern uint8_t *ablend128;
static int32_t depthbuffer_mode0 = DEPTHBUFFER_MODE__ON;
static int32_t depthbuffer_mode1 = DEPTHBUFFER_MODE__ON;

void hsb2rgb(hsb_color *hsb, rgb_color *rgb) {
double hu, hi, hf, pv, qv, tv;

if (hsb->s == 0.0) {
rgb->r = hsb->b; rgb->g = hsb->b; rgb->b = hsb->b; // no saturation = grayscale
} else {
hu = hsb->h / 60.0; // to sixtant [0,5]
if (hu >= 6.0) hu = hu - 6.0;
hf = modf(hu, &hi); // int/frac parts of hue
pv = hsb->b * (1.0 - hsb->s);
qv = hsb->b * (1.0 - (hsb->s * hf));
tv = hsb->b * (1.0 - (hsb->s * (1.0 - hf)));
switch (lround(hi)) {
case 0: {rgb->r = hsb->b; rgb->g = tv; rgb->b = pv; break;} // 0- 60 = Red->Yellow
case 1: {rgb->r = qv; rgb->g = hsb->b; rgb->b = pv; break;} // 60-120 = Yellow->Green
case 2: {rgb->r = pv; rgb->g = hsb->b; rgb->b = tv; break;} // 120-180 = Green->Cyan
case 3: {rgb->r = pv; rgb->g = qv; rgb->b = hsb->b; break;} // 180-240 = Cyan->Blue
case 4: {rgb->r = tv; rgb->g = pv; rgb->b = hsb->b; break;} // 240-300 = Blue->Magenta
case 5: {rgb->r = hsb->b; rgb->g = pv; rgb->b = qv; break;} // 300-360 = Magenta->Red
}
}
}

void rgb2hsb(rgb_color *rgb, hsb_color *hsb) {
double mini, maxi, diff, hu;
// --- find min/max and difference ---
mini = fmin(fmin(rgb->r, rgb->g), rgb->b);
maxi = fmax(fmax(rgb->r, rgb->g), rgb->b);
diff = maxi - mini;
// --- brightness ---
hsb->b = maxi;
// --- saturation (avoid division by zero) ---
maxi != 0.0 ? hsb->s = diff / maxi : hsb->s = 0.0;
// --- hue in degrees ---
if (hsb->s != 0.0) {
if (rgb->r == maxi) {
hu = ((rgb->g - rgb->b) / diff); // between Yellow & Magenta
if (hu < 0.0) hu = hu + 6.0;
} else if (rgb->g == maxi) {
hu = 2.0 + ((rgb->b - rgb->r) / diff); // between Cyan & Yellow
} else {
hu = 4.0 + ((rgb->r - rgb->g) / diff); // between Magenta & Cyan
}
hsb->h = hu * 60.0; // to degrees
} else {
hsb->h = 0.0; // technically there's no hue w/o saturation, commonly used is 0 (red)
}
}

uint32_t func__hsb32(double hue, double sat, double bri) {
hsb_color hsb; rgb_color rgb;
// --- prepare values for conversion ---
(hue < 0.0) ? hsb.h = 0.0 : ((hue > 360.0) ? hsb.h = 360.0 : hsb.h = hue);
(sat < 0.0) ? hsb.s = 0.0 : ((sat > 100.0) ? hsb.s = 100.0 : hsb.s = sat);
(bri < 0.0) ? hsb.b = 0.0 : ((bri > 100.0) ? hsb.b = 100.0 : hsb.b = bri);
hsb.s /= 100.0; hsb.b /= 100.0; // range [0,1]
// --- convert colorspace ---
hsb2rgb(&hsb, &rgb);
// --- build result ---
return ((lround(rgb.r * 255.0) << 16) + (lround(rgb.g * 255.0) << 8) + lround(rgb.b * 255.0)) | 0xFF000000;
}

uint32_t func__hsba32(double hue, double sat, double bri, double alf) {
hsb_color hsb; rgb_color rgb; double alpha;
// --- prepare values for conversion ---
(hue < 0.0) ? hsb.h = 0.0 : ((hue > 360.0) ? hsb.h = 360.0 : hsb.h = hue);
(sat < 0.0) ? hsb.s = 0.0 : ((sat > 100.0) ? hsb.s = 100.0 : hsb.s = sat);
(bri < 0.0) ? hsb.b = 0.0 : ((bri > 100.0) ? hsb.b = 100.0 : hsb.b = bri);
(alf < 0.0) ? alpha = 0.0 : ((alf > 100.0) ? alpha = 100.0 : alpha = alf);
hsb.s /= 100.0; hsb.b /= 100.0; alpha /= 100.0; // range [0,1]
// --- convert colorspace ---
hsb2rgb(&hsb, &rgb);
// --- build result ---
return (lround(alpha * 255.0) << 24) + (lround(rgb.r * 255.0) << 16) + (lround(rgb.g * 255.0) << 8) + lround(rgb.b * 255.0);
}

double func__hue32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.h;
}

double func__sat32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.s * 100.0;
}

double func__bri32(uint32_t argb) {
rgb_color rgb; hsb_color hsb;
// --- prepare values for conversion ---
rgb.r = ((argb >> 16) & 0xFF) / 255.0;
rgb.g = ((argb >> 8) & 0xFF) / 255.0;
rgb.b = (argb & 0xFF) / 255.0;
// --- convert colorspace ---
rgb2hsb(&rgb, &hsb);
// --- build result ---
return hsb.b * 100.0;
}

void sub__depthbuffer(int32_t options, int32_t dst, int32_t passed) {
// {ON|OFF|LOCK|_CLEAR}

Expand Down
5 changes: 0 additions & 5 deletions internal/c/qbx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,6 @@ extern int32 func__font(int32 i, int32 passed);
extern void sub__freefont(int32 f);
extern void sub__printmode(int32 mode, int32 i, int32 passed);
extern int32 func__printmode(int32 i, int32 passed);
extern uint32_t func__hsb32(double hue, double sat, double bri);
extern uint32_t func__hsba32(double hue, double sat, double bri, double alf);
extern double func__hue32(uint32_t argb);
extern double func__sat32(uint32_t argb);
extern double func__bri32(uint32_t argb);
extern uint32 matchcol(int32 r, int32 g, int32 b);
extern uint32 matchcol(int32 r, int32 g, int32 b, int32 i);
extern uint32 func__rgb(int32 r, int32 g, int32 b, int32 i, int32 passed);
Expand Down

0 comments on commit f06961e

Please sign in to comment.