Actually commiting new Magic tool source
...and CHANGES.txt update
This commit is contained in:
parent
d588c39d21
commit
06aa682667
2 changed files with 130 additions and 48 deletions
|
|
@ -7,7 +7,7 @@ Various contributors (see below, and AUTHORS.txt)
|
|||
https://tuxpaint.org/
|
||||
|
||||
|
||||
2023.February.26 (0.9.29)
|
||||
2023.February.28 (0.9.29)
|
||||
* Improvements to "Stamp" tool:
|
||||
-----------------------------
|
||||
* Stamps may now be rotated.
|
||||
|
|
@ -58,6 +58,20 @@ https://tuxpaint.org/
|
|||
Attribution 4.0 International (CC BY 4.0)
|
||||
by https://freesound.org/people/juskiddink/)
|
||||
|
||||
* [WIP] "Saturate" & "Desaturate" - Increase or decrease color saturation.
|
||||
Bill Kendrick <bill@newbreedsoftware.com>
|
||||
- need icons
|
||||
- need sound effects
|
||||
|
||||
* [WIP] "Keep Color" & "Remove Color" - Completely desaturate
|
||||
parts of the picture, based on the chosen color.
|
||||
"Keep" keeps the saturation intact if the colors match;
|
||||
while "Remove" desaturates parts of the image that match the
|
||||
chosen color.
|
||||
Bill Kendrick <bill@newbreedsoftware.com>
|
||||
- need icons
|
||||
- need sound effects
|
||||
|
||||
* [WIP] "Rivulet"; apply rivulets of water to the canvas
|
||||
- needs better icon
|
||||
- needs sound effect
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
(See COPYING.txt)
|
||||
|
||||
Last updated: February 12, 2023
|
||||
Last updated: February 28, 2023
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -36,10 +36,75 @@ enum
|
|||
{
|
||||
TOOL_FADE,
|
||||
TOOL_DARKEN,
|
||||
TOOL_DESATURATE,
|
||||
TOOL_SATURATE,
|
||||
TOOL_REMOVE,
|
||||
TOOL_KEEP,
|
||||
NUM_TOOLS
|
||||
};
|
||||
|
||||
char * tool_names[NUM_TOOLS] = {
|
||||
gettext_noop("Lighten"),
|
||||
gettext_noop("Darken"),
|
||||
gettext_noop("Desaturate"),
|
||||
gettext_noop("Saturate"),
|
||||
gettext_noop("Remove Color"),
|
||||
gettext_noop("Keep Color"),
|
||||
};
|
||||
|
||||
char * tool_descriptions[NUM_TOOLS][2] = {
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to lighten parts of your picture."),
|
||||
gettext_noop("Click to lighten your entire picture.")
|
||||
},
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to darken parts of your picture."),
|
||||
gettext_noop("Click to darken your entire picture.")
|
||||
},
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to desaturate parts of your picture."),
|
||||
gettext_noop("Click to desaturate your entire picture.")
|
||||
},
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to saturate parts of your picture."),
|
||||
gettext_noop("Click to saturate your entire picture.")
|
||||
},
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to entirely desaturate parts of your picture that match the chosen color."),
|
||||
gettext_noop("Click to entirely desaturate your the parts of your picture that match the chosen color."),
|
||||
},
|
||||
{
|
||||
gettext_noop("Click and drag the mouse to entirely desaturate parts of your picture that don't match the chosen color."),
|
||||
gettext_noop("Click to entirely desaturate your the parts of your picture that don't match the chosen color."),
|
||||
},
|
||||
};
|
||||
|
||||
char * sfx_filenames[NUM_TOOLS] = {
|
||||
"fade.wav",
|
||||
"darken.wav",
|
||||
"fade.wav", // FIXME
|
||||
"darken.wav", // FIXME
|
||||
"darken.wav", // FIXME
|
||||
"darken.wav", // FIXME
|
||||
};
|
||||
|
||||
char * icon_filenames[NUM_TOOLS] = {
|
||||
"fade.png",
|
||||
"darken.png",
|
||||
"fade.png", // FIXME
|
||||
"darken.png", // FIXME
|
||||
"darken.png", // FIXME
|
||||
"darken.png", // FIXME
|
||||
};
|
||||
|
||||
static Mix_Chunk *snd_effects[NUM_TOOLS];
|
||||
float chosen_h, chosen_s;
|
||||
|
||||
#define KEEP_REMOVE_HUE_THRESH 15.0
|
||||
#define KEEP_REMOVE_VALUE_THRESH 0.4
|
||||
|
||||
#define SAT_DESAT_RATIO_NUM 3
|
||||
#define SAT_DESAT_RATIO_DENOM 4
|
||||
|
||||
|
||||
/* Local function prototypes: */
|
||||
|
|
@ -74,17 +139,17 @@ void fade_darken_switchout(magic_api * api, int which, int mode,
|
|||
SDL_Surface * canvas);
|
||||
int fade_darken_modes(magic_api * api, int which);
|
||||
|
||||
|
||||
int fade_darken_init(magic_api * api)
|
||||
{
|
||||
int i;
|
||||
char fname[1024];
|
||||
|
||||
snprintf(fname, sizeof(fname), "%ssounds/magic/fade.wav",
|
||||
api->data_directory);
|
||||
snd_effects[TOOL_FADE] = Mix_LoadWAV(fname);
|
||||
|
||||
snprintf(fname, sizeof(fname), "%ssounds/magic/darken.wav",
|
||||
api->data_directory);
|
||||
snd_effects[TOOL_DARKEN] = Mix_LoadWAV(fname);
|
||||
for (i = 0; i < NUM_TOOLS; i++) {
|
||||
snprintf(fname, sizeof(fname), "%ssounds/magic/%s",
|
||||
api->data_directory, sfx_filenames[i]);
|
||||
snd_effects[i] = Mix_LoadWAV(fname);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -105,16 +170,8 @@ SDL_Surface *fade_darken_get_icon(magic_api * api, int which)
|
|||
{
|
||||
char fname[1024];
|
||||
|
||||
if (which == TOOL_FADE)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%simages/magic/fade.png",
|
||||
api->data_directory);
|
||||
}
|
||||
else if (which == TOOL_DARKEN)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%simages/magic/darken.png",
|
||||
api->data_directory);
|
||||
}
|
||||
snprintf(fname, sizeof(fname), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
return (IMG_Load(fname));
|
||||
}
|
||||
|
|
@ -122,12 +179,7 @@ SDL_Surface *fade_darken_get_icon(magic_api * api, int which)
|
|||
// Return our name, localized:
|
||||
char *fade_darken_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
|
||||
{
|
||||
if (which == TOOL_FADE)
|
||||
return (strdup(gettext_noop("Lighten")));
|
||||
else if (which == TOOL_DARKEN)
|
||||
return (strdup(gettext_noop("Darken")));
|
||||
|
||||
return (NULL);
|
||||
return strdup(gettext(tool_names[which]));
|
||||
}
|
||||
|
||||
// Return our group (all the same):
|
||||
|
|
@ -141,26 +193,7 @@ int fade_darken_get_group(magic_api * api ATTRIBUTE_UNUSED,
|
|||
char *fade_darken_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
|
||||
int mode)
|
||||
{
|
||||
if (which == TOOL_FADE)
|
||||
{
|
||||
if (mode == MODE_PAINT)
|
||||
return (strdup
|
||||
(gettext_noop
|
||||
("Click and drag the mouse to lighten parts of your picture.")));
|
||||
else if (mode == MODE_FULLSCREEN)
|
||||
return (strdup(gettext_noop("Click to lighten your entire picture.")));
|
||||
}
|
||||
else if (which == TOOL_DARKEN)
|
||||
{
|
||||
if (mode == MODE_PAINT)
|
||||
return (strdup
|
||||
(gettext_noop
|
||||
("Click and drag the mouse to darken parts of your picture.")));
|
||||
else if (mode == MODE_FULLSCREEN)
|
||||
return (strdup(gettext_noop("Click to darken your entire picture.")));
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
return strdup(gettext(tool_descriptions[which][mode - 1]));
|
||||
}
|
||||
|
||||
static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas,
|
||||
|
|
@ -183,10 +216,40 @@ static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas,
|
|||
g = max(g - 48, 0);
|
||||
b = max(b - 48, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float h, s, v;
|
||||
|
||||
api->rgbtohsv(r, g, b, &h, &s, &v);
|
||||
|
||||
if (which == TOOL_DESATURATE) {
|
||||
s = (s * SAT_DESAT_RATIO_NUM) / SAT_DESAT_RATIO_DENOM;
|
||||
} else if (which == TOOL_SATURATE) {
|
||||
if (s > 0.1) { /* don't saturate things w/o undefined color! */
|
||||
s = (s * SAT_DESAT_RATIO_DENOM) / SAT_DESAT_RATIO_NUM;
|
||||
if (s > 1.0) {
|
||||
s = 1.0;
|
||||
}
|
||||
}
|
||||
} else if (which == TOOL_REMOVE) {
|
||||
if (fabs(h - chosen_h) <= KEEP_REMOVE_HUE_THRESH &&
|
||||
fabs(s - chosen_s) <= KEEP_REMOVE_VALUE_THRESH) {
|
||||
s = 0.0;
|
||||
}
|
||||
} else if (which == TOOL_KEEP) {
|
||||
if (fabs(h - chosen_h) > KEEP_REMOVE_HUE_THRESH ||
|
||||
fabs(s - chosen_s) > KEEP_REMOVE_VALUE_THRESH) {
|
||||
s = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
api->hsvtorgb(h, s, v, &r, &g, &b);
|
||||
}
|
||||
|
||||
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
|
||||
}
|
||||
|
||||
|
||||
// Callback that does the fade_darken color effect on a circle centered around x,y
|
||||
static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * last, int x, int y)
|
||||
|
|
@ -288,16 +351,21 @@ void fade_darken_shutdown(magic_api * api ATTRIBUTE_UNUSED)
|
|||
Mix_FreeChunk(snd_effects[1]);
|
||||
}
|
||||
|
||||
// We don't use colors
|
||||
void fade_darken_set_color(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * last ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
|
||||
void fade_darken_set_color(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * last ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
|
||||
{
|
||||
float tmp;
|
||||
|
||||
api->rgbtohsv(r, g, b, &chosen_h, &chosen_s, &tmp);
|
||||
}
|
||||
|
||||
// We don't use colors
|
||||
int fade_darken_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
|
||||
int which ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (which == TOOL_REMOVE || which == TOOL_KEEP)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue