Skip to content

Commit bc2ee76

Browse files
committed
Add color to speech bubbles
1 parent 79ca46f commit bc2ee76

File tree

2 files changed

+105
-72
lines changed

2 files changed

+105
-72
lines changed

exec/exec.c

Lines changed: 104 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3676,52 +3676,61 @@ CTRL *MakeWindow(CTRL *tmpl, long size) {
36763676

36773677

36783678

3679-
void RGB2HSV(uint32_t bgra, float *_hsv) {
3680-
#define max(a, b) ((a > b)? a : b)
3679+
void RGB2HSL(uint32_t bgra, float *_hsl) {
36813680
#define min(a, b) ((a < b)? a : b)
3682-
float rd = (float)((bgra >> 16) & 0xFF) / 255;
3683-
float gd = (float)((bgra >> 8) & 0xFF) / 255;
3684-
float bd = (float)((bgra >> 0) & 0xFF) / 255;
3685-
float max = (float)max(rd, max(gd, bd)),
3686-
min = (float)min(rd, min(gd, bd));
3687-
float d = max - min;
3688-
3689-
_hsv[0] = 0;
3690-
_hsv[1] = (max == 0 ? 0 : d / max);
3691-
_hsv[2] = max;
3692-
if (max != min) {
3693-
if (max == rd) _hsv[0] = (gd - bd) / d + (gd < bd ? 6 : 0);
3694-
else if (max == gd) _hsv[0] = (bd - rd) / d + 2;
3695-
else if (max == bd) _hsv[0] = (rd - gd) / d + 4;
3696-
_hsv[0] = floor(_hsv[0] * 60.0);
3697-
_hsv[0] = (_hsv[0] < 360.0)? _hsv[0] : _hsv[0] - 360.0;
3698-
}
3699-
#undef max
3681+
#define max(a, b) ((a > b)? a : b)
3682+
float rrrr = (float)((uint8_t)(bgra >> 16)) / 255,
3683+
gggg = (float)((uint8_t)(bgra >> 8)) / 255,
3684+
bbbb = (float)((uint8_t)(bgra )) / 255,
3685+
_min = min(min(rrrr, gggg), bbbb),
3686+
_max = max(max(rrrr, gggg), bbbb), mean;
37003687
#undef min
3688+
#undef max
3689+
_hsl[0] = _hsl[1] = _hsl[2] = 0.0;
3690+
if ((_hsl[2] = (_min + _max) * 0.5) <= 0.0)
3691+
return;
3692+
if ((_hsl[1] = mean = _max - _min) > 0.0)
3693+
_hsl[1] /= (_hsl[2] <= 0.5)? (_max + _min) : (2.0 - _max - _min);
3694+
else
3695+
return;
3696+
if (rrrr == _max)
3697+
_hsl[0] = (gggg == _min)? (5.0 + (_max - bbbb) / mean)
3698+
: (1.0 - (_max - gggg) / mean);
3699+
else if (gggg == _max)
3700+
_hsl[0] = (bbbb == _min)? (1.0 + (_max - rrrr) / mean)
3701+
: (3.0 - (_max - bbbb) / mean);
3702+
else // (bbbb == _max)
3703+
_hsl[0] = (rrrr == _min)? (3.0 + (_max - gggg) / mean)
3704+
: (5.0 - (_max - rrrr) / mean);
3705+
_hsl[0] /= 6.0;
37013706
}
37023707

3703-
uint32_t HSV2RGB(float *_hsv) {
3704-
uint8_t r, g, b;
3705-
float p, q, t;
3706-
3707-
if (_hsv[1] == 0.0)
3708-
r = g = b = _hsv[1] * 255.0;
3709-
else {
3710-
t = _hsv[0] / 60.0;
3711-
t -= (r = floor(t));
3712-
p = _hsv[2] * (1.0 - _hsv[1]);
3713-
q = _hsv[2] * (1.0 - _hsv[1] * t);
3714-
t = _hsv[2] * (1.0 - _hsv[1] * (1.0 - t));
3715-
switch (r) {
3716-
case 0: r = _hsv[2]; g = t; b = p; break;
3717-
case 1: r = q; g = _hsv[2]; b = p; break;
3718-
case 2: r = p; g = _hsv[2]; b = t; break;
3719-
case 3: r = p; g = q; b = _hsv[2]; break;
3720-
case 4: r = t; g = p; b = _hsv[2]; break;
3721-
default: r = _hsv[2]; g = p; b = q; break;
3708+
uint32_t HSL2RGB(float *_hsl) {
3709+
uint8_t rrrr = 255 * _hsl[2], gggg = 255 * _hsl[2], bbbb = 255 * _hsl[2];
3710+
float coef, mean, fraq, mid1, mid2;
3711+
3712+
coef = (_hsl[2] <= 0.5)? ( _hsl[2] + _hsl[1] * _hsl[2])
3713+
: (_hsl[1] + _hsl[2] - _hsl[1] * _hsl[2]);
3714+
if (coef > 0) {
3715+
mean = 2.0 * _hsl[2] - coef;
3716+
fraq = (coef - mean) * (6 * _hsl[0] - (int)(6 * _hsl[0]));
3717+
mid1 = mean + fraq;
3718+
mid2 = coef - fraq;
3719+
switch ((int)(6 * _hsl[0])) {
3720+
case 0: rrrr = 255 * coef; gggg = 255 * mid1; bbbb = 255 * mean; break;
3721+
case 1: rrrr = 255 * mid2; gggg = 255 * coef; bbbb = 255 * mean; break;
3722+
case 2: rrrr = 255 * mean; gggg = 255 * coef; bbbb = 255 * mid1; break;
3723+
case 3: rrrr = 255 * mean; gggg = 255 * mid2; bbbb = 255 * coef; break;
3724+
case 4: rrrr = 255 * mid1; gggg = 255 * mean; bbbb = 255 * coef; break;
3725+
case 5: rrrr = 255 * coef; gggg = 255 * mean; bbbb = 255 * mid2; break;
37223726
}
37233727
}
3724-
return b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | 0xFF000000;
3728+
return bbbb | ((uint32_t)gggg << 8) | ((uint32_t)rrrr << 16) | 0xFF000000;
3729+
}
3730+
3731+
int li64cmp(const void *a, const void *b) {
3732+
int64_t retn = *(int64_t*)a - *(int64_t*)b;
3733+
return (retn >= 0)? (retn > 0)? 1 : 0 : -1;
37253734
}
37263735

37273736
int bgracmp(const void *a, const void *b) {
@@ -3749,12 +3758,13 @@ void eExecuteEngine(char *fcnf, char *base, ulong xico, ulong yico,
37493758
"wBGRA", "Opaque", "wRegion","Draw"},
37503759
*uSTF[] = {"Topmost","Hover", "CSpeech",
37513760
"Interaction","Speech", "Effects","Update"};
3761+
const float ldif = 0.25;
3762+
float mean, _hsl[2][3];
37523763
char *file, *fptr, *conf, *temp;
37533764
uint32_t elem, *iter; /// for IF_BIN_FIND and RNG_Make
3754-
uint64_t cclr, pclr;//, tclr;
3765+
uint64_t clrs[3], tclr;
37553766
intptr_t indx;
37563767
int16_t runs = 0;
3757-
// float _hsv[2][3];
37583768
LINF *ulib;
37593769
AINF atmp;
37603770

@@ -4059,41 +4069,64 @@ void eExecuteEngine(char *fcnf, char *base, ulong xico, ulong yico,
40594069
if (!indx)
40604070
CreatePreview(ulib); /// need that preview for others to work
40614071

4062-
/// calculating speech colors if there are speeches in the library
4063-
if (ulib->nsay) {
4064-
cclr = 0xFFFFFFFF;
4065-
pclr = 0xFF000000;
4066-
/*
4067-
anim.xdim = ulib->barr[0].unit[0].xdim;
4068-
anim.ydim = ulib->barr[0].unit[0].ydim;
4069-
anim.uuid = ulib->barr[0].unit[0].uuid;
4070-
xpos = anim.xdim * anim.ydim;
4071-
memset(anim.time, 0, xpos * sizeof(*anim.time));
4072-
cEngineCallback(engc.engd, ECB_DRAW, (intptr_t)&anim);
4073-
qsort(anim.time, xpos, sizeof(*anim.time), bgracmp);
4074-
for (tclr = cclr = pclr = 0; xpos >= 0; xpos--)
4075-
if (xpos && ((tclr & 0xFFFFFFFFUL) == anim.time[xpos - 1]))
4072+
ulib->fgsc = 0xFF000000;
4073+
ulib->bgsc = 0xFFFFFFFF;
4074+
/// calculating speech colors if there are speeches in
4075+
/// the library and the "colored speech" flag is set
4076+
if (ulib->nsay && (engc.ccur.flgs & CSF_ECLR)) {
4077+
atmp.fcnt = 0;
4078+
atmp.xdim = ulib->barr[0].unit[0].xdim;
4079+
atmp.ydim = ulib->barr[0].unit[0].ydim;
4080+
atmp.uuid = ulib->barr[0].unit[0].uuid;
4081+
atmp.time =
4082+
calloc(xpos = atmp.xdim * atmp.ydim, sizeof(*atmp.time));
4083+
cEngineCallback(engc.engd, ECB_DRAW, (intptr_t)&atmp);
4084+
qsort(atmp.time, xpos, sizeof(*atmp.time), bgracmp);
4085+
for (tclr = clrs[0] = clrs[1] = clrs[2] = 0; xpos >= 0; xpos--)
4086+
if (xpos && ((tclr & 0xFFFFFFFFUL) == atmp.time[xpos - 1]))
40764087
tclr += 0x100000000UL;
40774088
else {
4078-
if ((tclr & 0xFF000000) && ((tclr >> 32) >= (cclr >> 32))) {
4079-
pclr = cclr;
4080-
cclr = tclr;
4089+
if ((tclr & 0xFF000000)
4090+
&& ((tclr >> 32) >= (clrs[2] >> 32))) {
4091+
if ((tclr >> 32) < (clrs[1] >> 32))
4092+
clrs[2] = tclr;
4093+
else if ((tclr >> 32) < (clrs[0] >> 32)) {
4094+
clrs[2] = clrs[1];
4095+
clrs[1] = tclr;
4096+
}
4097+
else {
4098+
clrs[2] = clrs[1];
4099+
clrs[1] = clrs[0];
4100+
clrs[0] = tclr;
4101+
}
40814102
}
4082-
tclr = (xpos)? anim.time[xpos - 1] | 0x100000000UL : 0;
4103+
tclr = (xpos)? atmp.time[xpos - 1] | 0x100000000UL : 0;
4104+
}
4105+
free(atmp.time);
4106+
#define LUMA(c) (3 * (uint8_t)(c >> 16) + /* -R /G |B */ \
4107+
4 * (uint8_t)(c >> 8) + (uint8_t)c)
4108+
clrs[0] = ((uint64_t)LUMA(clrs[0]) << 32) + (uint32_t)clrs[0];
4109+
clrs[1] = ((uint64_t)LUMA(clrs[1]) << 32) + (uint32_t)clrs[1];
4110+
clrs[2] = ((uint64_t)LUMA(clrs[2]) << 32) + (uint32_t)clrs[2];
4111+
#undef LUMA
4112+
qsort(clrs, 3, sizeof(*clrs), li64cmp);
4113+
RGB2HSL(clrs[0], _hsl[0]);
4114+
RGB2HSL(clrs[2], _hsl[1]);
4115+
if (_hsl[1][2] - _hsl[0][2] < 2 * ldif) {
4116+
mean = 0.5 * (_hsl[1][2] + _hsl[0][2]);
4117+
if (mean + ldif > 1)
4118+
_hsl[0][2] = mean - 2 * ldif;
4119+
else if (mean - ldif < 0)
4120+
_hsl[1][2] = mean + 2 * ldif;
4121+
else {
4122+
_hsl[0][2] = mean - ldif;
4123+
_hsl[1][2] = mean + ldif;
40834124
}
4084-
RGB2HSV(pclr, _hsv[0]);
4085-
RGB2HSV(cclr, _hsv[1]);
4086-
tclr = cclr;
4087-
cclr = (_hsv[1][1] > _hsv[0][1])? cclr : pclr;
4088-
pclr = (_hsv[1][1] > _hsv[0][1])? pclr : tclr;
4089-
RGB2HSV(pclr, _hsv[0]);
4090-
RGB2HSV(cclr, _hsv[1]);
4091-
//*/
4092-
ulib->bgsc = cclr;
4093-
ulib->fgsc = pclr;
4125+
}
4126+
ulib->fgsc = HSL2RGB(_hsl[0]);
4127+
ulib->bgsc = HSL2RGB(_hsl[1]);
40944128
}
40954129
}
4096-
// free(anim.time);
40974130
RUN_FC2E(engc.MCT_FLTR, MSG_BCLK, 0);
40984131
CategorizePreviews(&engc);
40994132
engc.seed = RNG_Make(elem = time(0));

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The task at hand is to implement the remaining DP features missing from DPE:
6565

6666
Some functionality is not present in DP but would also be nice to have:
6767

68-
1. Add colors to speech bubbles, make default colors configurable
68+
1. ~~Add colors to speech bubbles, make default colors configurable~~
6969
1. Implement the "alias method" for behaviours
7070
1. Parallelize sprite processing in frontend
7171
1. Move rendering options from tray menu to tab 3

0 commit comments

Comments
 (0)