From 4eb834641d86c5549393691ba6bfd13bae0cc133 Mon Sep 17 00:00:00 2001 From: Bill Kendrick Date: Wed, 22 Feb 2023 21:00:41 -0800 Subject: [PATCH] WIP: Splitting 3D Glasses out of Color Sep... ...and supporting any arbitrary color with Color Sep. tool. --- magic/src/colorsep.c | 117 ++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/magic/src/colorsep.c b/magic/src/colorsep.c index 0218b87bf..618126226 100644 --- a/magic/src/colorsep.c +++ b/magic/src/colorsep.c @@ -3,7 +3,7 @@ Color separation effect (a la red/cyan aka red/blue 3D glasses). Bill Kendrick - Last updated: February 21, 2023 + Last updated: February 22, 2023 */ #include @@ -16,14 +16,33 @@ #include "SDL_mixer.h" enum { - COLORSEP_MODE_RED_CYAN, - COLORSEP_MODE_GREEN_PURPLE, - COLORSEP_MODE_BLUE_YELLOW + COLORSEP_TOOL_3DGLASSES, + COLORSEP_TOOL_COLORSEP, + NUM_TOOLS }; -Mix_Chunk *snd_effect = NULL; +static char * colorsep_snd_filenames[NUM_TOOLS] = { + "colorsep.ogg", /* FIXME */ + "colorsep.ogg" +}; + +static char * colorsep_icon_filenames[NUM_TOOLS] = { + "colorsep.png", /* FIXME */ + "colorsep.png" +}; + +char * colorsep_names[NUM_TOOLS] = { + gettext_noop("3D Glasses"), + gettext_noop("Color Sep."), +}; +char * colorsep_descrs[NUM_TOOLS] = { + gettext_noop("Click and drag left and right to separate your picture's red and cyan, to make anaglyphs you can view with 3D glasses!"), + gettext_noop("Click and drag to separate your picture's colors.") +}; + +Mix_Chunk *snd_effects[NUM_TOOLS]; int colorsep_click_x, colorsep_click_y; -int colorsep_mode = COLORSEP_MODE_RED_CYAN; +float colorsep_r_pct, colorsep_g_pct, colorsep_b_pct; Uint32 colorsep_api_version(void); int colorsep_init(magic_api * api); @@ -59,35 +78,38 @@ Uint32 colorsep_api_version(void) int colorsep_init(magic_api * api) { + int i; char fname[1024]; - snprintf(fname, sizeof(fname), "%ssounds/magic/colorsep.ogg", - api->data_directory); - snd_effect = Mix_LoadWAV(fname); + for (i = 0; i < NUM_TOOLS; i++) { + snprintf(fname, sizeof(fname), "%ssounds/magic/%s", + api->data_directory, colorsep_snd_filenames[i]); + snd_effects[i] = Mix_LoadWAV(fname); + } return (1); } int colorsep_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) { - return (1); + return (NUM_TOOLS); } -SDL_Surface *colorsep_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) +SDL_Surface *colorsep_get_icon(magic_api * api, int which) { char fname[1024]; - snprintf(fname, sizeof(fname), "%simages/magic/colorsep.png", - api->data_directory); + snprintf(fname, sizeof(fname), "%simages/magic/%s", + api->data_directory, colorsep_icon_filenames[which]); return (IMG_Load(fname)); } char *colorsep_get_name(magic_api * api ATTRIBUTE_UNUSED, - int which ATTRIBUTE_UNUSED) + int which) { - return strdup(gettext("Color Sep.")); + return strdup(gettext(colorsep_names[which])); } int colorsep_get_group(magic_api * api ATTRIBUTE_UNUSED, @@ -97,15 +119,18 @@ int colorsep_get_group(magic_api * api ATTRIBUTE_UNUSED, } char *colorsep_get_description(magic_api * api ATTRIBUTE_UNUSED, - int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) + int which, int mode ATTRIBUTE_UNUSED) { - return strdup(gettext("Click and drag to separate your picture's colors (based on your color choice: red from cyan, green from purple, or blue from yellow).")); + return strdup(gettext(colorsep_descrs[which])); } int colorsep_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { - return 1; + if (which == COLORSEP_TOOL_COLORSEP) + return 1; + else + return 0; } int colorsep_modes(magic_api * api ATTRIBUTE_UNUSED, @@ -116,8 +141,12 @@ int colorsep_modes(magic_api * api ATTRIBUTE_UNUSED, void colorsep_shutdown(magic_api * api ATTRIBUTE_UNUSED) { - if (snd_effect != NULL) - Mix_FreeChunk(snd_effect); + int i; + + for (i = 0; i < NUM_TOOLS; i++) { + if (snd_effects[i] != NULL) + Mix_FreeChunk(snd_effects[i]); + } } void @@ -125,8 +154,7 @@ colorsep_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect) { - if (snd_effect != NULL) - api->stopsound(); + api->stopsound(); /* (Start off as if they clicked off to the side a little, so that * quick click+release will split the image bit by bit */ @@ -137,30 +165,32 @@ colorsep_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void -colorsep_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, +colorsep_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect) { int xx, yy, offset_x, offset_y; - Uint8 r1, g1, b1, r2, g2, b2; + Uint8 r1, g1, b1, r2, g2, b2, r, g, b; offset_x = colorsep_click_x - x; - offset_y = colorsep_click_y - y; + if (which == COLORSEP_TOOL_3DGLASSES) { + offset_y = 0; + } else { + offset_y = colorsep_click_y - y; + } - api->playsound(snd_effect, (((-offset_x * 255) / canvas->w) + 128), 255); + api->playsound(snd_effects[which], (((-offset_x * 255) / canvas->w) + 128), 255); for (yy = 0; yy < canvas->h; yy++) { for (xx = 0; xx < canvas->w; xx++) { SDL_GetRGB(api->getpixel(snapshot, xx + offset_x / 2, yy + offset_y / 2), snapshot->format, &r1, &g1, &b1); SDL_GetRGB(api->getpixel(snapshot, xx - offset_x / 2, yy - offset_y / 2), snapshot->format, &r2, &g2, &b2); - if (colorsep_mode == COLORSEP_MODE_RED_CYAN) { - api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r1, g2, b2)); - } else if (colorsep_mode == COLORSEP_MODE_GREEN_PURPLE) { - api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r2, g1, b2)); - } else if (colorsep_mode == COLORSEP_MODE_BLUE_YELLOW) { - api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r2, g2, b1)); - } + r = (Uint8) ((float) r1 * colorsep_r_pct) + ((float) r2 * (1.0 - colorsep_r_pct)); + g = (Uint8) ((float) g1 * colorsep_g_pct) + ((float) g2 * (1.0 - colorsep_g_pct)); + b = (Uint8) ((float) b1 * colorsep_b_pct) + ((float) b2 * (1.0 - colorsep_b_pct)); + + api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); } } @@ -186,20 +216,14 @@ void colorsep_set_color(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UN Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect ATTRIBUTE_UNUSED) { - r >>= 4; - g >>= 4; - b >>= 4; + colorsep_r_pct = (float) r / 255.0; + colorsep_g_pct = (float) g / 255.0; + colorsep_b_pct = (float) b / 255.0; - /* If the color chosen is very strong in some colors, separate it */ - if ((r > g && r > b) || (b > r && g > r)) { - colorsep_mode = COLORSEP_MODE_RED_CYAN; - } else if ((g > r && g > b) || (r > g && b > g)) { - colorsep_mode = COLORSEP_MODE_GREEN_PURPLE; - } else if ((b > r && b > g) || (r > b && g > b)) { - colorsep_mode = COLORSEP_MODE_BLUE_YELLOW; - } else { - /* No winner? Default to the most comment, red/cyan */ - colorsep_mode = COLORSEP_MODE_RED_CYAN; + if (colorsep_r_pct == colorsep_g_pct && colorsep_r_pct == colorsep_b_pct) { + colorsep_r_pct = 1.0; + colorsep_g_pct = 0.0; + colorsep_b_pct = 0.0; } } @@ -216,3 +240,4 @@ void colorsep_switchout(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) { } +