Re-ran indent on all .c & .h source code files

Like so --
  find . -name "*.c" -or -name "*.h" -exec  indent -nbfda -npcs -npsl -bli0 --no-tabs {} \;

The `indent` invocation differs from the last one noted in
CHANGES.txt (from 2006!?), in that I've added "--no-tabs",
to ensure indents are all space-based.
This commit is contained in:
Bill Kendrick 2022-09-15 00:11:16 -07:00
parent 09f332367f
commit cc05925d9e
99 changed files with 31659 additions and 27102 deletions

View file

@ -7,7 +7,7 @@ Various contributors (see below, and AUTHORS.txt)
http://www.tuxpaint.org/
2022.September.14 (0.9.29)
2022.September.15 (0.9.29)
* Improvements to "Stamp" tool:
-----------------------------
* Stamps may now be rotated.
@ -131,6 +131,9 @@ http://www.tuxpaint.org/
Tux Paint Config. source updated to make the script's job easier.
Bill Kendrick <bill@newbreedsoftware.com>
* Cleaned up .c and .h source files using `indent`:
find . -name "*.c" -or -name "*.h" -exec indent -nbfda -npcs -npsl -bli0 --no-tabs {} \;
* Documentation updates:
---------------------
* Update macOS build instructions for SDL2.0.

View file

@ -11,7 +11,7 @@ static TYPE x UNUSED;
#endif
#ifdef SYMBOL
static int exists UNUSED = ! !SYMBOL;
static int exists UNUSED = !!SYMBOL;
#endif
int main(int argc UNUSED, char *argv[]UNUSED)

View file

@ -93,9 +93,11 @@ Uint8 example_r, example_g, example_b;
// that are declared _before_ them.
void example_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void example_line_callback(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
/* Setup Functions: */
@ -136,22 +138,23 @@ int example_init(magic_api * api)
char fname[1024];
for (i = 0; i < NUM_TOOLS; i++)
{
// Assemble the filename from the "snd_filenames[]" array into
// a full path to a real file.
//
// Use "api->data_directory" to figure out where our sounds should be.
// (The "tp-magic-config --dataprefix" command would have told us when
// we installed our plugin and its data.)
{
// Assemble the filename from the "snd_filenames[]" array into
// a full path to a real file.
//
// Use "api->data_directory" to figure out where our sounds should be.
// (The "tp-magic-config --dataprefix" command would have told us when
// we installed our plugin and its data.)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, snd_filenames[i]);
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory,
snd_filenames[i]);
printf("Trying to load %s sound file\n", fname);
printf("Trying to load %s sound file\n", fname);
// Try to load the file!
// Try to load the file!
snd_effect[i] = Mix_LoadWAV(fname);
}
snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -191,7 +194,8 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
// We use 'which' (which of our tools Tux Paint is asking about)
// as an index into the array.
snprintf(fname, sizeof(fname), "%s/images/magic/%s.png", api->data_directory, icon_filenames[which]);
snprintf(fname, sizeof(fname), "%s/images/magic/%s.png",
api->data_directory, icon_filenames[which]);
// Try to load the image, and return the results to Tux Paint:
@ -330,7 +334,8 @@ void example_shutdown(magic_api * api)
void
example_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
// In our case, a single click (which is also the start of a drag!)
// is identical to what dragging does, but just at one point, rather
@ -347,7 +352,8 @@ example_click(magic_api * api, int which, int mode,
void
example_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
// Call Tux Paint's "line()" function.
//
@ -358,7 +364,8 @@ example_drag(magic_api * api, int which, SDL_Surface * canvas,
// useful things (which of our "Magic" tools is being used and
// the current and snapshot canvases).
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, example_line_callback);
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, 1,
example_line_callback);
// If we need to, swap the X and/or Y values, so that
@ -366,19 +373,19 @@ example_drag(magic_api * api, int which, SDL_Surface * canvas,
// so the values we put inside "update_rect" make sense:
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
// Fill in the elements of the "update_rect" SDL_Rect structure
@ -409,7 +416,8 @@ example_drag(magic_api * api, int which, SDL_Surface * canvas,
void
example_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
// Neither of our effects do anything special when the mouse is released
// from a click or click-and-drag, so there's no code here...
@ -453,7 +461,8 @@ void example_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
// It pays attention to 'which' to determine which of our plugin's tools
// is currently selected.
void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
void example_line_callback(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y)
{
// For technical reasons, we can't accept a pointer to the "magic_api"
// struct, like the other functions do.
@ -473,37 +482,41 @@ void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surfa
// Tux Paint sends to us with the values we enumerated above.
if (which == TOOL_ONE)
{
// Tool number 1 simply draws a single pixel at the (x,y) location.
// It's a 1x1 pixel brush
{
// Tool number 1 simply draws a single pixel at the (x,y) location.
// It's a 1x1 pixel brush
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, example_r, example_g, example_b));
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, example_r, example_g,
example_b));
// We use "SDL_MapRGB()" to convert the RGB value we receive from Tux Paint
// for the user's current color selection to a 'Uint32' pixel value
// we can send to Tux Paint's "putpixel()" function.
}
// We use "SDL_MapRGB()" to convert the RGB value we receive from Tux Paint
// for the user's current color selection to a 'Uint32' pixel value
// we can send to Tux Paint's "putpixel()" function.
}
else if (which == TOOL_TWO)
{
// Tool number 2 copies an 8x8 square of pixels from the opposite side
// of the canvas and puts it under the cursor
for (yy = -4; yy < 4; yy++)
{
// Tool number 2 copies an 8x8 square of pixels from the opposite side
// of the canvas and puts it under the cursor
for (xx = -4; xx < 4; xx++)
{
api->putpixel(canvas, x + xx, y + yy,
api->getpixel(snapshot, canvas->w - x - xx,
canvas->h - y - yy));
for (yy = -4; yy < 4; yy++)
{
for (xx = -4; xx < 4; xx++)
{
api->putpixel(canvas, x + xx, y + yy, api->getpixel(snapshot, canvas->w - x - xx, canvas->h - y - yy));
// We simply use Tux Paint's "getpixel()" routine to pull pixel
// values from the 'snapshot', and then "putpixel()" to draw them
// right into the 'canvas'.
// We simply use Tux Paint's "getpixel()" routine to pull pixel
// values from the 'snapshot', and then "putpixel()" to draw them
// right into the 'canvas'.
// Note: putpixel() and getpixel() are safe to use, even if your
// X,Y values are outside of the SDL surface (e.g., negative, or
// greater than the surface's width or height).
}
}
// Note: putpixel() and getpixel() are safe to use, even if your
// X,Y values are outside of the SDL surface (e.g., negative, or
// greater than the surface's width or height).
}
}
}
}
// Switch-In event
@ -522,7 +535,8 @@ void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surfa
// Our example doesn't do anything when we switch to, or away from, our
// Magic tools, so we just do nothing here.
void example_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas)
void example_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas)
{
}
@ -542,6 +556,7 @@ void example_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas
// Our example doesn't do anything when we switch to, or away from, our
// Magic tools, so we just do nothing here.
void example_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas)
void example_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas)
{
}

View file

@ -73,7 +73,8 @@ const int alien_groups[alien_NUM_TOOLS] = {
};
const char *alien_descs[alien_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to change the colors in parts of your picture."),
{gettext_noop
("Click and drag the mouse to change the colors in parts of your picture."),
gettext_noop("Click to change the colors in your entire picture."),},
};
@ -86,17 +87,21 @@ char *alien_get_name(magic_api * api, int which);
int alien_get_group(magic_api * api, int which);
char *alien_get_description(magic_api * api, int which, int mode);
void alien_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
Mix_Chunk *magic_loadsound(char *file);
void alien_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void alien_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void alien_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void alien_shutdown(magic_api * api);
void alien_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int alien_requires_colors(magic_api * api, int which);
void alien_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void alien_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void alien_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void alien_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int alien_modes(magic_api * api, int which);
@ -114,10 +119,11 @@ int alien_init(magic_api * api)
srand(time(0));
for (i = 0; i < alien_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, alien_snd_filenames[i]);
alien_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
alien_snd_filenames[i]);
alien_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -131,7 +137,8 @@ SDL_Surface *alien_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, alien_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
alien_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -147,14 +154,16 @@ int alien_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *alien_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *alien_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(alien_descs[which][mode - 1])));
}
//Do the effect for one pixel
static void do_alien_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -162,74 +171,82 @@ static void do_alien_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
double temp2[3];
int k;
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1],
&temp[2]);
for (k = 0; k < 3; k++)
{
{
//EP temp2[k] = clamp(0,127.5 * (1.0 + sin (((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI)),255);
temp2[k] = clamp(0.0,
127.5 * (1.0 +
sin(((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI)),
255.0);
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
temp2[k] = clamp(0.0,
127.5 * (1.0 +
sin(((temp[k] / 127.5 -
1.0) * alien_FREQUENCY[k] +
alien_ANGLE[k] / 180.0) * M_PI)), 255.0);
}
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
}
// Do the effect for the full image
static void do_alien_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
static void do_alien_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which)
{
int x, y;
for (y = 0; y < last->h; y++)
{
for (x = 0; x < last->w; x++)
{
for (x = 0; x < last->w; x++)
{
do_alien_pixel(ptr, which, canvas, last, x, y);
}
do_alien_pixel(ptr, which, canvas, last, x, y);
}
}
}
//do the effect for the brush
static void do_alien_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_alien_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - alien_RADIUS; yy < y + alien_RADIUS; yy++)
{
for (xx = x - alien_RADIUS; xx < x + alien_RADIUS; xx++)
{
for (xx = x - alien_RADIUS; xx < x + alien_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, alien_RADIUS) && !api->touched(xx, yy))
{
do_alien_pixel(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, alien_RADIUS)
&& !api->touched(xx, yy))
{
do_alien_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag:
void alien_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_alien_brush);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_alien_brush);
api->playsound(alien_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - alien_RADIUS;
update_rect->y = oy - alien_RADIUS;
@ -244,34 +261,38 @@ Mix_Chunk *magic_loadsound(char *file)
Mix_Chunk *temp;
if (!use_sound)
{
return (Mix_Chunk *) - 1;
}
{
return (Mix_Chunk *) - 1;
}
temp = Mix_LoadWAV(file);
return temp;
}
// Affect the canvas on click:
void alien_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
alien_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_alien_full(api, canvas, last, which);
api->playsound(alien_snd_effect[which], 128, 255);
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_alien_full(api, canvas, last, which);
api->playsound(alien_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void alien_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void alien_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -282,32 +303,36 @@ void alien_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < alien_NUM_TOOLS; i++)
{
if (alien_snd_effect[i] != NULL)
{
if (alien_snd_effect[i] != NULL)
{
Mix_FreeChunk(alien_snd_effect[i]);
}
Mix_FreeChunk(alien_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void alien_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void alien_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int alien_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int alien_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void alien_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void alien_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void alien_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void alien_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -62,15 +62,20 @@ int blind_get_group(magic_api * api, int which);
char *blind_get_description(magic_api * api, int which, int mode);
int blind_requires_colors(magic_api * api, int which);
void blind_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void blind_shutdown(magic_api * api);
void blind_paint_blind(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void blind_paint_blind(void *ptr_to_api, int which_tool, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void blind_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void blind_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blind_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void blind_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void blind_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void blind_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int blind_modes(magic_api * api, int which);
// Housekeeping functions
@ -91,7 +96,8 @@ int blind_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/blind.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/blind.ogg",
api->data_directory);
blind_snd = Mix_LoadWAV(fname);
return (1);
@ -106,36 +112,45 @@ SDL_Surface *blind_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/blind.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/blind.png",
api->data_directory);
return (IMG_Load(fname));
}
char *blind_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *blind_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Blind"));
}
int blind_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int blind_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_DECORATIONS;
}
char *blind_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *blind_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return
strdup(gettext_noop
("Click towards the edge of your picture to pull window blinds over it. Move perpendicularly to open or close the blinds."));
}
int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void blind_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void blind_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -147,12 +162,14 @@ void blind_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Interactivity functions
void blind_paint_blind(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr_to_api;
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, (blind_r + blind_light) / 2, (blind_g + blind_light) / 2,
SDL_MapRGB(canvas->format, (blind_r + blind_light) / 2,
(blind_g + blind_light) / 2,
(blind_b + blind_light) / 2));
}
@ -167,145 +184,157 @@ void blind_paint_blind(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
*/
void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
int opaque;
SDL_BlitSurface(snapshot, NULL, canvas, NULL);
switch (blind_side)
{
int i, j;
case BLIND_SIDE_TOP:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y; i >= 0; i -= BLIND_THICKNESS)
{
int i, j;
case BLIND_SIDE_TOP:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y; i >= 0; i -= BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j > i - opaque / 2; j--)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light -= 20;
}
for (j = i - opaque / 2; j > i - opaque; j--)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = max(oy, y);
api->playsound(blind_snd, 128, 255);
break;
case BLIND_SIDE_BOTTOM:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y; i <= canvas->h; i += BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j < i + opaque / 2; j++)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light -= 20;
}
for (j = i + opaque / 2; j < i + opaque; j++)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = min(oy, y);
update_rect->w = canvas->w;
update_rect->h = canvas->h - update_rect->y;
api->playsound(blind_snd, 128, 255);
break;
case BLIND_SIDE_RIGHT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i <= canvas->w; i += BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j < i + opaque / 2; j++)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light -= 20;
}
for (j = i + opaque / 2; j < i + opaque; j++)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = min(ox, x);
update_rect->y = 0;
update_rect->w = canvas->w - update_rect->x;
update_rect->h = canvas->h;
api->playsound(blind_snd, (x * 255) / canvas->w, 255);
break;
case BLIND_SIDE_LEFT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i >= 0; i -= BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j > i - opaque / 2; j--)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light -= 20;
}
for (j = i - opaque / 2; j > i - opaque; j--)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = max(ox, x);
update_rect->h = canvas->h;
api->playsound(blind_snd, (x * 255) / canvas->w, 255);
break;
blind_light = 255;
for (j = i; j > i - opaque / 2; j--)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1,
blind_paint_blind);
blind_light -= 20;
}
for (j = i - opaque / 2; j > i - opaque; j--)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1,
blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = max(oy, y);
api->playsound(blind_snd, 128, 255);
break;
case BLIND_SIDE_BOTTOM:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y; i <= canvas->h; i += BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j < i + opaque / 2; j++)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1,
blind_paint_blind);
blind_light -= 20;
}
for (j = i + opaque / 2; j < i + opaque; j++)
{
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1,
blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = min(oy, y);
update_rect->w = canvas->w;
update_rect->h = canvas->h - update_rect->y;
api->playsound(blind_snd, 128, 255);
break;
case BLIND_SIDE_RIGHT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i <= canvas->w; i += BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j < i + opaque / 2; j++)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1,
blind_paint_blind);
blind_light -= 20;
}
for (j = i + opaque / 2; j < i + opaque; j++)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1,
blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = min(ox, x);
update_rect->y = 0;
update_rect->w = canvas->w - update_rect->x;
update_rect->h = canvas->h;
api->playsound(blind_snd, (x * 255) / canvas->w, 255);
break;
case BLIND_SIDE_LEFT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i >= 0; i -= BLIND_THICKNESS)
{
blind_light = 255;
for (j = i; j > i - opaque / 2; j--)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1,
blind_paint_blind);
blind_light -= 20;
}
for (j = i - opaque / 2; j > i - opaque; j--)
{
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1,
blind_paint_blind);
blind_light += 20;
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = max(ox, x);
update_rect->h = canvas->h;
api->playsound(blind_snd, (x * 255) / canvas->w, 255);
break;
}
}
void blind_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (y < canvas->h / 2)
{
if (x < y)
blind_side = BLIND_SIDE_LEFT;
else if (canvas->w - x < y)
blind_side = BLIND_SIDE_RIGHT;
else
blind_side = BLIND_SIDE_TOP;
}
{
if (x < y)
blind_side = BLIND_SIDE_LEFT;
else if (canvas->w - x < y)
blind_side = BLIND_SIDE_RIGHT;
else
blind_side = BLIND_SIDE_TOP;
}
else
{
if (x < canvas->h - y)
blind_side = BLIND_SIDE_LEFT;
else if (canvas->w - x < canvas->h - y)
blind_side = BLIND_SIDE_RIGHT;
else
blind_side = BLIND_SIDE_BOTTOM;
}
{
if (x < canvas->h - y)
blind_side = BLIND_SIDE_LEFT;
else if (canvas->w - x < canvas->h - y)
blind_side = BLIND_SIDE_RIGHT;
else
blind_side = BLIND_SIDE_BOTTOM;
}
blind_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void blind_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void blind_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void blind_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void blind_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{

View file

@ -60,18 +60,25 @@ SDL_Surface *blocks_chalk_drip_get_icon(magic_api * api, int which);
char *blocks_chalk_drip_get_name(magic_api * api, int which);
int blocks_chalk_drip_get_group(magic_api * api, int which);
char *blocks_chalk_drip_get_description(magic_api * api, int which, int mode);
static void blocks_chalk_drip_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void blocks_chalk_drip_linecb(void *ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void blocks_chalk_drip_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x,
int y, SDL_Rect * update_rect);
void blocks_chalk_drip_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect);
void blocks_chalk_drip_shutdown(magic_api * api);
void blocks_chalk_drip_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int blocks_chalk_drip_requires_colors(magic_api * api, int which);
void blocks_chalk_drip_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blocks_chalk_drip_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blocks_chalk_drip_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void blocks_chalk_drip_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int blocks_chalk_drip_modes(magic_api * api, int which);
@ -80,13 +87,16 @@ int blocks_chalk_drip_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/blocks.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/blocks.wav",
api->data_directory);
snd_effect[0] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/chalk.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/chalk.wav",
api->data_directory);
snd_effect[1] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/drip.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/drip.wav",
api->data_directory);
snd_effect[2] = Mix_LoadWAV(fname);
return (1);
@ -110,17 +120,20 @@ SDL_Surface *blocks_chalk_drip_get_icon(magic_api * api, int which)
char fname[1024];
if (which == TOOL_BLOCKS)
{
snprintf(fname, sizeof(fname), "%simages/magic/blocks.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/blocks.png",
api->data_directory);
}
else if (which == TOOL_CHALK)
{
snprintf(fname, sizeof(fname), "%simages/magic/chalk.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/chalk.png",
api->data_directory);
}
else if (which == TOOL_DRIP)
{
snprintf(fname, sizeof(fname), "%simages/magic/drip.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/drip.png",
api->data_directory);
}
return (IMG_Load(fname));
}
@ -139,54 +152,67 @@ char *blocks_chalk_drip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (all the same):
int blocks_chalk_drip_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int blocks_chalk_drip_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *blocks_chalk_drip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *blocks_chalk_drip_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which, int mode)
{
if (which == TOOL_BLOCKS)
{
if (mode == MODE_PAINT)
{
if (mode == MODE_PAINT)
{
return (strdup(gettext_noop("Click and drag the mouse around to make the picture blocky.")));
}
else
{
return (strdup(gettext_noop("Click to make the entire picture blocky.")));
}
return (strdup
(gettext_noop
("Click and drag the mouse around to make the picture blocky.")));
}
else
{
return (strdup
(gettext_noop("Click to make the entire picture blocky.")));
}
}
else if (which == TOOL_CHALK)
{
if (mode == MODE_PAINT)
{
if (mode == MODE_PAINT)
{
return (strdup(gettext_noop("Click and drag the mouse around to turn the picture into a chalk drawing.")));
}
else
{
return (strdup(gettext_noop("Click to turn the entire picture into a chalk drawing.")));
}
return (strdup
(gettext_noop
("Click and drag the mouse around to turn the picture into a chalk drawing.")));
}
else
{
return (strdup
(gettext_noop
("Click to turn the entire picture into a chalk drawing.")));
}
}
else if (which == TOOL_DRIP)
{
if (mode == MODE_PAINT)
{
if (mode == MODE_PAINT)
{
return (strdup(gettext_noop("Click and drag the mouse around to make the picture drip.")));
}
else
{
return (strdup(gettext_noop("Click to make the entire picture drip.")));
}
return (strdup
(gettext_noop
("Click and drag the mouse around to make the picture drip.")));
}
else
{
return (strdup(gettext_noop("Click to make the entire picture drip.")));
}
}
return (NULL);
}
// Do the effect:
static void blocks_chalk_drip_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void blocks_chalk_drip_linecb(void *ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
@ -196,125 +222,136 @@ static void blocks_chalk_drip_linecb(void *ptr, int which, SDL_Surface * canvas,
Uint32 colr;
if (which == TOOL_BLOCKS)
{
/* Put x/y on exact grid points: */
x = (x / EFFECT_REZ) * EFFECT_REZ;
y = (y / EFFECT_REZ) * EFFECT_REZ;
if (!api->touched(x, y))
{
/* Put x/y on exact grid points: */
x = (x / EFFECT_REZ) * EFFECT_REZ;
y = (y / EFFECT_REZ) * EFFECT_REZ;
if (!api->touched(x, y))
for (yy = y - (EFFECT_REZ * 2); yy < y + (EFFECT_REZ * 2);
yy = yy + EFFECT_REZ)
{
for (xx = x - (EFFECT_REZ * 2); xx < x + (EFFECT_REZ * 2);
xx = xx + EFFECT_REZ)
{
for (yy = y - (EFFECT_REZ * 2); yy < y + (EFFECT_REZ * 2); yy = yy + EFFECT_REZ)
Uint32 pix[(EFFECT_REZ * EFFECT_REZ)];
Uint32 p_or = 0;
Uint32 p_and = ~0;
unsigned i = (EFFECT_REZ * EFFECT_REZ);
while (i--)
{
Uint32 p_tmp;
p_tmp = api->getpixel(last, xx + (i >> 2), yy + (i & 3));
p_or |= p_tmp;
p_and &= p_tmp;
pix[i] = p_tmp;
}
if (p_or == p_and) // if all pixels the same already
{
SDL_GetRGB(p_or, last->format, &r, &g, &b);
}
else // nope, must average them
{
double r_sum = 0.0;
double g_sum = 0.0;
double b_sum = 0.0;
i = (EFFECT_REZ * EFFECT_REZ);
while (i--)
{
for (xx = x - (EFFECT_REZ * 2); xx < x + (EFFECT_REZ * 2); xx = xx + EFFECT_REZ)
{
Uint32 pix[(EFFECT_REZ * EFFECT_REZ)];
Uint32 p_or = 0;
Uint32 p_and = ~0;
unsigned i = (EFFECT_REZ * EFFECT_REZ);
while (i--)
{
Uint32 p_tmp;
p_tmp = api->getpixel(last, xx + (i >> 2), yy + (i & 3));
p_or |= p_tmp;
p_and &= p_tmp;
pix[i] = p_tmp;
}
if (p_or == p_and) // if all pixels the same already
{
SDL_GetRGB(p_or, last->format, &r, &g, &b);
}
else // nope, must average them
{
double r_sum = 0.0;
double g_sum = 0.0;
double b_sum = 0.0;
i = (EFFECT_REZ * EFFECT_REZ);
while (i--)
{
SDL_GetRGB(pix[i], last->format, &r, &g, &b);
r_sum += api->sRGB_to_linear(r);
g_sum += api->sRGB_to_linear(g);
b_sum += api->sRGB_to_linear(b);
}
r = api->linear_to_sRGB(r_sum / (float) (EFFECT_REZ * EFFECT_REZ));
g = api->linear_to_sRGB(g_sum / (float) (EFFECT_REZ * EFFECT_REZ));
b = api->linear_to_sRGB(b_sum / (float) (EFFECT_REZ * EFFECT_REZ));
}
/* Draw block: */
dest.x = xx;
dest.y = yy;
dest.w = EFFECT_REZ;
dest.h = EFFECT_REZ;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, r, g, b));
}
SDL_GetRGB(pix[i], last->format, &r, &g, &b);
r_sum += api->sRGB_to_linear(r);
g_sum += api->sRGB_to_linear(g);
b_sum += api->sRGB_to_linear(b);
}
r =
api->linear_to_sRGB(r_sum / (float) (EFFECT_REZ * EFFECT_REZ));
g =
api->linear_to_sRGB(g_sum / (float) (EFFECT_REZ * EFFECT_REZ));
b =
api->linear_to_sRGB(b_sum / (float) (EFFECT_REZ * EFFECT_REZ));
}
/* Draw block: */
dest.x = xx;
dest.y = yy;
dest.w = EFFECT_REZ;
dest.h = EFFECT_REZ;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
else if (which == TOOL_CHALK)
{
for (yy = y - (EFFECT_REZ * 2); yy <= y + (EFFECT_REZ * 2);
yy = yy + EFFECT_REZ)
{
for (yy = y - (EFFECT_REZ * 2); yy <= y + (EFFECT_REZ * 2); yy = yy + EFFECT_REZ)
{
for (xx = x - (EFFECT_REZ * 2); xx <= x + (EFFECT_REZ * 2); xx = xx + EFFECT_REZ)
{
dest.x = xx + ((rand() % (EFFECT_REZ + 1)) - (EFFECT_REZ / 2));
dest.y = yy + ((rand() % (EFFECT_REZ + 1)) - (EFFECT_REZ / 2));
dest.w = (rand() % EFFECT_REZ) + (EFFECT_REZ / 2);
dest.h = (rand() % EFFECT_REZ) + (EFFECT_REZ / 2);
for (xx = x - (EFFECT_REZ * 2); xx <= x + (EFFECT_REZ * 2);
xx = xx + EFFECT_REZ)
{
dest.x = xx + ((rand() % (EFFECT_REZ + 1)) - (EFFECT_REZ / 2));
dest.y = yy + ((rand() % (EFFECT_REZ + 1)) - (EFFECT_REZ / 2));
dest.w = (rand() % EFFECT_REZ) + (EFFECT_REZ / 2);
dest.h = (rand() % EFFECT_REZ) + (EFFECT_REZ / 2);
colr = api->getpixel(last, clamp(0, xx, canvas->w - 1), clamp(0, yy, canvas->h - 1));
SDL_FillRect(canvas, &dest, colr);
}
}
colr =
api->getpixel(last, clamp(0, xx, canvas->w - 1),
clamp(0, yy, canvas->h - 1));
SDL_FillRect(canvas, &dest, colr);
}
}
}
else if (which == TOOL_DRIP)
{
for (xx = x - 8; xx <= x + 8; xx++)
{
for (xx = x - 8; xx <= x + 8; xx++)
{
h = (rand() % 8) + 8;
h = (rand() % 8) + 8;
for (yy = y; yy <= y + h; yy++)
{
src.x = xx;
src.y = y;
src.w = 1;
src.h = 16;
for (yy = y; yy <= y + h; yy++)
{
src.x = xx;
src.y = y;
src.w = 1;
src.h = 16;
dest.x = xx;
dest.y = yy;
dest.x = xx;
dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
}
}
// Affect the canvas on drag:
void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, blocks_chalk_drip_linecb);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
blocks_chalk_drip_linecb);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -326,28 +363,41 @@ void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void blocks_chalk_drip_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x,
int y, SDL_Rect * update_rect)
{
if (mode == MODE_PAINT) {
if (mode == MODE_PAINT)
{
blocks_chalk_drip_drag(api, which, canvas, last, x, y, x, y, update_rect);
} else /* MODE_FULLSCREEN */ {
if (which != TOOL_DRIP) {
for (y = 0; y < canvas->h; y += EFFECT_REZ) {
if (y % 10 == 0) {
}
else /* MODE_FULLSCREEN */
{
if (which != TOOL_DRIP)
{
for (y = 0; y < canvas->h; y += EFFECT_REZ)
{
if (y % 10 == 0)
{
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x += EFFECT_REZ) {
for (x = 0; x < canvas->w; x += EFFECT_REZ)
{
blocks_chalk_drip_linecb(api, which, canvas, last, x, y);
}
}
} else {
}
else
{
/* Drip (works from bottom-to-top) */
int p = (canvas->h -1) % 10;
for (y = canvas->h -1; y >= 0; y -= EFFECT_REZ) {
if ((y + p) % 10 == 0) {
int p = (canvas->h - 1) % 10;
for (y = canvas->h - 1; y >= 0; y -= EFFECT_REZ)
{
if ((y + p) % 10 == 0)
{
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x += EFFECT_REZ) {
for (x = 0; x < canvas->w; x += EFFECT_REZ)
{
blocks_chalk_drip_linecb(api, which, canvas, last, x, y);
}
}
@ -362,9 +412,12 @@ void blocks_chalk_drip_click(magic_api * api, int which, int mode,
}
// Affect the canvas on release:
void blocks_chalk_drip_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void blocks_chalk_drip_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -380,31 +433,41 @@ void blocks_chalk_drip_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Record the color from Tux Paint:
void blocks_chalk_drip_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 r ATTRIBUTE_UNUSED,
Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int blocks_chalk_drip_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int blocks_chalk_drip_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void blocks_chalk_drip_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void blocks_chalk_drip_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void blocks_chalk_drip_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void blocks_chalk_drip_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int blocks_chalk_drip_modes(magic_api * api ATTRIBUTE_UNUSED, int which)
{
if (which == TOOL_BLOCKS || TOOL_CHALK) {
if (which == TOOL_BLOCKS || TOOL_CHALK)
{
return (MODE_PAINT | MODE_FULLSCREEN);
} else /* TOOL_DRIP */ {
}
else /* TOOL_DRIP */
{
return (MODE_PAINT);
}
}

View file

@ -47,16 +47,19 @@ char *blur_get_name(magic_api * api, int which);
int blur_get_group(magic_api * api, int which);
char *blur_get_description(magic_api * api, int which, int mode);
void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void blur_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void blur_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void blur_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void blur_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void blur_shutdown(magic_api * api);
void blur_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int blur_requires_colors(magic_api * api, int which);
void blur_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blur_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blur_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void blur_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int blur_modes(magic_api * api, int which);
enum
@ -103,10 +106,11 @@ int blur_init(magic_api * api)
char fname[1024];
for (i = 0; i < blur_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, blur_snd_filenames[i]);
blur_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
blur_snd_filenames[i]);
blur_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -120,7 +124,8 @@ SDL_Surface *blur_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, blur_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
blur_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -137,13 +142,16 @@ int blur_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *blur_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *blur_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(blur_descs[which][mode - 1])));
}
//Do the effect for one pixel
static void do_blur_pixel(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_blur_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
int i, j, k;
@ -159,89 +167,98 @@ static void do_blur_pixel(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
};
for (k = 0; k < 3; k++)
{
blurValue[k] = 0;
}
{
blurValue[k] = 0;
}
for (i = -2; i < 3; i++)
{
for (j = -2; j < 3; j++)
{
for (j = -2; j < 3; j++)
{
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0],
&temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
}
for (k = 0; k < 3; k++)
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2]));
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, blurValue[0], blurValue[1],
blurValue[2]));
}
// Do the effect for the full image
static void do_blur_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
static void do_blur_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which)
{
magic_api * api = (magic_api *) ptr;
magic_api *api = (magic_api *) ptr;
int x, y;
for (y = 0; y < last->h; y++)
{
if (y % 10 == 0)
{
if (y % 10 == 0) {
api->update_progress_bar();
}
for (x = 0; x < last->w; x++)
{
do_blur_pixel(api, which, canvas, last, x, y);
}
api->update_progress_bar();
}
for (x = 0; x < last->w; x++)
{
do_blur_pixel(api, which, canvas, last, x, y);
}
}
}
//do the effect for the brush
static void do_blur_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_blur_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - blur_RADIUS; yy < y + blur_RADIUS; yy++)
{
for (xx = x - blur_RADIUS; xx < x + blur_RADIUS; xx++)
{
for (xx = x - blur_RADIUS; xx < x + blur_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, blur_RADIUS) && !api->touched(xx, yy))
{
do_blur_pixel(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, blur_RADIUS)
&& !api->touched(xx, yy))
{
do_blur_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag:
void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_blur_brush);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_blur_brush);
api->playsound(blur_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - blur_RADIUS;
update_rect->y = oy - blur_RADIUS;
@ -251,25 +268,29 @@ void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void blur_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
blur_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_blur_full(api, canvas, last, which);
api->playsound(blur_snd_effect[which], 128, 255);
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_blur_full(api, canvas, last, which);
api->playsound(blur_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void blur_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void blur_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -280,32 +301,36 @@ void blur_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < blur_NUM_TOOLS; i++)
{
if (blur_snd_effect[i] != NULL)
{
if (blur_snd_effect[i] != NULL)
{
Mix_FreeChunk(blur_snd_effect[i]);
}
Mix_FreeChunk(blur_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void blur_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void blur_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int blur_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int blur_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void blur_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void blur_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void blur_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void blur_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -54,7 +54,8 @@ static Uint8 bricks_r, bricks_g, bricks_b;
/* Local function prototype: */
static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y, int w, int h);
static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y,
int w, int h);
int bricks_init(magic_api * api);
Uint32 bricks_api_version(void);
int bricks_get_tool_count(magic_api * api);
@ -63,15 +64,18 @@ char *bricks_get_name(magic_api * api, int which);
int bricks_get_group(magic_api * api, int which);
char *bricks_get_description(magic_api * api, int which, int mode);
void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void bricks_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void bricks_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void bricks_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect); //An empty function. Is there a purpose to this? Ask moderator.
void bricks_shutdown(magic_api * api);
void bricks_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int bricks_requires_colors(magic_api * api, int which);
void bricks_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void bricks_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void bricks_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void bricks_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int bricks_modes(magic_api * api, int which);
// No setup required:
@ -79,7 +83,8 @@ int bricks_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/brick.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/brick.wav",
api->data_directory);
brick_snd = Mix_LoadWAV(fname);
return (1);
@ -102,19 +107,22 @@ SDL_Surface *bricks_get_icon(magic_api * api, int which)
char fname[1024];
if (which == TOOL_LARGEBRICKS)
{
snprintf(fname, sizeof(fname), "%simages/magic/largebrick.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/largebrick.png",
api->data_directory);
}
else if (which == TOOL_SMALLBRICKS)
{
snprintf(fname, sizeof(fname), "%simages/magic/smallbrick.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/smallbrick.png",
api->data_directory);
}
return (IMG_Load(fname));
}
// Return our names, localized:
char *bricks_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *bricks_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
/* Both are named "Bricks", at the moment: */
@ -122,13 +130,15 @@ char *bricks_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUS
}
// Return our group (both the same):
int bricks_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int bricks_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *bricks_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *bricks_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (which == TOOL_LARGEBRICKS)
return (strdup(gettext_noop("Click and drag to draw large bricks.")));
@ -140,7 +150,8 @@ char *bricks_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mo
// Do the effect:
static void do_bricks(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
static void do_bricks(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -160,12 +171,12 @@ static void do_bricks(void *ptr, int which, SDL_Surface * canvas, SDL_Surface *
unsigned char *mybrick;
if (which == TOOL_LARGEBRICKS)
{
vertical_joint = 4; // between a brick and the one above/below
horizontal_joint = 4; // between a brick and the one to the side
nominal_width = 36;
nominal_height = 24; // 11 to 14, for joints of 2
}
{
vertical_joint = 4; // between a brick and the one above/below
horizontal_joint = 4; // between a brick and the one to the side
nominal_width = 36;
nominal_height = 24; // 11 to 14, for joints of 2
}
nominal_length = 2 * nominal_width;
specified_width = nominal_width - horizontal_joint;
@ -173,79 +184,82 @@ static void do_bricks(void *ptr, int which, SDL_Surface * canvas, SDL_Surface *
specified_length = nominal_length - horizontal_joint;
if (!api->button_down())
{
if (map)
free(map);
// the "+ 3" allows for both ends and misalignment
x_count = (canvas->w + nominal_width - 1) / nominal_width + 3;
y_count = (canvas->h + nominal_height - 1) / nominal_height + 3;
map = calloc(x_count, y_count);
}
{
if (map)
free(map);
// the "+ 3" allows for both ends and misalignment
x_count = (canvas->w + nominal_width - 1) / nominal_width + 3;
y_count = (canvas->h + nominal_height - 1) / nominal_height + 3;
map = calloc(x_count, y_count);
}
brick_x = x / nominal_width;
brick_y = y / nominal_height;
mybrick = map + brick_x + 1 + (brick_y + 1) * x_count;
if ((unsigned)x < (unsigned)canvas->w && (unsigned)y < (unsigned)canvas->h && !*mybrick)
if ((unsigned) x < (unsigned) canvas->w
&& (unsigned) y < (unsigned) canvas->h && !*mybrick)
{
int my_x = brick_x * nominal_width;
int my_w = specified_width;
*mybrick = 1;
// FIXME:
//SDL_LockSurface(canvas);
if ((brick_y ^ brick_x) & 1)
{
int my_x = brick_x * nominal_width;
int my_w = specified_width;
*mybrick = 1;
// FIXME:
//SDL_LockSurface(canvas);
if ((brick_y ^ brick_x) & 1)
{
if (mybrick[1])
my_w = specified_length;
}
else if (mybrick[-1])
{
my_x -= nominal_width;
my_w = specified_length;
}
do_brick(api, canvas, my_x, brick_y * nominal_height, my_w, specified_height);
// FIXME:
// SDL_UnlockSurface(canvas);
// upper left corner and lower right corner
// FIXME
/*
update_canvas(brick_x * nominal_width - nominal_width,
brick_y * nominal_height - vertical_joint,
brick_x * nominal_width + specified_length,
(brick_y + 1) * nominal_height);
*/
if (mybrick[1])
my_w = specified_length;
}
else if (mybrick[-1])
{
my_x -= nominal_width;
my_w = specified_length;
}
do_brick(api, canvas, my_x, brick_y * nominal_height, my_w,
specified_height);
// FIXME:
// SDL_UnlockSurface(canvas);
// upper left corner and lower right corner
// FIXME
/*
update_canvas(brick_x * nominal_width - nominal_width,
brick_y * nominal_height - vertical_joint,
brick_x * nominal_width + specified_length,
(brick_y + 1) * nominal_height);
*/
}
}
// Affect the canvas on drag:
void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_bricks);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_bricks);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = x - 64;
update_rect->y = y - 64;
@ -257,14 +271,18 @@ void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void bricks_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
bricks_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void bricks_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void bricks_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -276,7 +294,8 @@ void bricks_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void bricks_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void bricks_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
bricks_r = r;
bricks_g = g;
@ -284,21 +303,29 @@ void bricks_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8
}
// Use colors:
int bricks_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int bricks_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y, int w, int h)
static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y,
int w, int h)
{
SDL_Rect dest;
// brick color: 127,76,73
double ran_r = rand() / (double)RAND_MAX;
double ran_g = rand() / (double)RAND_MAX;
double base_r = api->sRGB_to_linear(bricks_r) * 1.5 + api->sRGB_to_linear(127) * 5.0 + ran_r;
double base_g = api->sRGB_to_linear(bricks_g) * 1.5 + api->sRGB_to_linear(76) * 5.0 + ran_g;
double base_b = api->sRGB_to_linear(bricks_b) * 1.5 + api->sRGB_to_linear(73) * 5.0 + (ran_r + ran_g * 2.0) / 3.0;
double ran_r = rand() / (double) RAND_MAX;
double ran_g = rand() / (double) RAND_MAX;
double base_r =
api->sRGB_to_linear(bricks_r) * 1.5 + api->sRGB_to_linear(127) * 5.0 +
ran_r;
double base_g =
api->sRGB_to_linear(bricks_g) * 1.5 + api->sRGB_to_linear(76) * 5.0 +
ran_g;
double base_b =
api->sRGB_to_linear(bricks_b) * 1.5 + api->sRGB_to_linear(73) * 5.0 +
(ran_r + ran_g * 2.0) / 3.0;
Uint8 r = api->linear_to_sRGB(base_r / 7.5);
Uint8 g = api->linear_to_sRGB(base_g / 7.5);
@ -318,13 +345,15 @@ static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y, int w,
api->playsound(brick_snd, (x * 255) / canvas->w, 255);
}
void bricks_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void bricks_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void bricks_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void bricks_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -50,7 +50,8 @@ static SDL_Surface *calligraphy_brush, *calligraphy_colored_brush;
/* Local Function Prototypes */
static Point2D calligraphy_PointOnCubicBezier(Point2D * cp, float t);
static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve);
static float calligraphy_dist(float x1, float y1, float x2, float y2);
int calligraphy_init(magic_api * api);
Uint32 calligraphy_api_version(void);
@ -60,16 +61,21 @@ char *calligraphy_get_name(magic_api * api, int which);
int calligraphy_get_group(magic_api * api, int which);
char *calligraphy_get_description(magic_api * api, int which, int mode);
void calligraphy_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void calligraphy_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void calligraphy_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void calligraphy_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void calligraphy_shutdown(magic_api * api);
void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int calligraphy_requires_colors(magic_api * api, int which);
void calligraphy_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void calligraphy_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void calligraphy_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void calligraphy_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int calligraphy_modes(magic_api * api, int which);
// No setup required:
@ -77,11 +83,13 @@ int calligraphy_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/calligraphy.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/calligraphy.ogg",
api->data_directory);
calligraphy_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%simages/magic/calligraphy_brush.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/calligraphy_brush.png",
api->data_directory);
calligraphy_brush = IMG_Load(fname);
calligraphy_colored_brush = NULL;
@ -115,32 +123,40 @@ SDL_Surface *calligraphy_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/calligraphy.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/calligraphy.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our name, localized:
char *calligraphy_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *calligraphy_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Calligraphy")));
}
// Return our group
int calligraphy_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int calligraphy_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our description, localized:
char *calligraphy_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
char *calligraphy_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag the mouse around to draw in calligraphy.")));
return (strdup
(gettext_noop
("Click and drag the mouse around to draw in calligraphy.")));
}
void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Rect * update_rect)
void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy,
int x, int y, SDL_Rect * update_rect)
{
Point2D *curve;
int i, n_points, thick, new_thick;
@ -180,7 +196,9 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
calligraphy_control_points[2].x,
calligraphy_control_points[2].y) +
calligraphy_dist(calligraphy_control_points[2].x,
calligraphy_control_points[2].y, calligraphy_control_points[3].x, calligraphy_control_points[3].y);
calligraphy_control_points[2].y,
calligraphy_control_points[3].x,
calligraphy_control_points[3].y);
if (n_points == 0)
return; // No-op; not any points to plot
@ -193,36 +211,37 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
new_thick = 40 - min((n_points /* / 2 */ ), 32);
for (i = 0; i < n_points - 1; i++)
{
thick = ((new_thick * i) + (calligraphy_old_thick * (n_points - i))) / n_points;
{
thick =
((new_thick * i) + (calligraphy_old_thick * (n_points - i))) / n_points;
/* The new way, using an antialiased brush bitmap */
/* The new way, using an antialiased brush bitmap */
x = curve[i].x;
y = curve[i].y;
x = curve[i].x;
y = curve[i].y;
src.x = calligraphy_brush->w - thick / 2 - thick / 4;
src.w = thick / 2 + thick / 4;
src.y = 0;
src.h = thick / 4;
src.x = calligraphy_brush->w - thick / 2 - thick / 4;
src.w = thick / 2 + thick / 4;
src.y = 0;
src.h = thick / 4;
dest.x = x - thick / 4;
dest.y = y - thick / 4;
dest.x = x - thick / 4;
dest.y = y - thick / 4;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
src.x = 0;
src.w = thick / 2 + thick / 4;
src.y = calligraphy_brush->h - thick / 4;
src.h = thick / 4;
src.x = 0;
src.w = thick / 2 + thick / 4;
src.y = calligraphy_brush->h - thick / 4;
src.h = thick / 4;
dest.x = x - thick / 2;
dest.y = y;
dest.x = x - thick / 2;
dest.y = y;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
}
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
}
calligraphy_old_thick = (calligraphy_old_thick + new_thick) / 2;
@ -231,19 +250,19 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -260,9 +279,11 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
api->playsound(calligraphy_snd, (x * 255) / canvas->w, 255);
}
void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
calligraphy_old_thick = 8;
calligraphy_last_time = 0;
@ -278,9 +299,12 @@ void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
}
void calligraphy_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void calligraphy_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -312,7 +336,9 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
if (calligraphy_colored_brush != NULL)
SDL_FreeSurface(calligraphy_colored_brush);
amask = ~(calligraphy_brush->format->Rmask | calligraphy_brush->format->Gmask | calligraphy_brush->format->Bmask);
amask =
~(calligraphy_brush->format->Rmask | calligraphy_brush->format->
Gmask | calligraphy_brush->format->Bmask);
calligraphy_colored_brush =
SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -320,7 +346,8 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
calligraphy_brush->h,
calligraphy_brush->format->BitsPerPixel,
calligraphy_brush->format->Rmask,
calligraphy_brush->format->Gmask, calligraphy_brush->format->Bmask, amask);
calligraphy_brush->format->Gmask,
calligraphy_brush->format->Bmask, amask);
if (calligraphy_colored_brush == NULL)
return; // FIXME: Error!
@ -330,22 +357,26 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
for (y = 0; y < calligraphy_brush->h; y++)
{
for (x = 0; x < calligraphy_brush->w; x++)
{
for (x = 0; x < calligraphy_brush->w; x++)
{
SDL_GetRGBA(api->getpixel(calligraphy_brush, x, y), calligraphy_brush->format, &r, &g, &b, &a);
SDL_GetRGBA(api->getpixel(calligraphy_brush, x, y),
calligraphy_brush->format, &r, &g, &b, &a);
api->putpixel(calligraphy_colored_brush, x, y,
SDL_MapRGBA(calligraphy_colored_brush->format, calligraphy_r, calligraphy_g, calligraphy_b, a));
}
api->putpixel(calligraphy_colored_brush, x, y,
SDL_MapRGBA(calligraphy_colored_brush->format,
calligraphy_r, calligraphy_g, calligraphy_b,
a));
}
}
SDL_UnlockSurface(calligraphy_colored_brush);
SDL_UnlockSurface(calligraphy_brush);
}
// We don't use colors
int calligraphy_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int calligraphy_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
@ -400,7 +431,8 @@ static Point2D calligraphy_PointOnCubicBezier(Point2D * cp, float t)
<sizeof(Point2D) numberOfPoints>
*/
static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve)
{
float dt;
int i;
@ -420,17 +452,22 @@ static float calligraphy_dist(float x1, float y1, float x2, float y2)
return d;
}
void calligraphy_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void calligraphy_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void calligraphy_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void calligraphy_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int calligraphy_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int calligraphy_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -39,7 +39,7 @@
/* Our globals: */
static Mix_Chunk *cartoon_snd;
SDL_Surface * result_surf;
SDL_Surface *result_surf;
#define OUTLINE_THRESH 48
@ -51,20 +51,26 @@ SDL_Surface *cartoon_get_icon(magic_api * api, int which);
char *cartoon_get_name(magic_api * api, int which);
int cartoon_get_group(magic_api * api, int which);
char *cartoon_get_description(magic_api * api, int which, int mode);
void cartoon_apply_colors(magic_api * api, SDL_Surface * surf, int xx, int yy);
void cartoon_apply_colors(magic_api * api, SDL_Surface * surf, int xx,
int yy);
void cartoon_apply_outline(magic_api * api, int xx, int yy);
static void do_cartoon(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_cartoon(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void cartoon_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void cartoon_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void cartoon_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void cartoon_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void cartoon_shutdown(magic_api * api);
void cartoon_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int cartoon_requires_colors(magic_api * api, int which);
void cartoon_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void cartoon_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void cartoon_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void cartoon_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int cartoon_modes(magic_api * api, int which);
@ -74,7 +80,8 @@ int cartoon_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/cartoon.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/cartoon.wav",
api->data_directory);
cartoon_snd = Mix_LoadWAV(fname);
return (1);
@ -96,39 +103,48 @@ SDL_Surface *cartoon_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/cartoon.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/cartoon.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *cartoon_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *cartoon_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Cartoon")));
}
// Return our groups
int cartoon_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int cartoon_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_COLOR_FILTERS;
}
// Return our descriptions, localized:
char *cartoon_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *cartoon_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
{
return (strdup(gettext_noop("Click and drag the mouse around to turn the picture into a cartoon.")));
}
{
return (strdup
(gettext_noop
("Click and drag the mouse around to turn the picture into a cartoon.")));
}
else
{
return (strdup(gettext_noop("Click to turn the entire picture into a cartoon.")));
}
{
return (strdup
(gettext_noop
("Click to turn the entire picture into a cartoon.")));
}
}
// Do the effect:
void cartoon_apply_colors(magic_api * api, SDL_Surface * surf, int xx, int yy) {
void cartoon_apply_colors(magic_api * api, SDL_Surface * surf, int xx, int yy)
{
Uint8 r, g, b;
float hue, sat, val;
@ -149,69 +165,81 @@ void cartoon_apply_colors(magic_api * api, SDL_Surface * surf, int xx, int yy) {
sat = floor(sat * 4) / 4;
api->hsvtorgb(hue, sat, val, &r, &g, &b);
api->putpixel(result_surf, xx, yy, SDL_MapRGB(result_surf->format, r, g, b));
api->putpixel(result_surf, xx, yy,
SDL_MapRGB(result_surf->format, r, g, b));
}
void cartoon_apply_outline(magic_api * api, int xx, int yy) {
void cartoon_apply_outline(magic_api * api, int xx, int yy)
{
Uint8 r, g, b;
Uint8 r1, g1, b1, r2, g2, b2;
SDL_GetRGB(api->getpixel(result_surf, xx, yy), result_surf->format, &r, &g, &b);
SDL_GetRGB(api->getpixel(result_surf, xx + 1, yy), result_surf->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(result_surf, xx + 1, yy + 1), result_surf->format, &r2, &g2, &b2);
SDL_GetRGB(api->getpixel(result_surf, xx, yy), result_surf->format, &r, &g,
&b);
SDL_GetRGB(api->getpixel(result_surf, xx + 1, yy), result_surf->format, &r1,
&g1, &b1);
SDL_GetRGB(api->getpixel(result_surf, xx + 1, yy + 1), result_surf->format,
&r2, &g2, &b2);
if (abs(((r + g + b) / 3) - (r1 + g1 + b1) / 3) > OUTLINE_THRESH
|| abs(((r + g + b) / 3) - (r2 + g2 + b2) / 3) >
OUTLINE_THRESH || abs(r - r1) > OUTLINE_THRESH
|| abs(g - g1) > OUTLINE_THRESH
|| abs(b - b1) > OUTLINE_THRESH
|| abs(r - r2) > OUTLINE_THRESH || abs(g - g2) > OUTLINE_THRESH || abs(b - b2) > OUTLINE_THRESH)
{
api->putpixel(result_surf, xx - 1, yy, SDL_MapRGB(result_surf->format, 0, 0, 0));
api->putpixel(result_surf, xx, yy - 1, SDL_MapRGB(result_surf->format, 0, 0, 0));
api->putpixel(result_surf, xx - 1, yy - 1, SDL_MapRGB(result_surf->format, 0, 0, 0));
}
|| abs(r - r2) > OUTLINE_THRESH || abs(g - g2) > OUTLINE_THRESH
|| abs(b - b2) > OUTLINE_THRESH)
{
api->putpixel(result_surf, xx - 1, yy,
SDL_MapRGB(result_surf->format, 0, 0, 0));
api->putpixel(result_surf, xx, yy - 1,
SDL_MapRGB(result_surf->format, 0, 0, 0));
api->putpixel(result_surf, xx - 1, yy - 1,
SDL_MapRGB(result_surf->format, 0, 0, 0));
}
}
static void do_cartoon(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
static void do_cartoon(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
for (yy = y - 16; yy < y + 16; yy = yy + 1)
{
for (xx = x - 16; xx < x + 16; xx = xx + 1)
{
for (xx = x - 16; xx < x + 16; xx = xx + 1)
{
if (api->in_circle(xx - x, yy - y, 16))
{
api->putpixel(canvas, xx, yy, api->getpixel(result_surf, xx, yy));
}
}
if (api->in_circle(xx - x, yy - y, 16))
{
api->putpixel(canvas, xx, yy, api->getpixel(result_surf, xx, yy));
}
}
}
}
// Affect the canvas on drag:
void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_cartoon);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_cartoon);
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -223,51 +251,57 @@ void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void cartoon_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
for (y = 0; y < canvas->h; y++)
{
if (y % 10 == 0)
{
if (y % 10 == 0) {
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x++)
{
cartoon_apply_colors(api, last, x, y);
}
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x++)
{
cartoon_apply_colors(api, last, x, y);
}
}
for (y = 0; y < canvas->h; y++)
{
if (y % 10 == 0)
{
if (y % 10 == 0) {
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x++)
{
cartoon_apply_outline(api, x, y);
}
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x++)
{
cartoon_apply_outline(api, x, y);
}
}
if (mode == MODE_PAINT)
{
cartoon_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
{
cartoon_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
else
{
api->playsound(cartoon_snd, 128, 255);
{
api->playsound(cartoon_snd, 128, 255);
SDL_BlitSurface(result_surf, NULL, canvas, NULL);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
SDL_BlitSurface(result_surf, NULL, canvas, NULL);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
}
// Affect the canvas on release:
void cartoon_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void cartoon_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -279,39 +313,47 @@ void cartoon_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void cartoon_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void cartoon_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int cartoon_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int cartoon_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void cartoon_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void cartoon_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{
Uint32 amask;
amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
amask =
~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
result_surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
}
void cartoon_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void cartoon_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
if (result_surf != NULL)
SDL_FreeSurface(result_surf);
}
int cartoon_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int cartoon_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}

View file

@ -46,15 +46,22 @@ int checkerboard_get_group(magic_api * api, int which);
char *checkerboard_get_description(magic_api * api, int which, int mode);
int checkerboard_requires_colors(magic_api * api, int which);
void checkerboard_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void checkerboard_shutdown(magic_api * api);
void checkerboard_paint_checkerboard(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void checkerboard_paint_checkerboard(void *ptr_to_api, int which_tool,
SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void checkerboard_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void checkerboard_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void checkerboard_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void checkerboard_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * canvas, SDL_Surface * last, int x,
int y, SDL_Rect * update_rect);
void checkerboard_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void checkerboard_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int checkerboard_modes(magic_api * api, int which);
// Housekeeping functions
@ -64,7 +71,7 @@ Uint32 checkerboard_api_version(void)
return (TP_MAGIC_API_VERSION);
}
void checkerboard_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
void checkerboard_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
{
checkerboard_r = r;
checkerboard_g = g;
@ -75,7 +82,8 @@ int checkerboard_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/checkerboard.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/checkerboard.ogg",
api->data_directory);
checkerboard_snd = Mix_LoadWAV(fname);
return (1);
@ -86,40 +94,50 @@ int checkerboard_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1;
}
SDL_Surface *checkerboard_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
SDL_Surface *checkerboard_get_icon(magic_api * api,
int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/checkerboard.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/checkerboard.png",
api->data_directory);
return (IMG_Load(fname));
}
char *checkerboard_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *checkerboard_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Checkerboard"));
}
int checkerboard_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int checkerboard_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_DECORATIONS;
}
char *checkerboard_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *checkerboard_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return
strdup(gettext_noop
("Click and drag to fill the canvas with a checkerboard pattern."));
}
int checkerboard_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int checkerboard_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void checkerboard_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void checkerboard_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -130,10 +148,10 @@ void checkerboard_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Interactivity functions
void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * snapshot,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
{
int sz, xx, yy;
Uint8 draw_start, draw_row, draw_cell;
@ -142,9 +160,13 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
SDL_BlitSurface(snapshot, NULL, canvas, NULL);
sz = max(10, max(abs(x - checkerboard_start_x), abs(y - checkerboard_start_y)));
sz =
max(10,
max(abs(x - checkerboard_start_x), abs(y - checkerboard_start_y)));
colr = SDL_MapRGB(canvas->format, checkerboard_r, checkerboard_g, checkerboard_b);
colr =
SDL_MapRGB(canvas->format, checkerboard_r, checkerboard_g,
checkerboard_b);
draw_start = 1;
if (x < checkerboard_start_x)
@ -154,11 +176,14 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
/* From the mouse Y position down... */
draw_row = draw_start;
for (yy = checkerboard_start_y; yy <= canvas->h; yy += sz) {
for (yy = checkerboard_start_y; yy <= canvas->h; yy += sz)
{
/* From the mouse X position right... */
draw_cell = draw_row;
for (xx = checkerboard_start_x; xx <= canvas->w; xx += sz) {
if (draw_cell) {
for (xx = checkerboard_start_x; xx <= canvas->w; xx += sz)
{
if (draw_cell)
{
dest.x = xx;
dest.y = yy;
dest.w = sz;
@ -170,8 +195,10 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
/* From the mouse X position left... */
draw_cell = !draw_row;
for (xx = checkerboard_start_x - sz; xx > -sz; xx -= sz) {
if (draw_cell) {
for (xx = checkerboard_start_x - sz; xx > -sz; xx -= sz)
{
if (draw_cell)
{
dest.x = xx;
dest.y = yy;
dest.w = sz;
@ -186,11 +213,14 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
/* From the mouse Y position up... */
draw_row = !draw_start;
for (yy = checkerboard_start_y - sz; yy > -sz; yy -= sz) {
for (yy = checkerboard_start_y - sz; yy > -sz; yy -= sz)
{
/* From the mouse X position right... */
draw_cell = draw_row;
for (xx = checkerboard_start_x; xx <= canvas->w; xx += sz) {
if (draw_cell) {
for (xx = checkerboard_start_x; xx <= canvas->w; xx += sz)
{
if (draw_cell)
{
dest.x = xx;
dest.y = yy;
dest.w = sz;
@ -202,8 +232,10 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
/* From the mouse X position left... */
draw_cell = !draw_row;
for (xx = checkerboard_start_x - sz; xx > -sz; xx -= sz) {
if (draw_cell) {
for (xx = checkerboard_start_x - sz; xx > -sz; xx -= sz)
{
if (draw_cell)
{
dest.x = xx;
dest.y = yy;
dest.w = sz;
@ -225,27 +257,32 @@ void checkerboard_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface
api->playsound(checkerboard_snd, 128, 255);
}
void checkerboard_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y,
SDL_Rect * update_rect)
void checkerboard_click(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
checkerboard_start_x = x;
checkerboard_start_y = y;
checkerboard_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void checkerboard_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
void checkerboard_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void checkerboard_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
void checkerboard_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int checkerboard_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int checkerboard_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -59,7 +59,7 @@ static Mix_Chunk *clone_start_snd, *clone_snd;
int clone_state;
int clone_src_x, clone_src_y;
int clone_drag_start_x, clone_drag_start_y;
SDL_Surface * clone_last;
SDL_Surface *clone_last;
int clone_crosshair_visible;
@ -73,31 +73,38 @@ char *clone_get_name(magic_api * api, int which);
int clone_get_group(magic_api * api, int which);
char *clone_get_description(magic_api * api, int which, int mode);
void clone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect,
int crosshairs);
void clone_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void clone_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect, int crosshairs);
void clone_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void clone_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void clone_shutdown(magic_api * api);
void clone_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int clone_requires_colors(magic_api * api, int which);
void clone_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void clone_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void clone_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void clone_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int clone_modes(magic_api * api, int which);
void clone_crosshairs(magic_api * api, SDL_Surface * canvas, int x, int y);
void done_cloning(magic_api * api, SDL_Surface * canvas, SDL_Rect * update_rect);
void done_cloning(magic_api * api, SDL_Surface * canvas,
SDL_Rect * update_rect);
// No setup required:
int clone_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/clone_start.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/clone_start.ogg",
api->data_directory);
clone_start_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/clone.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/clone.ogg",
api->data_directory);
clone_snd = Mix_LoadWAV(fname);
clone_state = CLONE_READY_TO_START;
@ -122,34 +129,42 @@ SDL_Surface *clone_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/clone.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/clone.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *clone_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *clone_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Clone")));
}
// Return our groups:
int clone_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int clone_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *clone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *clone_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click once to pick a spot to begin cloning. Click again and drag to clone that part of the picture.")));
return (strdup
(gettext_noop
("Click once to pick a spot to begin cloning. Click again and drag to clone that part of the picture.")));
return (NULL);
}
// Do the effect:
static void do_clone(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_clone(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 r, g, b;
@ -161,25 +176,27 @@ static void do_clone(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas
srcy = clone_src_y + (y - clone_drag_start_y);
if (!api->touched(x, y))
{
for (yy = -16; yy < 16; yy++)
{
for (yy = -16; yy < 16; yy++)
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
SDL_GetRGB(api->getpixel(last, srcx + xx, srcy + yy), last->format, &r, &g, &b);
pixel = SDL_MapRGB(canvas->format, r, g, b);
api->putpixel(canvas, x + xx, y + yy, pixel);
}
}
SDL_GetRGB(api->getpixel(last, srcx + xx, srcy + yy), last->format,
&r, &g, &b);
pixel = SDL_MapRGB(canvas->format, r, g, b);
api->putpixel(canvas, x + xx, y + yy, pixel);
}
}
}
}
}
// Affect the canvas on drag:
void clone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x,
int y, SDL_Rect * update_rect)
{
/* Step 3 - Actively cloning (moving the mouse) */
@ -192,8 +209,8 @@ void clone_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect,
int crosshairs)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect, int crosshairs)
{
if (clone_state != CLONE_CLONING)
return;
@ -201,28 +218,29 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
clone_drag_start_x = ox;
clone_drag_start_y = oy;
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_clone);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_clone);
/* Move source position relative to mouse motion */
clone_src_x += (x - ox);
clone_src_y += (y - oy);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
if (crosshairs) {
if (crosshairs)
{
clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
/* FIXME be more clever */
update_rect->x = 0;
@ -230,7 +248,9 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
update_rect->w = canvas->w;
update_rect->h = canvas->h;
clone_crosshair_visible = 1;
} else {
}
else
{
update_rect->x = x - 64;
update_rect->y = y - 64;
update_rect->w = (ox + 128) - update_rect->x;
@ -242,9 +262,11 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void clone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (clone_state == CLONE_READY_TO_START) {
if (clone_state == CLONE_READY_TO_START)
{
/* Step 1 - Picking a source for the clone */
clone_src_x = x;
clone_src_y = y;
@ -260,47 +282,57 @@ void clone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
update_rect->y = y - 15;
update_rect->w = 32;
update_rect->h = 32;
} else if (clone_state == CLONE_CLONING) {
}
else if (clone_state == CLONE_CLONING)
{
/* Step 2 - Starting a clone (hopefully holding mouse down here) */
clone_doit(api, which, canvas, clone_last, x, y, x, y, update_rect, 0);
}
}
void clone_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect)
{
if (clone_state == CLONE_STARTING) {
if (clone_state == CLONE_STARTING)
{
/* Release of the initial click (to pick initial source position);
now ready for second click (to begin cloning) */
clone_state = CLONE_CLONING;
} else {
}
else
{
done_cloning(api, canvas, update_rect);
}
}
void done_cloning(magic_api * api, SDL_Surface * canvas, SDL_Rect * update_rect) {
void done_cloning(magic_api * api, SDL_Surface * canvas,
SDL_Rect * update_rect)
{
/* Done cloning! */
/* Erase crosshairs from source position, now that we're all done */
if (clone_crosshair_visible)
{
clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
update_rect->x = clone_src_x - 15;
update_rect->y = clone_src_y - 15;
update_rect->w = 32;
update_rect->h = 32;
clone_crosshair_visible = 0;
}
{
clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
update_rect->x = clone_src_x - 15;
update_rect->y = clone_src_y - 15;
update_rect->w = 32;
update_rect->h = 32;
clone_crosshair_visible = 0;
}
clone_state = CLONE_READY_TO_START;
api->stopsound();
}
void clone_crosshairs(magic_api * api, SDL_Surface * canvas, int x, int y) {
void clone_crosshairs(magic_api * api, SDL_Surface * canvas, int x, int y)
{
int i;
for (i = -15; i < 16; i++) {
for (i = -15; i < 16; i++)
{
api->xorpixel(canvas, x + i, y);
api->xorpixel(canvas, x, y + i);
}
@ -314,29 +346,35 @@ void clone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(clone_start_snd);
}
void clone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 ATTRIBUTE_UNUSED r, Uint8 ATTRIBUTE_UNUSED g, Uint8 ATTRIBUTE_UNUSED b)
void clone_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 ATTRIBUTE_UNUSED r, Uint8 ATTRIBUTE_UNUSED g,
Uint8 ATTRIBUTE_UNUSED b)
{
}
int clone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int clone_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void clone_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void clone_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
clone_last = SDL_CreateRGBSurface(0, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
clone_last =
SDL_CreateRGBSurface(0, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
clone_state = CLONE_READY_TO_START;
}
void clone_switchout(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
SDL_Rect update_rect; /* Needed to satisfy done_cloning() :-( */
SDL_Rect update_rect; /* Needed to satisfy done_cloning() :-( */
done_cloning(api, canvas, &update_rect);

View file

@ -33,21 +33,26 @@ int confetti_get_group(magic_api * api, int which);
char *confetti_get_description(magic_api * api, int which, int mode);
int confetti_requires_colors(magic_api * api, int which);
void confetti_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void confetti_shutdown(magic_api * api);
inline char confetti_get_greater(const char what1, const char what2);
inline char confetti_get_lesser(const char what1, const char what2);
Uint32 confetti_get_new_color(void *ptr, SDL_Surface * canvas);
void confetti_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void confetti_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void confetti_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void confetti_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void confetti_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int confetti_modes(magic_api * api, int which);
// Housekeeping functions
void confetti_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
Uint32 confetti_api_version(void)
{
@ -65,7 +70,8 @@ int confetti_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/confetti.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/confetti.ogg",
api->data_directory);
confetti_snd = Mix_LoadWAV(fname);
return (1);
@ -80,34 +86,43 @@ SDL_Surface *confetti_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/confetti.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/confetti.png",
api->data_directory);
return (IMG_Load(fname));
}
char *confetti_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *confetti_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Confetti"));
}
int confetti_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int confetti_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
char *confetti_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *confetti_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click to throw confetti!"));
}
int confetti_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int confetti_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void confetti_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void confetti_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -160,48 +175,52 @@ Uint32 confetti_get_new_color(void *ptr, SDL_Surface * canvas) //this function
static void confetti_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
Uint32 color = confetti_get_new_color(api, canvas);
for (yy = y - CONFETTI_BRUSH_SIZE / 2; yy < y + CONFETTI_BRUSH_SIZE / 2; yy++)
for (yy = y - CONFETTI_BRUSH_SIZE / 2; yy < y + CONFETTI_BRUSH_SIZE / 2;
yy++)
for (xx = x - CONFETTI_BRUSH_SIZE / 2; xx < x + CONFETTI_BRUSH_SIZE / 2; xx++)
for (xx = x - CONFETTI_BRUSH_SIZE / 2; xx < x + CONFETTI_BRUSH_SIZE / 2;
xx++)
if (api->in_circle(xx - x, yy - y, CONFETTI_BRUSH_SIZE / 2))
api->putpixel(canvas, xx, yy, color);
}
void confetti_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
unsigned char i;
char min_x = 0, max_x = 0, min_y = 0, max_y = 0;
char dx = 0, dy = 0;
for (i = 0; i < CONFETTI_QUANTITY; i++)
{
srand((dx + dy) / 2 + time(0)); //to get a unique seed even if dx and dy aren't defined
dx = (rand() % 100) - 50; //generate a value between <-50; +50>
dy = (rand() % 100) - 50; //to spread confetti around the cursor position
{
srand((dx + dy) / 2 + time(0)); //to get a unique seed even if dx and dy aren't defined
dx = (rand() % 100) - 50; //generate a value between <-50; +50>
dy = (rand() % 100) - 50; //to spread confetti around the cursor position
if (!i)
{
min_x = max_x = dx;
min_y = max_y = dy;
}
else
{
min_x = confetti_get_lesser(min_x, dx); //any candidates to new min/max values? Hands up please...
max_x = confetti_get_greater(max_x, dx);
min_y = confetti_get_lesser(min_y, dy);
max_y = confetti_get_greater(max_y, dy);
}
confetti_circle((void *)api, which, canvas, last, x + dx, y + dy);
if (!i)
{
min_x = max_x = dx;
min_y = max_y = dy;
}
else
{
min_x = confetti_get_lesser(min_x, dx); //any candidates to new min/max values? Hands up please...
max_x = confetti_get_greater(max_x, dx);
min_y = confetti_get_lesser(min_y, dy);
max_y = confetti_get_greater(max_y, dy);
}
confetti_circle((void *) api, which, canvas, last, x + dx, y + dy);
}
update_rect->x = x + min_x - CONFETTI_BRUSH_SIZE / 2;
update_rect->y = y + min_y - CONFETTI_BRUSH_SIZE / 2;
@ -212,37 +231,41 @@ void confetti_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
}
void confetti_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
int temp;
if (ox > x)
{
temp = x;
x = ox;
ox = temp;
}
{
temp = x;
x = ox;
ox = temp;
}
if (oy > y)
{
temp = y;
y = oy;
oy = temp;
}
{
temp = y;
y = oy;
oy = temp;
}
confetti_click(api, which, MODE_PAINT, canvas, snapshot, x, y, update_rect);
}
void confetti_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void confetti_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void confetti_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void confetti_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int confetti_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int confetti_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -65,19 +65,26 @@ int distortion_requires_colors(magic_api * api, int which);
void distortion_shutdown(magic_api * api);
void distortion_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
void distortion_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void distortion_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void distortion_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void distortion_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void distortion_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void distortion_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void distortion_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int distortion_modes(magic_api * api, int which);
void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
static void distortion_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
static void distortion_line_callback(void *ptr, int which,
SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
/* Setup Functions: */
@ -95,7 +102,8 @@ int distortion_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/distortion.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/distortion.ogg",
api->data_directory);
// Try to load the file!
@ -119,7 +127,8 @@ SDL_Surface *distortion_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/distortion.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/distortion.png",
api->data_directory);
// Try to load the image, and return the results to Tux Paint:
@ -130,7 +139,8 @@ SDL_Surface *distortion_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
// Report our "Magic" tool names
char *distortion_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *distortion_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Distortion")));
}
@ -138,7 +148,8 @@ char *distortion_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
// Report our "Magic" tool groups
int distortion_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int distortion_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
@ -146,15 +157,19 @@ int distortion_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
// Report our "Magic" tool descriptions
char *distortion_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
char *distortion_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag the mouse to cause distortion in your picture.")));
return (strdup
(gettext_noop
("Click and drag the mouse to cause distortion in your picture.")));
}
// Report whether we accept colors
int distortion_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int distortion_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
@ -174,7 +189,8 @@ void distortion_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Affect the canvas on click:
void distortion_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect)
{
distortion_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
@ -183,25 +199,27 @@ void distortion_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on drag:
void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, distortion_line_callback);
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, 1,
distortion_line_callback);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 8;
@ -217,14 +235,18 @@ void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on release:
void distortion_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void distortion_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
void distortion_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void distortion_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
@ -233,7 +255,8 @@ void distortion_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UN
// Our "callback" function
static void distortion_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
@ -244,28 +267,34 @@ static void distortion_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
// Tux Paint sends to us with the values we enumerated above.
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
for (xx = -8; xx < 8; xx++)
{
if (api->in_circle(xx, yy, 8))
{
api->putpixel(canvas, x + xx, y + yy, api->getpixel(snapshot, x + xx / 2, y + yy));
}
}
if (api->in_circle(xx, yy, 8))
{
api->putpixel(canvas, x + xx, y + yy,
api->getpixel(snapshot, x + xx / 2, y + yy));
}
}
}
}
void distortion_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void distortion_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void distortion_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void distortion_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int distortion_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int distortion_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -47,19 +47,24 @@ int emboss_get_group(magic_api * api, int which);
char *emboss_get_description(magic_api * api, int which, int mode);
void emboss_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void emboss_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void emboss_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void emboss_shutdown(magic_api * api);
void emboss_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int emboss_requires_colors(magic_api * api, int which);
void emboss_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void emboss_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void emboss_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void emboss_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int emboss_modes(magic_api * api, int which);
@ -74,7 +79,8 @@ int emboss_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/emboss.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/emboss.ogg",
api->data_directory);
emboss_snd = Mix_LoadWAV(fname);
return (1);
@ -91,28 +97,34 @@ SDL_Surface *emboss_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/emboss.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/emboss.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *emboss_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *emboss_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Emboss")));
}
// Return our groups:
int emboss_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int emboss_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *emboss_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *emboss_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return (strdup(gettext_noop("Click and drag the mouse to emboss the picture.")));
return (strdup
(gettext_noop
("Click and drag the mouse to emboss the picture.")));
else
return (strdup(gettext_noop("Click to emboss the entire picture.")));
}
@ -120,7 +132,9 @@ char *emboss_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBU
// Do the effect (single pixel; used by do_emboss() (painted circle)
// and emboss_click() when in fullscreen mode):
static void emboss_pixel(void * ptr, SDL_Surface * last, int x, int y, SDL_Surface * canvas) {
static void emboss_pixel(void *ptr, SDL_Surface * last, int x, int y,
SDL_Surface * canvas)
{
magic_api *api = (magic_api *) ptr;
Uint8 r1, g1, b1, r2, g2, b2;
int r;
@ -150,46 +164,48 @@ static void emboss_pixel(void * ptr, SDL_Surface * last, int x, int y, SDL_Surfa
// Do the effect (a circle around a touch point):
static void do_emboss(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_emboss(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
for (xx = -16; xx < 16; xx++)
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(x + xx, y + yy))
{
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(x + xx, y + yy))
{
emboss_pixel(api, last, x + xx, y + yy, canvas);
}
}
emboss_pixel(api, last, x + xx, y + yy, canvas);
}
}
}
}
}
// Affect the canvas on drag:
void emboss_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_emboss);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_emboss);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -201,17 +217,24 @@ void emboss_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void emboss_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT) {
if (mode == MODE_PAINT)
{
emboss_drag(api, which, canvas, last, x, y, x, y, update_rect);
} else {
for (y = 0; y < canvas->h; y++) {
if (y % 10 == 0) {
}
else
{
for (y = 0; y < canvas->h; y++)
{
if (y % 10 == 0)
{
api->update_progress_bar();
}
for (x = 0; x < canvas->w; x++) {
for (x = 0; x < canvas->w; x++)
{
emboss_pixel(api, last, x, y, canvas);
}
}
@ -224,9 +247,12 @@ void emboss_click(magic_api * api, int which, int mode,
}
// Affect the canvas on release:
void emboss_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void emboss_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -238,23 +264,27 @@ void emboss_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void emboss_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void emboss_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int emboss_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int emboss_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void emboss_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void emboss_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void emboss_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void emboss_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -52,29 +52,38 @@ SDL_Surface *fade_darken_get_icon(magic_api * api, int which);
int fade_darken_get_group(magic_api * api, int which);
char *fade_darken_get_name(magic_api * api, int which);
char *fade_darken_get_description(magic_api * api, int which, int mode);
static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void fade_darken_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void fade_darken_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void fade_darken_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void fade_darken_shutdown(magic_api * api);
void fade_darken_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int fade_darken_requires_colors(magic_api * api, int which);
void fade_darken_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fade_darken_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fade_darken_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
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)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/fade.wav", api->data_directory);
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);
snprintf(fname, sizeof(fname), "%ssounds/magic/darken.wav",
api->data_directory);
snd_effects[TOOL_DARKEN] = Mix_LoadWAV(fname);
return (1);
@ -97,13 +106,15 @@ 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);
}
{
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/darken.png",
api->data_directory);
}
return (IMG_Load(fname));
}
@ -120,33 +131,40 @@ char *fade_darken_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (all the same):
int fade_darken_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fade_darken_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_COLOR_FILTERS;
}
// Return our description, localized:
char *fade_darken_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
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.")));
}
{
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.")));
}
{
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);
}
static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
Uint8 r, g, b;
magic_api *api = (magic_api *) ptr;
@ -154,47 +172,50 @@ static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas, SDL_Surfa
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r, &g, &b);
if (which == TOOL_FADE)
{
r = min(r + 48, 255);
g = min(g + 48, 255);
b = min(b + 48, 255);
}
{
r = min(r + 48, 255);
g = min(g + 48, 255);
b = min(b + 48, 255);
}
else if (which == TOOL_DARKEN)
{
r = max(r - 48, 0);
g = max(g - 48, 0);
b = max(b - 48, 0);
}
{
r = max(r - 48, 0);
g = max(g - 48, 0);
b = max(b - 48, 0);
}
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)
static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
if (api->in_circle(xx - x, yy - y, 16) && !api->touched(xx, yy))
{
do_fade_darken(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, 16) && !api->touched(xx, yy))
{
do_fade_darken(api, which, canvas, last, xx, yy);
}
}
}
}
// Ask Tux Paint to call our 'do_fade_darken_paint()' callback over a line
void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
SDL_LockSurface(last);
SDL_LockSurface(canvas);
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_fade_darken_paint);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_fade_darken_paint);
SDL_UnlockSurface(canvas);
SDL_UnlockSurface(last);
@ -202,19 +223,19 @@ void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
api->playsound(snd_effects[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -225,31 +246,35 @@ void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
// Ask Tux Paint to call our 'do_fade_darken_paint()' callback at a single point,
// or 'do_fade_darken()' on the entire image
void fade_darken_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
fade_darken_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
int xx, yy;
{
int xx, yy;
for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++)
do_fade_darken(api, which, canvas, last, xx, yy);
for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++)
do_fade_darken(api, which, canvas, last, xx, yy);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
/* FIXME: Play sfx */
}
/* FIXME: Play sfx */
}
}
// Release
void fade_darken_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void fade_darken_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -265,27 +290,34 @@ void fade_darken_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// We don't use colors
void fade_darken_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// We don't use colors
int fade_darken_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fade_darken_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void fade_darken_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fade_darken_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void fade_darken_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fade_darken_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int fade_darken_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fade_darken_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}

View file

@ -45,29 +45,36 @@ int fisheye_get_group(magic_api * api, int which);
char *fisheye_get_description(magic_api * api, int which, int mode);
int fisheye_requires_colors(magic_api * api, int which);
void fisheye_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void fisheye_shutdown(magic_api * api);
void fisheye_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void fisheye_draw(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void fisheye_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void fisheye_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fisheye_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void fisheye_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void fisheye_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void fisheye_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int fisheye_modes(magic_api * api, int which);
// Housekeeping functions
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
Uint32 fisheye_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
void fisheye_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void fisheye_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
@ -77,7 +84,8 @@ int fisheye_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/fisheye.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/fisheye.ogg",
api->data_directory);
fisheye_snd = Mix_LoadWAV(fname);
return (1);
@ -92,34 +100,45 @@ SDL_Surface *fisheye_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/fisheye.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/fisheye.png",
api->data_directory);
return (IMG_Load(fname));
}
char *fisheye_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *fisheye_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Fisheye"));
}
int fisheye_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fisheye_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
char *fisheye_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *fisheye_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click on part of your picture to create a fisheye effect."));
return
strdup(gettext_noop
("Click on part of your picture to create a fisheye effect."));
}
int fisheye_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fisheye_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void fisheye_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void fisheye_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -131,8 +150,8 @@ void fisheye_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// do-fisheye
void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -147,13 +166,15 @@ void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, S
last_x = x;
last_y = y;
oryg = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
oryg =
SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
output = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
output =
SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
rect.x = x - 40;
rect.y = y - 40;
@ -163,79 +184,85 @@ void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, S
//do vertical fisheye
for (i = 0; i < 40; i++)
{
temp_src = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
{
temp_src =
SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
//let's take a smooth bar of scaled bitmap and copy it to temp
//left side first
rect.x = i;
rect.y = 0;
rect.w = 1;
//let's take a smooth bar of scaled bitmap and copy it to temp
//left side first
rect.x = i;
rect.y = 0;
rect.w = 1;
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src
temp_dest = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80 + 2 * i, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp_dest =
SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80 + 2 * i,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
temp_rect.x = 0;
temp_rect.y = i;
temp_rect.w = 1;
temp_rect.h = 80;
temp_rect.x = 0;
temp_rect.y = i;
temp_rect.w = 1;
temp_rect.h = 80;
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
//right side then
//right side then
rect.x = 79 - i;
rect.x = 79 - i;
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src //OK
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src //OK
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
}
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
}
//do horizontal fisheye
for (i = 0; i < 40; i++)
{
temp_src = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
{
temp_src =
SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
temp_dest = SDL_CreateRGBSurface(SDL_SWSURFACE, 80 + 2 * i, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp_dest =
SDL_CreateRGBSurface(SDL_SWSURFACE, 80 + 2 * i, 1,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
//upper side first
rect.x = 0;
rect.y = i;
rect.w = 80;
rect.h = 1;
//upper side first
rect.x = 0;
rect.y = i;
rect.w = 80;
rect.h = 1;
temp_rect.x = i;
temp_rect.y = 0;
temp_rect.w = 80;
temp_rect.h = 1;
temp_rect.x = i;
temp_rect.y = 0;
temp_rect.w = 80;
temp_rect.h = 1;
SDL_BlitSurface(output, &rect, temp_src, NULL);
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
//lower side then
//lower side then
rect.y = 79 - i;
SDL_BlitSurface(output, &rect, temp_src, NULL);
rect.y = 79 - i;
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
}
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
}
rect.x = x - 40;
rect.y = y - 40;
@ -247,7 +274,8 @@ void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, S
for (xx = x - 40; xx < x + 40; xx++)
if (api->in_circle(xx - x, yy - y, 40))
api->putpixel(canvas, xx, yy, api->getpixel(output, xx + 40 - x, yy + 40 - y));
api->putpixel(canvas, xx, yy,
api->getpixel(output, xx + 40 - x, yy + 40 - y));
SDL_FreeSurface(oryg);
@ -259,7 +287,8 @@ void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, S
}
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, fisheye_draw);
@ -270,26 +299,30 @@ void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void fisheye_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
last_x = -80; /* A value that will be beyond any clicked position */
last_y = -80;
fisheye_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void fisheye_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fisheye_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void fisheye_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fisheye_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int fisheye_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fisheye_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -51,7 +51,8 @@ static Uint8 flower_r, flower_g, flower_b;
static int flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y;
static int flower_side_first;
static int flower_side_decided;
static SDL_Surface *flower_base, *flower_leaf, *flower_petals, *flower_petals_colorized;
static SDL_Surface *flower_base, *flower_leaf, *flower_petals,
*flower_petals_colorized;
/* Local function prototypes: */
@ -61,9 +62,11 @@ typedef struct
} Point2D;
static void flower_drawbase(magic_api * api, SDL_Surface * canvas);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x,
int y);
static Point2D flower_PointOnCubicBezier(Point2D * cp, float t);
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve);
static void flower_colorize_petals(magic_api * api);
Uint32 flower_api_version(void);
int flower_init(magic_api * api);
@ -72,25 +75,32 @@ SDL_Surface *flower_get_icon(magic_api * api, int which);
char *flower_get_name(magic_api * api, int which);
int flower_get_group(magic_api * api, int which);
char *flower_get_description(magic_api * api, int which, int mode);
static void flower_predrag(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y);
static void flower_predrag(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y);
void flower_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void flower_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void flower_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void flower_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void flower_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x,
int y);
static void flower_drawbase(magic_api * api, SDL_Surface * canvas);
static void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final);
int top_x, int top_y, int minx, int maxx,
int bottom_x, int bottom_y, int final);
void flower_shutdown(magic_api * api);
void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int flower_requires_colors(magic_api * api, int which);
static Point2D flower_PointOnCubicBezier(Point2D * cp, float t);
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve);
static void flower_colorize_petals(magic_api * api);
void flower_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void flower_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void flower_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void flower_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int flower_modes(magic_api * api, int which);
@ -106,19 +116,24 @@ int flower_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/flower_click.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/flower_click.ogg",
api->data_directory);
flower_click_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/flower_release.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/flower_release.ogg",
api->data_directory);
flower_release_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%simages/magic/flower_base.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/flower_base.png",
api->data_directory);
flower_base = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%simages/magic/flower_leaf.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/flower_leaf.png",
api->data_directory);
flower_leaf = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%simages/magic/flower_petals.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/flower_petals.png",
api->data_directory);
flower_petals = IMG_Load(fname);
return (1);
@ -135,32 +150,41 @@ SDL_Surface *flower_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/flower.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/flower.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *flower_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *flower_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Flower")));
}
// Return our groups:
int flower_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int flower_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_ARTISTIC;
}
// Return our descriptions, localized:
char *flower_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *flower_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to draw a flower stalk. Let go to finish the flower.")));
return (strdup
(gettext_noop
("Click and drag to draw a flower stalk. Let go to finish the flower.")));
}
// Affect the canvas on drag:
static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y)
static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox,
int oy, int x, int y)
{
if (x < flower_min_x)
flower_min_x = x;
@ -179,22 +203,23 @@ static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canva
// Determine which way to bend first:
//
if (flower_side_decided == 0)
{
if (x < flower_bottom_x - 10)
{
if (x < flower_bottom_x - 10)
{
flower_side_first = SIDE_LEFT;
flower_side_decided = 1;
}
else if (x > flower_bottom_x + 10)
{
flower_side_first = SIDE_RIGHT;
flower_side_decided = 1;
}
flower_side_first = SIDE_LEFT;
flower_side_decided = 1;
}
else if (x > flower_bottom_x + 10)
{
flower_side_first = SIDE_RIGHT;
flower_side_decided = 1;
}
}
}
void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int ox, int oy,
int x, int y, SDL_Rect * update_rect)
{
flower_predrag(api, canvas, last, ox, oy, x, y);
@ -207,7 +232,8 @@ void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canv
/* Draw the base and the stalk (low-quality) for now: */
flower_drawstalk(api, canvas,
x, y, flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y, !(api->button_down()));
x, y, flower_min_x, flower_max_x, flower_bottom_x,
flower_bottom_y, !(api->button_down()));
flower_drawbase(api, canvas);
@ -219,7 +245,8 @@ void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canv
// Affect the canvas on click:
void flower_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
flower_min_x = x;
flower_max_x = x;
@ -236,7 +263,8 @@ void flower_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release:
void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
/* Don't let flower be too low compared to base: */
@ -256,7 +284,8 @@ void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
/* Draw high-quality stalk, and flower: */
flower_drawstalk(api, canvas, x, y, flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y, 1);
flower_drawstalk(api, canvas, x, y, flower_min_x, flower_max_x,
flower_bottom_x, flower_bottom_y, 1);
flower_drawflower(api, canvas, x, y);
@ -272,7 +301,8 @@ void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
}
static void flower_drawflower(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas, int x, int y)
static void flower_drawflower(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas, int x, int y)
{
SDL_Rect dest;
@ -282,7 +312,8 @@ static void flower_drawflower(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * ca
SDL_BlitSurface(flower_petals_colorized, NULL, canvas, &dest);
}
static void flower_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas)
static void flower_drawbase(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{
SDL_Rect dest;
@ -292,8 +323,10 @@ static void flower_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canv
SDL_BlitSurface(flower_base, NULL, canvas, &dest);
}
static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final)
static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas, int top_x, int top_y,
int minx, int maxx, int bottom_x, int bottom_y,
int final)
{
Point2D control_points[4];
Point2D *curve;
@ -310,15 +343,15 @@ static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
control_points[0].y = top_y;
if (flower_side_first == SIDE_LEFT)
{
control_points[1].x = minx;
control_points[2].x = maxx;
}
{
control_points[1].x = minx;
control_points[2].x = maxx;
}
else
{
control_points[1].x = maxx;
control_points[2].x = minx;
}
{
control_points[1].x = maxx;
control_points[2].x = minx;
}
control_points[1].y = ((bottom_y - top_y) / 3) + top_y;
control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y;
@ -339,126 +372,127 @@ static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
/* Draw the curve: */
for (i = 0; i < n_points - 1; i++)
{
if (final == 0)
{
if (final == 0)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
}
else
{
left = min(curve[i].x, curve[i + 1].x);
right = max(curve[i].x, curve[i + 1].x);
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
/* When we're done (final render), we can add some random leaves: */
if (final && i > 32 && i < n_points - 32 && (i % 16) == 0 && (rand() % 5) > 0)
{
/* Check for hard left/right angles: */
side = -1;
if (curve[i - 2].x - curve[i + 2].x > 5)
{
/* Hard lower-left-to-upper-right (/),
stick either a left-upward or right-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_UP;
else
side = LEAFSIDE_RIGHT_DOWN;
}
else if (curve[i - 2].x - curve[i + 2].x < -5)
{
/* Hard lower-right-to-upper-left (\)
stick either a right-upward or left-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_UP;
}
else if (fabs(curve[i - 2].x - curve[i + 2].x) < 5)
{
/* Mostly up; stick left- or right-downward: */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_DOWN;
}
/* Draw the appropriately-oriented leaf, if any: */
if (side == LEAFSIDE_RIGHT_DOWN)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, NULL, canvas, &dest);
}
else if (side == LEAFSIDE_LEFT_DOWN)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
src.x = xx;
src.y = 0;
src.w = 1;
src.h = flower_leaf->h;
dest.x = curve[i].x - xx;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_RIGHT_UP)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = flower_leaf->w;
src.h = 1;
dest.x = curve[i].x;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_LEFT_UP)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = xx;
src.y = yy;
src.w = 1;
src.h = 1;
dest.x = curve[i].x - xx;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
}
}
dest.x = curve[i].x;
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
}
else
{
left = min(curve[i].x, curve[i + 1].x);
right = max(curve[i].x, curve[i + 1].x);
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
/* When we're done (final render), we can add some random leaves: */
if (final && i > 32 && i < n_points - 32 && (i % 16) == 0
&& (rand() % 5) > 0)
{
/* Check for hard left/right angles: */
side = -1;
if (curve[i - 2].x - curve[i + 2].x > 5)
{
/* Hard lower-left-to-upper-right (/),
stick either a left-upward or right-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_UP;
else
side = LEAFSIDE_RIGHT_DOWN;
}
else if (curve[i - 2].x - curve[i + 2].x < -5)
{
/* Hard lower-right-to-upper-left (\)
stick either a right-upward or left-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_UP;
}
else if (fabs(curve[i - 2].x - curve[i + 2].x) < 5)
{
/* Mostly up; stick left- or right-downward: */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_DOWN;
}
/* Draw the appropriately-oriented leaf, if any: */
if (side == LEAFSIDE_RIGHT_DOWN)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, NULL, canvas, &dest);
}
else if (side == LEAFSIDE_LEFT_DOWN)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
src.x = xx;
src.y = 0;
src.w = 1;
src.h = flower_leaf->h;
dest.x = curve[i].x - xx;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_RIGHT_UP)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = flower_leaf->w;
src.h = 1;
dest.x = curve[i].x;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_LEFT_UP)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = xx;
src.y = yy;
src.w = 1;
src.h = 1;
dest.x = curve[i].x - xx;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
}
}
}
free(curve);
}
@ -492,7 +526,8 @@ void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
}
// Use colors:
int flower_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int flower_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
@ -547,7 +582,8 @@ static Point2D flower_PointOnCubicBezier(Point2D * cp, float t)
<sizeof(Point2D) numberOfPoints>
*/
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
static void flower_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve)
{
float dt;
int i;
@ -570,7 +606,9 @@ static void flower_colorize_petals(magic_api * api)
/* Create a surface to render into: */
amask = ~(flower_petals->format->Rmask | flower_petals->format->Gmask | flower_petals->format->Bmask);
amask =
~(flower_petals->format->Rmask | flower_petals->format->
Gmask | flower_petals->format->Bmask);
flower_petals_colorized =
SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -578,7 +616,8 @@ static void flower_colorize_petals(magic_api * api)
flower_petals->h,
flower_petals->format->BitsPerPixel,
flower_petals->format->Rmask,
flower_petals->format->Gmask, flower_petals->format->Bmask, amask);
flower_petals->format->Gmask,
flower_petals->format->Bmask, amask);
/* Render the new petals: */
@ -586,32 +625,38 @@ static void flower_colorize_petals(magic_api * api)
SDL_LockSurface(flower_petals_colorized);
for (y = 0; y < flower_petals->h; y++)
{
for (x = 0; x < flower_petals->w; x++)
{
for (x = 0; x < flower_petals->w; x++)
{
SDL_GetRGBA(api->getpixel(flower_petals, x, y), flower_petals->format, &r, &g, &b, &a);
SDL_GetRGBA(api->getpixel(flower_petals, x, y), flower_petals->format,
&r, &g, &b, &a);
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format, flower_r, flower_g, flower_b, a));
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format, flower_r,
flower_g, flower_b, a));
if (api->in_circle((x - flower_petals->w / 2), (y - flower_petals->h / 2), 8))
{
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format, 0xFF, 0xFF, 0x00, a));
}
}
if (api->in_circle
((x - flower_petals->w / 2), (y - flower_petals->h / 2), 8))
{
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format, 0xFF, 0xFF,
0x00, a));
}
}
}
SDL_UnlockSurface(flower_petals_colorized);
SDL_UnlockSurface(flower_petals);
}
void flower_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void flower_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void flower_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void flower_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -46,16 +46,22 @@ Uint32 foam_api_version(void);
int foam_init(magic_api * api);
char *foam_get_description(magic_api * api, int which, int mode);
void foam_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void foam_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void foam_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface *foam_get_icon(magic_api * api, int which);
char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED);
int foam_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED);
void foam_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void foam_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED);
int foam_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED);
void foam_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void foam_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void foam_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void foam_shutdown(magic_api * api);
int foam_get_tool_count(magic_api * api);
@ -77,16 +83,26 @@ int foam_init(magic_api * api)
char fname[1024];
SDL_Surface *foam_data;
snprintf(fname, sizeof(fname), "%ssounds/magic/foam.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/foam.ogg",
api->data_directory);
foam_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%simages/magic/foam_data.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/foam_data.png",
api->data_directory);
foam_data = IMG_Load(fname);
foam_7 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 4) / 4, ((api->canvas_h / FOAM_PROP) * 4) / 4, 0);
foam_5 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 3) / 4, ((api->canvas_h / FOAM_PROP) * 3) / 4, 0);
foam_3 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 2) / 4, ((api->canvas_h / FOAM_PROP) * 2) / 4, 0);
foam_1 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 1) / 4, ((api->canvas_h / FOAM_PROP) * 1) / 4, 0);
foam_7 =
api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 4) / 4,
((api->canvas_h / FOAM_PROP) * 4) / 4, 0);
foam_5 =
api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 3) / 4,
((api->canvas_h / FOAM_PROP) * 3) / 4, 0);
foam_3 =
api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 2) / 4,
((api->canvas_h / FOAM_PROP) * 2) / 4, 0);
foam_1 =
api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 1) / 4,
((api->canvas_h / FOAM_PROP) * 1) / 4, 0);
SDL_FreeSurface(foam_data);
@ -104,32 +120,40 @@ SDL_Surface *foam_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/foam.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/foam.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Foam")));
}
// Return our groups
int foam_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int foam_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *foam_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *foam_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag the mouse to cover an area with foamy bubbles.")));
return (strdup
(gettext_noop
("Click and drag the mouse to cover an area with foamy bubbles.")));
}
// Do the effect:
static void do_foam(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
static void do_foam(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -138,46 +162,47 @@ static void do_foam(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas
/* SDL_Rect dest; */
for (yy = -FOAM_RADIUS; yy < FOAM_RADIUS; yy++)
{
for (xx = -FOAM_RADIUS; xx < FOAM_RADIUS; xx++)
{
for (xx = -FOAM_RADIUS; xx < FOAM_RADIUS; xx++)
{
if (api->in_circle(xx, yy, FOAM_RADIUS))
{
nx = (x / FOAM_PROP) + xx;
ny = (y / FOAM_PROP) + yy;
if (api->in_circle(xx, yy, FOAM_RADIUS))
{
nx = (x / FOAM_PROP) + xx;
ny = (y / FOAM_PROP) + yy;
if (nx >= 0 && ny >= 0 && nx < foam_mask_w && ny < foam_mask_h)
{
foam_mask[ny * foam_mask_w + nx] = 1;
}
}
if (nx >= 0 && ny >= 0 && nx < foam_mask_w && ny < foam_mask_h)
{
foam_mask[ny * foam_mask_w + nx] = 1;
}
}
}
}
}
// Affect the canvas on drag:
void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_foam);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_foam);
foam_release(api, which, canvas, last, x, y, update_rect);
/* FIXME */
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = 0;
update_rect->y = 0;
@ -188,20 +213,21 @@ void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
}
// Affect the canvas on click:
void foam_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
void foam_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
{
int i;
if (foam_mask == NULL)
{
foam_mask_w = canvas->w / FOAM_PROP;
foam_mask_h = canvas->h / FOAM_PROP;
{
foam_mask_w = canvas->w / FOAM_PROP;
foam_mask_h = canvas->h / FOAM_PROP;
foam_mask = (int *)malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
foam_mask_tmp = (int *)malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
}
foam_mask = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
foam_mask_tmp = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
}
for (i = 0; i < foam_mask_w * foam_mask_h; i++)
foam_mask[i] = 0;
@ -217,24 +243,25 @@ static int foam_mask_test(int r, int x, int y)
tot = 0;
for (yy = 0; yy < r; yy++)
{
for (xx = 0; xx < r; xx++)
{
for (xx = 0; xx < r; xx++)
{
if (x + xx < foam_mask_w && y + yy < foam_mask_h)
{
bub_r = foam_mask[((y + yy) * foam_mask_w) + (x + xx)];
tot = tot + bub_r;
}
}
if (x + xx < foam_mask_w && y + yy < foam_mask_h)
{
bub_r = foam_mask[((y + yy) * foam_mask_w) + (x + xx)];
tot = tot + bub_r;
}
}
}
return (tot);
}
// Affect the canvas on release:
void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
{
int xx, yy;
int changes, max_iters;
@ -244,165 +271,167 @@ void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED, int which A
SDL_BlitSurface(last, NULL, canvas, NULL);
memcpy(foam_mask_tmp, foam_mask, (sizeof(int) * (foam_mask_w * foam_mask_h)));
memcpy(foam_mask_tmp, foam_mask,
(sizeof(int) * (foam_mask_w * foam_mask_h)));
max_iters = 2;
do
{
changes = 0;
max_iters--;
for (yy = 0; yy < foam_mask_h - 7; yy++)
{
changes = 0;
max_iters--;
for (yy = 0; yy < foam_mask_h - 7; yy++)
for (xx = 0; xx < foam_mask_w - 7; xx++)
{
if (foam_mask_test(7, xx, yy) >= 40)
{
for (xx = 0; xx < foam_mask_w - 7; xx++)
{
if (foam_mask_test(7, xx, yy) >= 40)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 7;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 7;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 3)] = 7;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 5)] = 3;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 3)] = 7;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 5)] = 3;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 6)] = 2;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 6)] = 2;
changes = 1;
}
else if (foam_mask_test(5, xx, yy) >= 30)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 5;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
changes = 1;
}
else if (foam_mask_test(3, xx, yy) >= 8)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 3;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 1;
changes = 1;
}
}
changes = 1;
}
else if (foam_mask_test(5, xx, yy) >= 30)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 5;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
changes = 1;
}
else if (foam_mask_test(3, xx, yy) >= 8)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 3;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 1;
changes = 1;
}
}
}
}
while (changes && max_iters > 0);
for (yy = 0; yy < foam_mask_h; yy++)
{
for (xx = 0; xx < foam_mask_w; xx++)
{
for (xx = 0; xx < foam_mask_w; xx++)
{
n = foam_mask[yy * foam_mask_w + xx];
n = foam_mask[yy * foam_mask_w + xx];
img = NULL;
img = NULL;
if (n == 1)
img = foam_1;
else if (n == 3)
img = foam_3;
else if (n == 5)
img = foam_5;
else if (n == 7)
img = foam_7;
if (n == 1)
img = foam_1;
else if (n == 3)
img = foam_3;
else if (n == 5)
img = foam_5;
else if (n == 7)
img = foam_7;
if (img != NULL)
{
dest.x = (xx * FOAM_PROP) - (img->w / 2) + ((rand() % 15) - 7);
dest.y = (yy * FOAM_PROP) - (img->h / 2) + ((rand() % 15) - 7);
if (img != NULL)
{
dest.x = (xx * FOAM_PROP) - (img->w / 2) + ((rand() % 15) - 7);
dest.y = (yy * FOAM_PROP) - (img->h / 2) + ((rand() % 15) - 7);
SDL_BlitSurface(img, NULL, canvas, &dest);
}
}
SDL_BlitSurface(img, NULL, canvas, &dest);
}
}
}
memcpy(foam_mask, foam_mask_tmp, (sizeof(int) * (foam_mask_w * foam_mask_h)));
memcpy(foam_mask, foam_mask_tmp,
(sizeof(int) * (foam_mask_w * foam_mask_h)));
update_rect->x = 0;
@ -431,7 +460,8 @@ void foam_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void foam_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void foam_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
foam_r = r;
foam_g = g;
@ -439,17 +469,20 @@ void foam_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
}
// Use colors:
int foam_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int foam_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0; /* FIXME: Would be nice to tint the bubbles */
}
void foam_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void foam_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void foam_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void foam_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -32,15 +32,21 @@ SDL_Surface *fold_surface_src, *fold_surface_dst;
void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
static void fold_erase(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
static void fold_erase(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void translate_coords(SDL_Surface * canvas, int angle);
SDL_Surface *rotate(magic_api * api, SDL_Surface * canvas, int angle);
void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
static void fold_print_line(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void fold_print_dark_line(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b, int rotation);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
static void fold_print_line(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void fold_print_dark_line(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b,
int rotation);
Uint32 fold_api_version(void);
void fold_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int fold_init(magic_api * api);
@ -51,21 +57,27 @@ int fold_get_group(magic_api * api, int which);
char *fold_get_description(magic_api * api, int which, int mode);
int fold_requires_colors(magic_api * api, int which);
void fold_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void fold_shutdown(magic_api * api);
void fold_click(magic_api * ptr, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
int fold_modes(magic_api * api, int which);
// Housekeeping functions
void fold_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void fold_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void fold_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas);
void fold_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fold_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
Uint32 fold_api_version(void)
{
@ -83,7 +95,8 @@ int fold_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/fold.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/fold.wav",
api->data_directory);
fold_snd = Mix_LoadWAV(fname);
return (1);
@ -94,50 +107,65 @@ int fold_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1;
}
SDL_Surface *fold_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
SDL_Surface *fold_get_icon(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/fold.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/fold.png",
api->data_directory);
return (IMG_Load(fname));
}
char *fold_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *fold_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (gettext_noop("Fold"));
}
int fold_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fold_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
char *fold_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *fold_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Choose a background color and click to turn the corner of the page over."));
return
strdup(gettext_noop
("Choose a background color and click to turn the corner of the page over."));
}
int fold_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fold_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
} //selected color will be a "backpage" color
static void fold_shadow(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * temp, int x, int y)
static void fold_shadow(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * temp, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 r, g, b, a;
SDL_GetRGBA(api->getpixel(temp, x, y), temp->format, &r, &g, &b, &a);
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format,
max(r - 160 + fold_shadow_value * 4, 0), max(g - 160 + fold_shadow_value * 4,
0),
max(b - 160 + fold_shadow_value * 4, 0), a));
max(r - 160 + fold_shadow_value * 4,
0),
max(g - 160 + fold_shadow_value * 4,
0),
max(b - 160 + fold_shadow_value * 4,
0), a));
}
void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
float right_step_x, right_step_y, left_step_x, left_step_y;
float dist_x, dist_y;
@ -145,86 +173,103 @@ void fold_draw(magic_api * api, int which,
float w, h;
SDL_Surface *temp;
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
SDL_BlitSurface(canvas, 0, temp, 0);
right_step_x = (float)(x - left_arm_x) / (float)(left_arm_x - fold_ox);
right_step_y = (float)(y - left_arm_y) / (float)(left_arm_x - fold_ox);
left_step_x = (float)(x - right_arm_x) / (float)(right_arm_y - fold_oy);
left_step_y = (float)(y - right_arm_y) / (float)(right_arm_y - fold_oy);
right_step_x = (float) (x - left_arm_x) / (float) (left_arm_x - fold_ox);
right_step_y = (float) (y - left_arm_y) / (float) (left_arm_x - fold_ox);
left_step_x = (float) (x - right_arm_x) / (float) (right_arm_y - fold_oy);
left_step_y = (float) (y - right_arm_y) / (float) (right_arm_y - fold_oy);
left_y = (float)right_arm_y / left_arm_x * (left_arm_x - canvas->w);
right_x = (float)left_arm_x / right_arm_y * (right_arm_y - canvas->h);
left_y = (float) right_arm_y / left_arm_x * (left_arm_x - canvas->w);
right_x = (float) left_arm_x / right_arm_y * (right_arm_y - canvas->h);
for (w = 0; w < canvas->w; w += 0.5)
{
for (h = 0; h < canvas->h; h += 0.5)
{
for (h = 0; h < canvas->h; h += 0.5)
{
dist_x = right_step_x * w + left_step_x * h;
dist_y = right_step_y * w + left_step_y * h;
api->putpixel(canvas, x - dist_x, y - dist_y, api->getpixel(temp, w, h));
}
dist_x = right_step_x * w + left_step_x * h;
dist_y = right_step_y * w + left_step_y * h;
api->putpixel(canvas, x - dist_x, y - dist_y,
api->getpixel(temp, w, h));
}
}
// Erasing the triangle.
// The 1 pixel in plus is a workaround for api-line not getting the end in some lines.
if (left_arm_x > canvas->w)
{
for (h = 0; h <= right_arm_y; h++)
api->line((void *)api, which, canvas, snapshot, canvas->w, left_y - h, -1, right_arm_y - h, 1, fold_erase);
}
{
for (h = 0; h <= right_arm_y; h++)
api->line((void *) api, which, canvas, snapshot, canvas->w, left_y - h,
-1, right_arm_y - h, 1, fold_erase);
}
else if (right_arm_y > canvas->h)
{
for (w = 0; w <= left_arm_x; w++)
api->line((void *)api, which, canvas, snapshot, left_arm_x - w, 0, right_x - w, canvas->h + 1, 1, fold_erase);
}
{
for (w = 0; w <= left_arm_x; w++)
api->line((void *) api, which, canvas, snapshot, left_arm_x - w, 0,
right_x - w, canvas->h + 1, 1, fold_erase);
}
else
for (w = 0; w <= min(left_arm_x, right_arm_y); w++) // The -1 values are because api->line
api->line((void *)api, which, canvas, snapshot, left_arm_x - w, 0, -1, right_arm_y - w, 1, fold_erase);
api->line((void *) api, which, canvas, snapshot, left_arm_x - w, 0, -1,
right_arm_y - w, 1, fold_erase);
SDL_BlitSurface(canvas, 0, temp, 0);
// Shadows
if (left_arm_x > canvas->w)
{
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, canvas->w, left_y - fold_shadow_value, 0,
right_arm_y - fold_shadow_value, 1, fold_shadow);
{
for (fold_shadow_value = 0; fold_shadow_value < 40;
fold_shadow_value += 1)
api->line((void *) api, which, canvas, temp, canvas->w,
left_y - fold_shadow_value, 0,
right_arm_y - fold_shadow_value, 1, fold_shadow);
}
}
else if (right_arm_y > canvas->h)
{
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, left_arm_x - fold_shadow_value, 0, right_x - fold_shadow_value,
canvas->h, 1, fold_shadow);
{
for (fold_shadow_value = 0; fold_shadow_value < 40;
fold_shadow_value += 1)
api->line((void *) api, which, canvas, temp,
left_arm_x - fold_shadow_value, 0,
right_x - fold_shadow_value, canvas->h, 1, fold_shadow);
}
}
else
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, left_arm_x - fold_shadow_value, 0, 0, right_arm_y - fold_shadow_value,
1, fold_shadow);
for (fold_shadow_value = 0; fold_shadow_value < 40;
fold_shadow_value += 1)
api->line((void *) api, which, canvas, temp,
left_arm_x - fold_shadow_value, 0, 0,
right_arm_y - fold_shadow_value, 1, fold_shadow);
SDL_BlitSurface(canvas, 0, temp, 0);
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
{
if (fold_shadow_value * left_step_x > x || fold_shadow_value * right_step_y > y)
break;
{
if (fold_shadow_value * left_step_x > x
|| fold_shadow_value * right_step_y > y)
break;
dist_x = fold_shadow_value * (right_step_x + left_step_x);
dist_y = fold_shadow_value * (right_step_y + left_step_y);
api->line((void *)api, which, canvas, temp, left_arm_x + fold_shadow_value * right_step_x,
fold_shadow_value * right_step_y, fold_shadow_value * left_step_x,
right_arm_y + fold_shadow_value * left_step_y, 1, fold_shadow);
}
dist_x = fold_shadow_value * (right_step_x + left_step_x);
dist_y = fold_shadow_value * (right_step_y + left_step_y);
api->line((void *) api, which, canvas, temp,
left_arm_x + fold_shadow_value * right_step_x,
fold_shadow_value * right_step_y,
fold_shadow_value * left_step_x,
right_arm_y + fold_shadow_value * left_step_y, 1, fold_shadow);
}
api->line((void *)api, which, canvas, snapshot, x, y, right_arm_x, right_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1,
fold_print_dark_line);
api->line((void *) api, which, canvas, snapshot, x, y, right_arm_x,
right_arm_y, 1, fold_print_line);
api->line((void *) api, which, canvas, snapshot, x, y, left_arm_x,
left_arm_y, 1, fold_print_line);
api->line((void *) api, which, canvas, snapshot, left_arm_x, left_arm_y,
right_arm_x, right_arm_y, 1, fold_print_dark_line);
}
@ -235,44 +280,48 @@ SDL_Surface *rotate(magic_api * api, SDL_Surface * canvas, int angle)
int a, b;
if (angle == 180)
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
else
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->h, canvas->w, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->h, canvas->w,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
switch (angle)
{
case 90:
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 90);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
{
case 90:
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 90);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
case 180:
// printf("%i, %i\n",temp,canvas);
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 180);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
case 180:
// printf("%i, %i\n",temp,canvas);
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 180);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
case 270:
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 270);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
}
case 270:
for (x = 0; x < canvas->w; x++)
for (y = 0; y < canvas->h; y++)
{
translate_xy(canvas, x, y, &a, &b, 270);
api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
}
break;
}
return temp;
}
@ -281,54 +330,56 @@ void translate_coords(SDL_Surface * canvas, int angle)
int a, b;
switch (angle)
{
case 90:
translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 90);
right_arm_x = a;
right_arm_y = b;
translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 90);
left_arm_x = a;
left_arm_y = b;
{
case 90:
translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 90);
right_arm_x = a;
right_arm_y = b;
translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 90);
left_arm_x = a;
left_arm_y = b;
break;
case 180:
right_arm_x = canvas->w - 1 - right_arm_x;
right_arm_y = canvas->h - 1 - right_arm_y;
left_arm_x = canvas->w - 1 - left_arm_x;
left_arm_y = canvas->h - 1 - left_arm_y;
break;
case 270:
translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 270);
right_arm_x = a;
right_arm_y = b;
translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 270);
left_arm_x = a;
left_arm_y = b;
break;
}
break;
case 180:
right_arm_x = canvas->w - 1 - right_arm_x;
right_arm_y = canvas->h - 1 - right_arm_y;
left_arm_x = canvas->w - 1 - left_arm_x;
left_arm_y = canvas->h - 1 - left_arm_y;
break;
case 270:
translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 270);
right_arm_x = a;
right_arm_y = b;
translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 270);
left_arm_x = a;
left_arm_y = b;
break;
}
}
void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b, int rotation)
void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b,
int rotation)
{
switch (rotation)
{
case 90:
*a = y;
*b = canvas->w - 1 - x;
break;
case 180:
*a = canvas->w - 1 - x;
*b = canvas->h - 1 - y;
break;
case 270:
*a = canvas->h - 1 - y;
*b = x;
break;
}
{
case 90:
*a = y;
*b = canvas->w - 1 - x;
break;
case 180:
*a = canvas->w - 1 - x;
*b = canvas->h - 1 - y;
break;
case 270:
*a = canvas->h - 1 - y;
*b = x;
break;
}
}
void fold_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
int a, b;
SDL_Surface *temp, *temp2;
@ -338,44 +389,44 @@ void fold_release(magic_api * api, int which,
fold_ox = fold_oy = 0;
SDL_BlitSurface(snapshot, 0, canvas, 0);
switch (corner)
{
case 1:
translate_xy(canvas, x, y, &a, &b, 90);
translate_coords(canvas, 90);
temp = rotate(api, canvas, 90);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 270);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
{
case 1:
translate_xy(canvas, x, y, &a, &b, 90);
translate_coords(canvas, 90);
temp = rotate(api, canvas, 90);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 270);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
case 2:
fold_draw(api, which, canvas, snapshot, x, y, update_rect);
break;
case 2:
fold_draw(api, which, canvas, snapshot, x, y, update_rect);
break;
case 3:
translate_xy(canvas, x, y, &a, &b, 270);
translate_coords(canvas, 270);
temp = rotate(api, canvas, 270);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 90);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
case 3:
translate_xy(canvas, x, y, &a, &b, 270);
translate_coords(canvas, 270);
temp = rotate(api, canvas, 270);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 90);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
case 4:
translate_xy(canvas, x, y, &a, &b, 180);
translate_coords(canvas, 180);
temp = rotate(api, canvas, 180);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 180);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
}
case 4:
translate_xy(canvas, x, y, &a, &b, 180);
translate_coords(canvas, 180);
temp = rotate(api, canvas, 180);
fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2 = rotate(api, temp, 180);
SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp);
SDL_FreeSurface(temp2);
break;
}
update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w;
@ -395,77 +446,84 @@ void fold_shutdown(magic_api * api ATTRIBUTE_UNUSED)
inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas)
{
if (x >= canvas->w / 2)
{
if (y >= canvas->h / 2)
return 4;
else
return 1;
}
{
if (y >= canvas->h / 2)
return 4;
else
return 1;
}
else
{
if (y >= canvas->h / 2)
return 3;
else
return 2;
}
{
if (y >= canvas->h / 2)
return 3;
else
return 2;
}
}
static void fold_print_line(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
static void fold_print_line(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 222, 222, 222)); //Middle gray. Color have been set arbitrary.
}
static void fold_print_dark_line(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
static void fold_print_dark_line(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 90, 90, 90)); //It should not look too black nor too white with shadowed colors.
}
static void fold_erase(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
static void fold_erase(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, fold_r, fold_g, fold_b));
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, fold_r, fold_g, fold_b));
}
void fold_click(magic_api * ptr, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
magic_api *api = (magic_api *) ptr;
corner = fold_what_corner(x, y, snapshot);
switch (corner)
{
case 1:
fold_ox = canvas->w - 1;
fold_oy = 0;
break;
case 2:
fold_ox = fold_oy = 0;
break;
case 3:
fold_ox = 0;
fold_oy = canvas->h - 1;
break;
case 4:
fold_ox = canvas->w - 1;
fold_oy = canvas->h - 1;
break;
}
{
case 1:
fold_ox = canvas->w - 1;
fold_oy = 0;
break;
case 2:
fold_ox = fold_oy = 0;
break;
case 3:
fold_ox = 0;
fold_oy = canvas->h - 1;
break;
case 4:
fold_ox = canvas->w - 1;
fold_oy = canvas->h - 1;
break;
}
fold_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect)
{
int middle_point_x;
@ -479,51 +537,69 @@ void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
middle_point_y = (fold_oy + y) / 2;
switch (corner)
{
case 1: //Right Upper
right_arm_x = fold_ox - (fold_ox - middle_point_x) - middle_point_y * middle_point_y / (fold_ox - middle_point_x);
right_arm_y = fold_oy;
{
case 1: //Right Upper
right_arm_x =
fold_ox - (fold_ox - middle_point_x) -
middle_point_y * middle_point_y / (fold_ox - middle_point_x);
right_arm_y = fold_oy;
left_arm_x = fold_ox;
left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
break;
left_arm_x = fold_ox;
left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox -
middle_point_x) * (fold_ox -
middle_point_x)
/ (fold_oy - middle_point_y);
break;
case 2: //LU
right_arm_x = fold_ox;
right_arm_y = middle_point_y + middle_point_x * middle_point_x / middle_point_y;
case 2: //LU
right_arm_x = fold_ox;
right_arm_y =
middle_point_y + middle_point_x * middle_point_x / middle_point_y;
left_arm_x = middle_point_x + middle_point_y * middle_point_y / middle_point_x;
left_arm_y = fold_oy;
break;
left_arm_x =
middle_point_x + middle_point_y * middle_point_y / middle_point_x;
left_arm_y = fold_oy;
break;
case 3: //LL
right_arm_x = middle_point_x + (fold_oy - middle_point_y) * (fold_oy - middle_point_y) / middle_point_x;
right_arm_y = fold_oy;
case 3: //LL
right_arm_x =
middle_point_x + (fold_oy - middle_point_y) * (fold_oy -
middle_point_y) /
middle_point_x;
right_arm_y = fold_oy;
left_arm_x = fold_ox;
left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
break;
left_arm_x = fold_ox;
left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox -
middle_point_x) * (fold_ox -
middle_point_x)
/ (fold_oy - middle_point_y);
break;
case 4: //RL
right_arm_x = fold_ox;
right_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
case 4: //RL
right_arm_x = fold_ox;
right_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox -
middle_point_x) * (fold_ox -
middle_point_x)
/ (fold_oy - middle_point_y);
left_arm_x =
fold_ox - (fold_ox - middle_point_x) - (fold_oy - middle_point_y) * (fold_oy - middle_point_y) / (fold_ox -
middle_point_x);
left_arm_y = fold_oy;
break;
}
left_arm_x =
fold_ox - (fold_ox - middle_point_x) - (fold_oy -
middle_point_y) * (fold_oy -
middle_point_y)
/ (fold_ox - middle_point_x);
left_arm_y = fold_oy;
break;
}
api->line((void *)api, which, canvas, snapshot, x, y, right_arm_x, right_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1, fold_print_line);
api->line((void *) api, which, canvas, snapshot, x, y, right_arm_x,
right_arm_y, 1, fold_print_line);
api->line((void *) api, which, canvas, snapshot, x, y, left_arm_x,
left_arm_y, 1, fold_print_line);
api->line((void *) api, which, canvas, snapshot, left_arm_x, left_arm_y,
right_arm_x, right_arm_y, 1, fold_print_line);
update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w;
@ -531,7 +607,8 @@ void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
}
void fold_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
// Avoid division by zero when calculating the preview
x = clamp(2, x, canvas->w - 2);
@ -539,12 +616,14 @@ void fold_drag(magic_api * api, int which, SDL_Surface * canvas,
fold_preview(api, which, canvas, snapshot, ox, oy, x, y, update_rect);
}
void fold_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fold_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void fold_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void fold_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -49,7 +49,8 @@ static unsigned int fretwork_update_rectangle_width; //the width of the updat
static unsigned int fretwork_update_rectangle_height; //the height of the update_rectangle
static SDL_Rect modification_rect;
static SDL_Surface *canvas_backup;
static SDL_Surface *fretwork_one_back, *fretwork_three_back, *fretwork_four_back, *fretwork_corner_back;
static SDL_Surface *fretwork_one_back, *fretwork_three_back,
*fretwork_four_back, *fretwork_corner_back;
// Housekeeping functions
@ -57,7 +58,8 @@ static SDL_Surface *fretwork_one_back, *fretwork_three_back, *fretwork_four_back
Uint32 fretwork_api_version(void);
int fretwork_modes(magic_api * api, int which);
void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src);
static void fretwork_colorize(magic_api * api, SDL_Surface * dest,
SDL_Surface * src);
int fretwork_init(magic_api * api);
int fretwork_get_tool_count(magic_api * api);
SDL_Surface *fretwork_get_icon(magic_api * api, int which);
@ -66,20 +68,28 @@ int fretwork_get_group(magic_api * api, int which);
char *fretwork_get_description(magic_api * api, int which, int mode);
int fretwork_requires_colors(magic_api * api, int which);
void fretwork_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void fretwork_shutdown(magic_api * api);
void fretwork_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void fretwork_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void fretwork_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot);
void fretwork_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot);
#define POINT_TYPE typeof(((SDL_Rect *)NULL)->x)
inline void fretwork_extract_coords_from_segment(unsigned int segment, POINT_TYPE * x, POINT_TYPE * y);
inline void fretwork_extract_coords_from_segment(unsigned int segment,
POINT_TYPE * x,
POINT_TYPE * y);
void fretwork_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void fretwork_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
inline unsigned int fretwork_get_segment(int x, int y);
@ -90,7 +100,8 @@ Uint32 fretwork_api_version(void)
return (TP_MAGIC_API_VERSION);
}
int fretwork_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fretwork_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}
@ -107,7 +118,8 @@ void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
}
/* Adapted from flower.c */
static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src)
static void fretwork_colorize(magic_api * api, SDL_Surface * dest,
SDL_Surface * src)
{
int x, y;
Uint8 r, g, b, a;
@ -116,14 +128,16 @@ static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface *
SDL_LockSurface(dest);
for (y = 0; y < src->h; y++)
{
for (x = 0; x < src->w; x++)
{
for (x = 0; x < src->w; x++)
{
SDL_GetRGBA(api->getpixel(src, x, y), src->format, &r, &g, &b, &a);
SDL_GetRGBA(api->getpixel(src, x, y), src->format, &r, &g, &b, &a);
api->putpixel(dest, x, y, SDL_MapRGBA(dest->format, fretwork_r, fretwork_g, fretwork_b, a));
}
api->putpixel(dest, x, y,
SDL_MapRGBA(dest->format, fretwork_r, fretwork_g,
fretwork_b, a));
}
}
SDL_UnlockSurface(src);
SDL_UnlockSurface(dest);
@ -135,15 +149,19 @@ int fretwork_init(magic_api * api)
char fname[1024];
Uint8 i; //is always < 4, so Uint8 seems to be a good idea
fretwork_images = (char **)malloc(sizeof(char *) * 4);
fretwork_images = (char **) malloc(sizeof(char *) * 4);
for (i = 0; i < 4; i++)
fretwork_images[i] = (char *)malloc(sizeof(char) * 1024);
fretwork_images[i] = (char *) malloc(sizeof(char) * 1024);
snprintf(fretwork_images[0], 1024 * sizeof(char), "%simages/magic/fretwork_one.png", api->data_directory);
snprintf(fretwork_images[1], 1024 * sizeof(char), "%simages/magic/fretwork_three.png", api->data_directory);
snprintf(fretwork_images[2], 1024 * sizeof(char), "%simages/magic/fretwork_four.png", api->data_directory);
snprintf(fretwork_images[3], 1024 * sizeof(char), "%simages/magic/fretwork_corner.png", api->data_directory);
snprintf(fretwork_images[0], 1024 * sizeof(char),
"%simages/magic/fretwork_one.png", api->data_directory);
snprintf(fretwork_images[1], 1024 * sizeof(char),
"%simages/magic/fretwork_three.png", api->data_directory);
snprintf(fretwork_images[2], 1024 * sizeof(char),
"%simages/magic/fretwork_four.png", api->data_directory);
snprintf(fretwork_images[3], 1024 * sizeof(char),
"%simages/magic/fretwork_corner.png", api->data_directory);
fretwork_one = IMG_Load(fretwork_images[0]);
fretwork_three = IMG_Load(fretwork_images[1]);
@ -157,7 +175,8 @@ int fretwork_init(magic_api * api)
img_w = fretwork_one->w;
img_h = fretwork_one->h;
snprintf(fname, sizeof(fname), "%ssounds/magic/fretwork.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/fretwork.ogg",
api->data_directory);
fretwork_snd = Mix_LoadWAV(fname);
return (1);
@ -172,37 +191,48 @@ SDL_Surface *fretwork_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/fretwork.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/fretwork.png",
api->data_directory);
return (IMG_Load(fname));
}
int fretwork_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fretwork_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
char *fretwork_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *fretwork_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Fretwork"));
}
char *fretwork_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *fretwork_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return strdup(gettext_noop("Click and drag to draw repetitive patterns."));
return
strdup(gettext_noop("Click and drag to draw repetitive patterns."));
else
return strdup(gettext_noop("Click to surround your picture with repetitive patterns."));
return
strdup(gettext_noop
("Click to surround your picture with repetitive patterns."));
}
int fretwork_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int fretwork_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void fretwork_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void fretwork_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -229,14 +259,18 @@ void fretwork_shutdown(magic_api * api ATTRIBUTE_UNUSED)
free(fretwork_status_of_segments);
}
void fretwork_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
void fretwork_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{
//we've to compute the quantity of segments in each direction
canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
fretwork_segments_x = fretwork_math_ceil(canvas->w, img_w);
@ -246,8 +280,10 @@ void fretwork_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
}
void fretwork_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
void fretwork_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{
free(fretwork_status_of_segments);
fretwork_status_of_segments = NULL;
@ -260,7 +296,7 @@ inline int fretwork_math_ceil(int x, int y)
{
int temp;
temp = (int)x / y;
temp = (int) x / y;
if (x % y)
return temp + 1;
else
@ -279,10 +315,12 @@ inline unsigned int fretwork_get_segment(int x, int y)
return (yy - 1) * fretwork_segments_x + xx;
}
inline void fretwork_extract_coords_from_segment(unsigned int segment, POINT_TYPE * x, POINT_TYPE * y)
inline void fretwork_extract_coords_from_segment(unsigned int segment,
POINT_TYPE * x,
POINT_TYPE * y)
{
*x = ((segment % fretwork_segments_x) - 1) * img_w; //useful to set update_rect as small as possible
*y = (int)(segment / fretwork_segments_x) * img_h;
*y = (int) (segment / fretwork_segments_x) * img_h;
}
/* static void fretwork_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src) */
@ -296,81 +334,87 @@ inline void fretwork_extract_coords_from_segment(unsigned int segment, POINT_TYP
/* api->putpixel(dest, x, y, api->getpixel(src, x, src->h-y)); */
/* } */
static void fretwork_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src)
static void fretwork_flip_flop(void *ptr, SDL_Surface * dest,
SDL_Surface * src)
{
magic_api *api = (magic_api *) ptr;
POINT_TYPE x, y;
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, dest->w - 1 - x, dest->h - 1 - y, api->getpixel(src, x, y));
api->putpixel(dest, dest->w - 1 - x, dest->h - 1 - y,
api->getpixel(src, x, y));
}
static void fretwork_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, _Bool direction)
static void fretwork_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src,
_Bool direction)
//src and dest must have same size
{
magic_api *api = (magic_api *) ptr;
POINT_TYPE x, y;
if (direction) //rotate -90 degs
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, src->h - 1 - x));
}
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, src->h - 1 - x));
}
else //rotate +90 degs
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
}
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
}
}
void fretwork_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect)
{
int left_x, right_x, top_y, bottom_y;
fretwork_segment_modified_last = 0;
if (mode == MODE_PAINT)
{
fretwork_segment_last_clicked = fretwork_get_segment(x, y);
fretwork_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
{
fretwork_segment_last_clicked = fretwork_get_segment(x, y);
fretwork_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
else
{
if (fretwork_full_runs <=
min(fretwork_segments_x, fretwork_segments_y) / 2)
{
if (fretwork_full_runs <= min(fretwork_segments_x, fretwork_segments_y) / 2)
{
left_x = img_w * fretwork_full_runs;
right_x = img_w * fretwork_segments_x - img_w * fretwork_full_runs;
top_y = img_h * fretwork_full_runs;
bottom_y = img_h * fretwork_segments_y - img_h * (fretwork_full_runs - 1);
left_x = img_w * fretwork_full_runs;
right_x = img_w * fretwork_segments_x - img_w * fretwork_full_runs;
top_y = img_h * fretwork_full_runs;
bottom_y =
img_h * fretwork_segments_y - img_h * (fretwork_full_runs - 1);
//left line
api->line((void *)api, which, canvas, snapshot, left_x, top_y, left_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
//left line
api->line((void *) api, which, canvas, snapshot, left_x, top_y, left_x,
bottom_y, img_w / 2, fretwork_draw_wrapper);
//top line
api->line((void *)api, which, canvas, snapshot, left_x, top_y, right_x, top_y, img_w / 2,
fretwork_draw_wrapper);
//top line
api->line((void *) api, which, canvas, snapshot, left_x, top_y, right_x,
top_y, img_w / 2, fretwork_draw_wrapper);
//bottom line
api->line((void *)api, which, canvas, snapshot, left_x, bottom_y, right_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
//bottom line
api->line((void *) api, which, canvas, snapshot, left_x, bottom_y,
right_x, bottom_y, img_w / 2, fretwork_draw_wrapper);
//right line
api->line((void *)api, which, canvas, snapshot, right_x, top_y, right_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
//right line
api->line((void *) api, which, canvas, snapshot, right_x, top_y,
right_x, bottom_y, img_w / 2, fretwork_draw_wrapper);
fretwork_full_runs += 1;
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
fretwork_full_runs += 1;
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
}
}
static Uint8 fretwork_select_image(Uint16 segment)
@ -378,44 +422,49 @@ static Uint8 fretwork_select_image(Uint16 segment)
int take_up, take_down;
int val_up, val_down, val_left, val_right;
int from_top = 0, from_bottom = 0, from_left = 0, from_right = 0;
int from_top_right = 0, from_top_left = 0, from_bottom_right = 0, from_bottom_left = 0;
int from_top_right = 0, from_top_left = 0, from_bottom_right =
0, from_bottom_left = 0;
int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0;
//Checking from were we come...
if (fretwork_segment_modified_last > 0)
{
if (segment == fretwork_segment_modified_last + 1)
from_left = 1;
else if (segment == fretwork_segment_modified_last - 1)
from_right = 1;
else if (segment == fretwork_segment_modified_last - fretwork_segments_x)
from_bottom = 1;
else if (segment == fretwork_segment_modified_last + fretwork_segments_x)
from_top = 1;
{
if (segment == fretwork_segment_modified_last + 1)
from_left = 1;
else if (segment == fretwork_segment_modified_last - 1)
from_right = 1;
else if (segment == fretwork_segment_modified_last - fretwork_segments_x)
from_bottom = 1;
else if (segment == fretwork_segment_modified_last + fretwork_segments_x)
from_top = 1;
// Very very few cases will reach this, segments are joining by the corner
// We need to add a new segment to join by side, adding clockwise
else if (segment == fretwork_segment_modified_last + fretwork_segments_x + 1)
{
from_top_left = 1;
fretwork_segment_to_add = segment - fretwork_segments_x;
}
else if (segment == fretwork_segment_modified_last + fretwork_segments_x - 1)
{
from_top_right = 1;
fretwork_segment_to_add = segment + 1;
}
else if (segment == fretwork_segment_modified_last - fretwork_segments_x - 1)
{
from_bottom_right = 1;
fretwork_segment_to_add = segment + fretwork_segments_x;
}
else if (segment == fretwork_segment_modified_last - fretwork_segments_x + 1)
{
from_bottom_left = 1;
fretwork_segment_to_add = segment - 1;
}
// Very very few cases will reach this, segments are joining by the corner
// We need to add a new segment to join by side, adding clockwise
else if (segment ==
fretwork_segment_modified_last + fretwork_segments_x + 1)
{
from_top_left = 1;
fretwork_segment_to_add = segment - fretwork_segments_x;
}
else if (segment ==
fretwork_segment_modified_last + fretwork_segments_x - 1)
{
from_top_right = 1;
fretwork_segment_to_add = segment + 1;
}
else if (segment ==
fretwork_segment_modified_last - fretwork_segments_x - 1)
{
from_bottom_right = 1;
fretwork_segment_to_add = segment + fretwork_segments_x;
}
else if (segment ==
fretwork_segment_modified_last - fretwork_segments_x + 1)
{
from_bottom_left = 1;
fretwork_segment_to_add = segment - 1;
}
}
take_up = segment - fretwork_segments_x;
if (take_up <= 0)
@ -424,7 +473,7 @@ static Uint8 fretwork_select_image(Uint16 segment)
val_up = fretwork_status_of_segments[take_up];
take_down = segment + fretwork_segments_x;
if (take_down > (signed)(fretwork_segments_x * fretwork_segments_y))
if (take_down > (signed) (fretwork_segments_x * fretwork_segments_y))
val_down = SEG_NONE;
else
val_down = fretwork_status_of_segments[take_down];
@ -440,9 +489,9 @@ static Uint8 fretwork_select_image(Uint16 segment)
val_right = fretwork_status_of_segments[segment + 1];
if (from_left || (val_left & SEG_RIGHT) || from_bottom_left)
{
LEFT = 1;
}
{
LEFT = 1;
}
if (from_right || (val_right & SEG_LEFT) || from_top_right)
RIGHT = 1;
if (from_top || (val_up & SEG_BOTTOM) || from_top_left)
@ -480,8 +529,10 @@ static Uint8 fretwork_select_image(Uint16 segment)
}
static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y ATTRIBUTE_UNUSED, unsigned int segment)
static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x,
int y ATTRIBUTE_UNUSED, unsigned int segment)
{
magic_api *api = (magic_api *) ptr;
SDL_Surface *result, *temp;
@ -491,7 +542,8 @@ static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
use_temp = 0;
if ((segment < 1) | (segment > fretwork_segments_x * fretwork_segments_y))
return;
fretwork_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y);
fretwork_extract_coords_from_segment(segment, &modification_rect.x,
&modification_rect.y);
modification_rect.h = img_w;
modification_rect.w = img_h;
@ -502,73 +554,81 @@ static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
fretwork_status_of_segments[segment] = image; //and write it to global table
result = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask,
fretwork_one->format->Amask);
result =
SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h,
fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask,
fretwork_one->format->Gmask,
fretwork_one->format->Bmask,
fretwork_one->format->Amask);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask,
fretwork_one->format->Amask);
temp =
SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h,
fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask,
fretwork_one->format->Gmask,
fretwork_one->format->Bmask,
fretwork_one->format->Amask);
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
switch (image)
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_one, NULL, result, NULL);
break;
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_one, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
fretwork_rotate(api, temp, fretwork_one, 1);
use_temp = 1;
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
fretwork_rotate(api, temp, fretwork_one, 1);
use_temp = 1;
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(fretwork_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(fretwork_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_three);
use_temp = 1;
break;
case SEG_LEFT_RIGHT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_three);
use_temp = 1;
break;
case SEG_LEFT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 0);
use_temp = 1;
break;
case SEG_LEFT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 0);
use_temp = 1;
break;
case SEG_RIGHT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 1);
use_temp = 1;
break;
case SEG_RIGHT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 1);
use_temp = 1;
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(fretwork_corner, NULL, result, NULL);
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(fretwork_corner, NULL, result, NULL);
break;
case SEG_RIGHT_BOTTOM:
fretwork_rotate(api, temp, fretwork_corner, 1);
use_temp = 1;
break;
case SEG_RIGHT_BOTTOM:
fretwork_rotate(api, temp, fretwork_corner, 1);
use_temp = 1;
break;
case SEG_LEFT_TOP:
fretwork_rotate(api, temp, fretwork_corner, 0);
use_temp = 1;
break;
case SEG_LEFT_TOP:
fretwork_rotate(api, temp, fretwork_corner, 0);
use_temp = 1;
break;
case SEG_LEFT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_corner);
use_temp = 1;
break;
}
case SEG_LEFT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_corner);
use_temp = 1;
break;
}
if (use_temp)
SDL_BlitSurface(temp, NULL, result, NULL);
@ -580,58 +640,67 @@ static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
}
static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
fretwork_segment_modified = fretwork_get_segment(x, y);
fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified);
fretwork_draw((void *) ptr, which, canvas, last, x, y,
fretwork_segment_modified);
if (fretwork_segment_modified_last > 0)
{
fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified_last);
fretwork_extract_coords_from_segment(fretwork_segment_start_rectangle, &modification_rect.x,
&modification_rect.y);
modification_rect.w = fretwork_update_rectangle_width * img_w;
modification_rect.h = fretwork_update_rectangle_height * img_h;
}
{
fretwork_draw((void *) ptr, which, canvas, last, x, y,
fretwork_segment_modified_last);
fretwork_extract_coords_from_segment(fretwork_segment_start_rectangle,
&modification_rect.x,
&modification_rect.y);
modification_rect.w = fretwork_update_rectangle_width * img_w;
modification_rect.h = fretwork_update_rectangle_height * img_h;
}
if (fretwork_segment_to_add > 0)
{
fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_to_add);
fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified_last);
fretwork_segment_to_add = 0;
}
{
fretwork_draw((void *) ptr, which, canvas, last, x, y,
fretwork_segment_to_add);
fretwork_draw((void *) ptr, which, canvas, last, x, y,
fretwork_segment_modified_last);
fretwork_segment_to_add = 0;
}
fretwork_segment_modified_last = fretwork_segment_modified;
}
void fretwork_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int ox,
int oy, int x, int y, SDL_Rect * update_rect)
{
int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h;
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
&& ((signed)ox > 0) && ((signed)oy > 0))
{
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, img_w / 2, fretwork_draw_wrapper);
// This should be improved, maybe passed to fretwork_draw()
start_x = min(ox, x);
end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
segment_start = fretwork_get_segment(start_x - img_w, start_y - img_h);
segment_end = fretwork_get_segment(end_x + img_w, end_y + img_h);
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w)
&& (oy < canvas->h) && ((signed) x > 0) && ((signed) y > 0)
&& ((signed) ox > 0) && ((signed) oy > 0))
{
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, img_w / 2,
fretwork_draw_wrapper);
// This should be improved, maybe passed to fretwork_draw()
start_x = min(ox, x);
end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
segment_start = fretwork_get_segment(start_x - img_w, start_y - img_h);
segment_end = fretwork_get_segment(end_x + img_w, end_y + img_h);
x = ((segment_start % fretwork_segments_x) - 1) * img_w;
y = (int)(segment_start / fretwork_segments_x) * img_h;
w = ((segment_end % fretwork_segments_x) - 1) * img_w - x + img_w;
h = (int)(segment_end / fretwork_segments_x) * img_h - y + img_h;
x = ((segment_start % fretwork_segments_x) - 1) * img_w;
y = (int) (segment_start / fretwork_segments_x) * img_h;
w = ((segment_end % fretwork_segments_x) - 1) * img_w - x + img_w;
h = (int) (segment_end / fretwork_segments_x) * img_h - y + img_h;
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
}

View file

@ -46,18 +46,24 @@ SDL_Surface *glasstile_get_icon(magic_api * api, int which);
char *glasstile_get_name(magic_api * api, int which);
int glasstile_get_group(magic_api * api, int which);
char *glasstile_get_description(magic_api * api, int which, int mode);
static void do_glasstile(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_glasstile(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void glasstile_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void glasstile_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void glasstile_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void glasstile_shutdown(magic_api * api);
void glasstile_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int glasstile_requires_colors(magic_api * api, int which);
void glasstile_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void glasstile_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void glasstile_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void glasstile_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int glasstile_modes(magic_api * api, int which);
Uint32 glasstile_api_version(void)
@ -74,7 +80,8 @@ int glasstile_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/glasstile.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/glasstile.ogg",
api->data_directory);
glasstile_snd = Mix_LoadWAV(fname);
glasstile_hit = NULL;
@ -94,35 +101,45 @@ SDL_Surface *glasstile_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/glasstile.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/glasstile.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *glasstile_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *glasstile_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Glass Tile")));
}
// Return our groups
int glasstile_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int glasstile_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *glasstile_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *glasstile_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return (strdup(gettext_noop("Click and drag the mouse to put glass tile over your picture.")));
return (strdup
(gettext_noop
("Click and drag the mouse to put glass tile over your picture.")));
else
return (strdup(gettext_noop("Click to cover your entire picture in glass tiles.")));
return (strdup
(gettext_noop
("Click to cover your entire picture in glass tiles.")));
}
// Do the effect:
static void do_glasstile(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_glasstile(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy, xl, xr, yt, yb;
@ -153,61 +170,66 @@ static void do_glasstile(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * ca
/* Apply the effect: */
for (yy = -GT_SIZE; yy < GT_SIZE; yy = yy + 2)
{
for (xx = -GT_SIZE; xx < GT_SIZE; xx = xx + 2)
{
for (xx = -GT_SIZE; xx < GT_SIZE; xx = xx + 2)
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy), last->format, &r2, &g2, &b2);
SDL_GetRGB(api->getpixel(last, x + xx, y + yy + 1), last->format, &r3, &g3, &b3);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy + 1), last->format, &r4, &g4, &b4);
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1,
&b1);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy), last->format, &r2,
&g2, &b2);
SDL_GetRGB(api->getpixel(last, x + xx, y + yy + 1), last->format, &r3,
&g3, &b3);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy + 1), last->format,
&r4, &g4, &b4);
r = (r1 + r2 + r3 + r4) >> 2;
g = (g1 + g2 + g3 + g4) >> 2;
b = (b1 + b2 + b3 + b4) >> 2;
r = (r1 + r2 + r3 + r4) >> 2;
g = (g1 + g2 + g3 + g4) >> 2;
b = (b1 + b2 + b3 + b4) >> 2;
if (xx <= -GT_SIZE + 2 || yy == -GT_SIZE + 2)
{
r = min(255, r + 64);
g = min(255, g + 64);
b = min(255, b + 64);
}
else if (xx >= GT_SIZE - 3 || yy >= GT_SIZE - 3)
{
r = max(0, r - 64);
g = max(0, g - 64);
b = max(0, b - 64);
}
if (xx <= -GT_SIZE + 2 || yy == -GT_SIZE + 2)
{
r = min(255, r + 64);
g = min(255, g + 64);
b = min(255, b + 64);
}
else if (xx >= GT_SIZE - 3 || yy >= GT_SIZE - 3)
{
r = max(0, r - 64);
g = max(0, g - 64);
b = max(0, b - 64);
}
rgb = SDL_MapRGB(canvas->format, r, g, b);
rgb = SDL_MapRGB(canvas->format, r, g, b);
xl = (xx / 3) - GT_SIZE + (GT_SIZE / 3);
xr = (xx / 3) + (GT_SIZE * 2) / 3;
yt = (yy / 3) - GT_SIZE + (GT_SIZE / 3);
yb = (yy / 3) + (GT_SIZE * 2) / 3;
xl = (xx / 3) - GT_SIZE + (GT_SIZE / 3);
xr = (xx / 3) + (GT_SIZE * 2) / 3;
yt = (yy / 3) - GT_SIZE + (GT_SIZE / 3);
yb = (yy / 3) + (GT_SIZE * 2) / 3;
api->putpixel(canvas, x + xl, y + yt, rgb);
api->putpixel(canvas, x + xx / 2, y + yt, rgb);
api->putpixel(canvas, x + xr, y + yt, rgb);
api->putpixel(canvas, x + xl, y + yt, rgb);
api->putpixel(canvas, x + xx / 2, y + yt, rgb);
api->putpixel(canvas, x + xr, y + yt, rgb);
api->putpixel(canvas, x + xl, y + yy / 2, rgb);
api->putpixel(canvas, x + xr, y + yy / 2, rgb);
api->putpixel(canvas, x + xl, y + yy / 2, rgb);
api->putpixel(canvas, x + xr, y + yy / 2, rgb);
api->putpixel(canvas, x + xl, y + yb, rgb);
api->putpixel(canvas, x + xx / 2, y + yb, rgb);
api->putpixel(canvas, x + xr, y + yb, rgb);
api->putpixel(canvas, x + xl, y + yb, rgb);
api->putpixel(canvas, x + xx / 2, y + yb, rgb);
api->putpixel(canvas, x + xr, y + yb, rgb);
/* Center */
/* Center */
api->putpixel(canvas, x + xx / 2, y + yy / 2, rgb);
}
api->putpixel(canvas, x + xx / 2, y + yy / 2, rgb);
}
}
}
// Affect the canvas on drag:
void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_glasstile);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_glasstile);
update_rect->x = 0;
update_rect->y = 0;
@ -240,20 +262,21 @@ void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void glasstile_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
int xx, yy;
if (glasstile_hit == NULL)
{
glasstile_hit_ysize = (canvas->h / GT_SIZE) + 1;
glasstile_hit_xsize = (canvas->w / GT_SIZE) + 1;
{
glasstile_hit_ysize = (canvas->h / GT_SIZE) + 1;
glasstile_hit_xsize = (canvas->w / GT_SIZE) + 1;
glasstile_hit = (int * *)malloc(sizeof(int *) * glasstile_hit_ysize);
glasstile_hit = (int * *) malloc(sizeof(int *) * glasstile_hit_ysize);
for (yy = 0; yy < glasstile_hit_ysize; yy++)
glasstile_hit[yy] = (int *)malloc(sizeof(int) * glasstile_hit_xsize);
}
for (yy = 0; yy < glasstile_hit_ysize; yy++)
glasstile_hit[yy] = (int *) malloc(sizeof(int) * glasstile_hit_xsize);
}
for (yy = 0; yy < glasstile_hit_ysize; yy++)
for (xx = 0; xx < glasstile_hit_xsize; xx++)
@ -262,24 +285,27 @@ void glasstile_click(magic_api * api, int which, int mode,
if (mode == MODE_PAINT)
glasstile_drag(api, which, canvas, last, x, y, x, y, update_rect);
else if (mode == MODE_FULLSCREEN)
{
for (y = 0; y < canvas->h; y = y + GT_SIZE)
for (x = 0; x < canvas->w; x = x + GT_SIZE)
do_glasstile(api, which, canvas, last, x, y);
{
for (y = 0; y < canvas->h; y = y + GT_SIZE)
for (x = 0; x < canvas->w; x = x + GT_SIZE)
do_glasstile(api, which, canvas, last, x, y);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(glasstile_snd, 128, 255);
}
api->playsound(glasstile_snd, 128, 255);
}
}
// Affect the canvas on release:
void glasstile_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void glasstile_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -292,39 +318,45 @@ void glasstile_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(glasstile_snd);
if (glasstile_hit != NULL)
{
for (y = 0; y < glasstile_hit_ysize; y++)
{
for (y = 0; y < glasstile_hit_ysize; y++)
{
if (glasstile_hit[y] != NULL)
free(glasstile_hit[y]);
}
free(glasstile_hit);
if (glasstile_hit[y] != NULL)
free(glasstile_hit[y]);
}
free(glasstile_hit);
}
}
// Record the color from Tux Paint:
void glasstile_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void glasstile_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int glasstile_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int glasstile_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void glasstile_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void glasstile_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void glasstile_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void glasstile_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int glasstile_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int glasstile_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}

View file

@ -50,18 +50,22 @@ char *grass_get_name(magic_api * api, int which);
int grass_get_group(magic_api * api, int which);
char *grass_get_description(magic_api * api, int which, int mode);
void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void grass_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void grass_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void grass_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void grass_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void grass_shutdown(magic_api * api);
void grass_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int grass_requires_colors(magic_api * api, int which);
static void do_grass(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_grass(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static int log2int(int x);
void grass_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void grass_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void grass_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void grass_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int grass_modes(magic_api * api, int which);
@ -70,10 +74,12 @@ int grass_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/grass.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/grass.wav",
api->data_directory);
grass_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%simages/magic/grass_data.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/grass_data.png",
api->data_directory);
img_grass = IMG_Load(fname);
return (1);
@ -97,50 +103,58 @@ SDL_Surface *grass_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/grass.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/grass.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *grass_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *grass_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Grass")));
}
// Return our groups:
int grass_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int grass_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *grass_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *grass_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to draw grass. Dont forget the dirt!")));
return (strdup
(gettext_noop
("Click and drag to draw grass. Dont forget the dirt!")));
}
// Affect the canvas on drag:
void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 4, do_grass);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 4, do_grass);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 64;
update_rect->y = oy - 64;
@ -152,14 +166,18 @@ void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void grass_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
grass_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void grass_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void grass_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -171,7 +189,8 @@ void grass_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void grass_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void grass_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
grass_r = r;
grass_g = g;
@ -179,13 +198,15 @@ void grass_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b
}
// Use colors:
int grass_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int grass_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
static void do_grass(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
@ -198,50 +219,63 @@ static void do_grass(void *ptr, int which ATTRIBUTE_UNUSED,
if (!api->button_down())
bucket = 0;
bucket += (3.5 + (rand() / (double)RAND_MAX)) * 7.0;
bucket += (3.5 + (rand() / (double) RAND_MAX)) * 7.0;
while (bucket >= 0)
{
int rank =
log2int(((double) y / canvas->h) *
(0.99 + (rand() / (double) RAND_MAX)) * 64);
int ah = 1 << rank;
bucket -= ah;
src.x = (rand() % 4) * 64;
src.y = ah;
src.w = 64;
src.h = ah;
dest.x = x - 32;
dest.y = y - 30 + (int) ((rand() / (double) RAND_MAX) * 30);
tmp_red =
api->sRGB_to_linear(grass_r) * 2.0 + (rand() / (double) RAND_MAX);
tmp_green =
api->sRGB_to_linear(grass_g) * 2.0 + (rand() / (double) RAND_MAX);
tmp_blue = api->sRGB_to_linear(grass_b) * 2.0 + api->sRGB_to_linear(17);
for (yy = 0; yy < ah; yy++)
{
int rank = log2int(((double)y / canvas->h) * (0.99 + (rand() / (double)RAND_MAX)) * 64);
int ah = 1 << rank;
for (xx = 0; xx < 64; xx++)
{
double rd, gd, bd;
bucket -= ah;
src.x = (rand() % 4) * 64;
src.y = ah;
src.w = 64;
src.h = ah;
SDL_GetRGBA(api->getpixel(img_grass, xx + src.x, yy + src.y),
img_grass->format, &r, &g, &b, &a);
dest.x = x - 32;
dest.y = y - 30 + (int)((rand() / (double)RAND_MAX) * 30);
rd = api->sRGB_to_linear(r) * 8.0 + tmp_red;
rd = rd * (a / 255.0) / 11.0;
gd = api->sRGB_to_linear(g) * 8.0 + tmp_green;
gd = gd * (a / 255.0) / 11.0;
bd = api->sRGB_to_linear(b) * 8.0 + tmp_blue;
bd = bd * (a / 255.0) / 11.0;
tmp_red = api->sRGB_to_linear(grass_r) * 2.0 + (rand() / (double)RAND_MAX);
tmp_green = api->sRGB_to_linear(grass_g) * 2.0 + (rand() / (double)RAND_MAX);
tmp_blue = api->sRGB_to_linear(grass_b) * 2.0 + api->sRGB_to_linear(17);
SDL_GetRGB(api->getpixel(canvas, xx + dest.x, yy + dest.y),
canvas->format, &r, &g, &b);
for (yy = 0; yy < ah; yy++)
{
for (xx = 0; xx < 64; xx++)
{
double rd, gd, bd;
r =
api->linear_to_sRGB(api->sRGB_to_linear(r) * (1.0 - a / 255.0) +
rd);
g =
api->linear_to_sRGB(api->sRGB_to_linear(g) * (1.0 - a / 255.0) +
gd);
b =
api->linear_to_sRGB(api->sRGB_to_linear(b) * (1.0 - a / 255.0) +
bd);
SDL_GetRGBA(api->getpixel(img_grass, xx + src.x, yy + src.y), img_grass->format, &r, &g, &b, &a);
rd = api->sRGB_to_linear(r) * 8.0 + tmp_red;
rd = rd * (a / 255.0) / 11.0;
gd = api->sRGB_to_linear(g) * 8.0 + tmp_green;
gd = gd * (a / 255.0) / 11.0;
bd = api->sRGB_to_linear(b) * 8.0 + tmp_blue;
bd = bd * (a / 255.0) / 11.0;
SDL_GetRGB(api->getpixel(canvas, xx + dest.x, yy + dest.y), canvas->format, &r, &g, &b);
r = api->linear_to_sRGB(api->sRGB_to_linear(r) * (1.0 - a / 255.0) + rd);
g = api->linear_to_sRGB(api->sRGB_to_linear(g) * (1.0 - a / 255.0) + gd);
b = api->linear_to_sRGB(api->sRGB_to_linear(b) * (1.0 - a / 255.0) + bd);
api->putpixel(canvas, xx + dest.x, yy + dest.y, SDL_MapRGB(canvas->format, r, g, b));
}
}
api->putpixel(canvas, xx + dest.x, yy + dest.y,
SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
// this one rounds down
@ -253,19 +287,21 @@ static int log2int(int x)
return 0;
x >>= 1;
while (x)
{
x >>= 1;
y++;
}
{
x >>= 1;
y++;
}
return y;
}
void grass_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void grass_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void grass_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void grass_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -19,8 +19,8 @@
#define deg_cos(x) cos((x) * M_PI / 180.0)
#define deg_sin(x) sin((x) * M_PI / 180.0)
#define GRID_SIZE 16 /* Size of the grid, and hence max size of the circle (it may fill more, into a square shape) */
#define OFFSET_RADIUS 2 /* Radius for when offsetting C, M, Y, and K colors by their angles (see `chan_angles[]`) */
#define GRID_SIZE 16 /* Size of the grid, and hence max size of the circle (it may fill more, into a square shape) */
#define OFFSET_RADIUS 2 /* Radius for when offsetting C, M, Y, and K colors by their angles (see `chan_angles[]`) */
enum
{
@ -47,9 +47,9 @@ const int groups[NUM_TOOLS] = {
const char *descs[NUM_TOOLS][2] = {
{
gettext_noop("Click and drag to turn your drawing into a newspaper."),
gettext_noop("Click to turn your drawing into a newspaper."),
},
gettext_noop("Click and drag to turn your drawing into a newspaper."),
gettext_noop("Click to turn your drawing into a newspaper."),
},
};
Mix_Chunk *snd_effect[NUM_TOOLS];
@ -59,8 +59,10 @@ static SDL_Surface *canvas_backup, *square;
/* Function Prototypes: */
void halftone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void halftone_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void halftone_line_callback(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
Uint32 halftone_api_version(void);
int halftone_init(magic_api * api);
int halftone_get_tool_count(magic_api * api);
@ -72,12 +74,16 @@ int halftone_requires_colors(magic_api * api, int which);
int halftone_modes(magic_api * api, int which);
void halftone_shutdown(magic_api * api);
void halftone_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
void halftone_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void halftone_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void halftone_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void halftone_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void halftone_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void halftone_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void halftone_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void halftone_rgb2cmyk(Uint8 r, Uint8 g, Uint8 b, float cmyk[]);
Uint32 halftone_api_version(void)
@ -94,11 +100,12 @@ int halftone_init(magic_api * api)
square = NULL;
for (i = 0; i < NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, snd_filenames[i]);
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
snd_filenames[i]);
snd_effect[i] = Mix_LoadWAV(fname);
}
snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
@ -113,7 +120,8 @@ SDL_Surface *halftone_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
icon_filenames[which]);
return (IMG_Load(fname));
}
@ -134,7 +142,8 @@ int halftone_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
return groups[which];
}
char *halftone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *halftone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
const char *our_desc_english;
const char *our_desc_localized;
@ -145,12 +154,14 @@ char *halftone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int
return (strdup(our_desc_localized));
}
int halftone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int halftone_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
int halftone_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int halftone_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}
@ -159,8 +170,10 @@ void halftone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{
int i;
for (i = 0; i < NUM_TOOLS; i++) {
if (snd_effect[i] != NULL) {
for (i = 0; i < NUM_TOOLS; i++)
{
if (snd_effect[i] != NULL)
{
Mix_FreeChunk(snd_effect[i]);
}
}
@ -170,50 +183,53 @@ void halftone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
void halftone_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect)
{
int full_x, full_y;
if (mode == MODE_PAINT)
{
halftone_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
{
halftone_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
else
{
for (full_y = 0; full_y < canvas->h; full_y += GRID_SIZE)
{
for (full_y = 0; full_y < canvas->h; full_y += GRID_SIZE)
{
for (full_x = 0; full_x < canvas->w; full_x += GRID_SIZE)
{
halftone_line_callback(api, which, canvas, snapshot, full_x, full_y);
}
}
api->playsound(snd_effect[which], 128, 255);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
for (full_x = 0; full_x < canvas->w; full_x += GRID_SIZE)
{
halftone_line_callback(api, which, canvas, snapshot, full_x, full_y);
}
}
api->playsound(snd_effect[which], 128, 255);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
}
void halftone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 4, halftone_line_callback);
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, 4,
halftone_line_callback);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
ox = (ox / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
oy = (oy / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
@ -239,33 +255,39 @@ enum
};
Uint8 chan_colors[NUM_CHANS][3] = {
{0, 255, 255}, /* Cyan */
{255, 0, 255}, /* Magenta */
{255, 255, 0}, /* Yellow */
{0, 0, 0} /* Black */
{0, 255, 255}, /* Cyan */
{255, 0, 255}, /* Magenta */
{255, 255, 0}, /* Yellow */
{0, 0, 0} /* Black */
};
int chan_angles[NUM_CHANS] = {
75, /* Cyan */
15, /* Magenta */
90, /* Yellow */
45 /* Black */
75, /* Cyan */
15, /* Magenta */
90, /* Yellow */
45 /* Black */
};
void halftone_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void halftone_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
void halftone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED,
Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
void halftone_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x,
int y)
{
Uint8 r, g, b, or, og, ob;
Uint32 total_r, total_g, total_b;
@ -285,24 +307,25 @@ void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
y = (y / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
if (api->touched(x, y))
{
return;
}
{
return;
}
/* Get the average color around the mouse */
total_r = total_g = total_b = 0;
px_cnt = 0;
for (xxx = -(GRID_SIZE / 2); xxx < (GRID_SIZE / 2); xxx++)
{
for (yyy = -(GRID_SIZE / 2); yyy < (GRID_SIZE / 2); yyy++)
{
for (yyy = -(GRID_SIZE / 2); yyy < (GRID_SIZE / 2); yyy++)
{
SDL_GetRGB(api->getpixel(canvas_backup, x + xxx, y + yyy), canvas_backup->format, &r, &g, &b);
total_r += r;
total_g += g;
total_b += b;
px_cnt++;
}
SDL_GetRGB(api->getpixel(canvas_backup, x + xxx, y + yyy),
canvas_backup->format, &r, &g, &b);
total_r += r;
total_g += g;
total_b += b;
px_cnt++;
}
}
total_r /= px_cnt;
total_g /= px_cnt;
@ -314,42 +337,42 @@ void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
/* Draw C, M, Y and K blobs into our 'square' surface */
for (channel = 0; channel < NUM_CHANS; channel++)
{
for (xxx = -(GRID_SIZE / 2) - 1; xxx < (GRID_SIZE / 2) + 1; xxx++)
{
for (xxx = -(GRID_SIZE / 2) - 1; xxx < (GRID_SIZE / 2) + 1; xxx++)
for (yyy = -(GRID_SIZE / 2) - 1; yyy < (GRID_SIZE / 2) + 1; yyy++)
{
/* A circle blob, radius based upon channel (C, M, Y or K) strength for this color */
ox = xxx + deg_cos(chan_angles[channel]) * OFFSET_RADIUS;
oy = yyy + deg_sin(chan_angles[channel]) * OFFSET_RADIUS;
sqx = ((GRID_SIZE / 2) + ox) % GRID_SIZE;
sqy = ((GRID_SIZE / 2) + oy) % GRID_SIZE;
/* Use intensity of the CMKY channel in question to decide
how big of a circle to paint */
if (api->in_circle(xxx, yyy, cmyk[channel] * GRID_SIZE))
{
for (yyy = -(GRID_SIZE / 2) - 1; yyy < (GRID_SIZE / 2) + 1; yyy++)
{
/* A circle blob, radius based upon channel (C, M, Y or K) strength for this color */
/* Use the pure C, Y, M, or K color to paint with */
r = chan_colors[channel][0];
g = chan_colors[channel][1];
b = chan_colors[channel][2];
ox = xxx + deg_cos(chan_angles[channel]) * OFFSET_RADIUS;
oy = yyy + deg_sin(chan_angles[channel]) * OFFSET_RADIUS;
sqx = ((GRID_SIZE / 2) + ox) % GRID_SIZE;
sqy = ((GRID_SIZE / 2) + oy) % GRID_SIZE;
/* Use intensity of the CMKY channel in question to decide
how big of a circle to paint */
if (api->in_circle(xxx, yyy, cmyk[channel] * GRID_SIZE))
{
/* Use the pure C, Y, M, or K color to paint with */
r = chan_colors[channel][0];
g = chan_colors[channel][1];
b = chan_colors[channel][2];
/* Additively blend with whatever we have in the
'square' buffer (which starts as white)
(since the target is RGB, we use `min()`) */
SDL_GetRGB(api->getpixel(square, sqx, sqy), square->format, &or, &og, &ob);
pixel = SDL_MapRGB(square->format,
min((Uint8) (r * 2.0), or),
min((Uint8) (g * 2.0), og),
min((Uint8) (b * 2.0), ob)
);
api->putpixel(square, sqx, sqy, pixel);
}
}
/* Additively blend with whatever we have in the
'square' buffer (which starts as white)
(since the target is RGB, we use `min()`) */
SDL_GetRGB(api->getpixel(square, sqx, sqy), square->format, &or,
&og, &ob);
pixel =
SDL_MapRGB(square->format, min((Uint8) (r * 2.0), or),
min((Uint8) (g * 2.0), og), min((Uint8) (b * 2.0),
ob));
api->putpixel(square, sqx, sqy, pixel);
}
}
}
}
/* Copy the results to the canvas */
dest.x = x - GRID_SIZE / 2;
@ -360,27 +383,33 @@ void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_BlitSurface(square, NULL, canvas, &dest);
}
void halftone_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
void halftone_switchin(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
if (canvas_backup == NULL)
{
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, api->canvas_w, api->canvas_h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
}
{
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, api->canvas_w, api->canvas_h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
}
if (square == NULL)
{
square =
SDL_CreateRGBSurface(SDL_SWSURFACE, GRID_SIZE, GRID_SIZE, canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
}
{
square =
SDL_CreateRGBSurface(SDL_SWSURFACE, GRID_SIZE, GRID_SIZE,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask,
canvas->format->Bmask, canvas->format->Amask);
}
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
}
void halftone_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void halftone_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
@ -393,25 +422,25 @@ void halftone_rgb2cmyk(Uint8 r, Uint8 g, Uint8 b, float cmyk[])
by Alexei Kourbatov <alexei@kourbatov.com> */
if (r == 0 && g == 0 && b == 0)
{
/* Black */
c = 0.0;
m = 0.0;
y = 0.0;
k = 1.0;
}
{
/* Black */
c = 0.0;
m = 0.0;
y = 0.0;
k = 1.0;
}
else
{
c = 1.0 - (((float)r) / 255.0);
m = 1.0 - (((float)g) / 255.0);
y = 1.0 - (((float)b) / 255.0);
{
c = 1.0 - (((float) r) / 255.0);
m = 1.0 - (((float) g) / 255.0);
y = 1.0 - (((float) b) / 255.0);
mincmy = min(c, min(m, y));
c = (c - mincmy) / (1.0 - mincmy);
m = (m - mincmy) / (1.0 - mincmy);
y = (y - mincmy) / (1.0 - mincmy);
k = mincmy;
}
mincmy = min(c, min(m, y));
c = (c - mincmy) / (1.0 - mincmy);
m = (m - mincmy) / (1.0 - mincmy);
y = (y - mincmy) / (1.0 - mincmy);
k = mincmy;
}
cmyk[0] = c;
cmyk[1] = m;

View file

@ -67,18 +67,24 @@ SDL_Surface *kalidescope_get_icon(magic_api * api, int which);
char *kalidescope_get_name(magic_api * api, int which);
int kalidescope_get_group(magic_api * api, int which);
char *kalidescope_get_description(magic_api * api, int which, int mode);
static void do_kalidescope(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_kalidescope(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void kalidescope_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void kalidescope_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void kalidescope_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void kalidescope_shutdown(magic_api * api);
int kalidescope_requires_colors(magic_api * api, int which);
void kalidescope_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void kalidescope_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void kalidescope_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void kalidescope_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void kalidescope_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int kalidescope_modes(magic_api * api, int which);
Uint32 kalidescope_api_version(void)
@ -91,7 +97,8 @@ int kalidescope_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/kaleidoscope.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/kaleidoscope.ogg",
api->data_directory);
kalidescope_snd = Mix_LoadWAV(fname);
return (1);
@ -107,7 +114,8 @@ SDL_Surface *kalidescope_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, kal_icon_names[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
kal_icon_names[which]);
return (IMG_Load(fname));
}
@ -116,61 +124,69 @@ SDL_Surface *kalidescope_get_icon(magic_api * api, int which)
char *kalidescope_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{
if (which == KAL_LR)
{
return (strdup(gettext_noop("Symmetric Left/Right")));
}
{
return (strdup(gettext_noop("Symmetric Left/Right")));
}
else if (which == KAL_UD)
{
return (strdup(gettext_noop("Symmetric Up/Down")));
}
{
return (strdup(gettext_noop("Symmetric Up/Down")));
}
else if (which == KAL_PATTERN)
{
return (strdup(gettext_noop("Pattern")));
}
{
return (strdup(gettext_noop("Pattern")));
}
else if (which == KAL_TILES)
{
return (strdup(gettext_noop("Tiles")));
}
{
return (strdup(gettext_noop("Tiles")));
}
else
{ /* KAL_BOTH */
return (strdup(gettext_noop("Kaleidoscope")));
}
{ /* KAL_BOTH */
return (strdup(gettext_noop("Kaleidoscope")));
}
}
// Return our group (all the same):
int kalidescope_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int kalidescope_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PATTERN_PAINTING;
}
// Return our descriptions, localized:
char *kalidescope_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *kalidescope_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (which == KAL_LR)
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw with two brushes that are symmetric across the left and right of your picture.")));
}
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw with two brushes that are symmetric across the left and right of your picture.")));
}
else if (which == KAL_UD)
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw with two brushes that are symmetric across the top and bottom of your picture.")));
}
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw with two brushes that are symmetric across the top and bottom of your picture.")));
}
else if (which == KAL_PATTERN)
{
return (strdup(gettext_noop("Click and drag the mouse to draw a pattern across the picture.")));
}
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw a pattern across the picture.")));
}
else if (which == KAL_TILES)
{
return (strdup(gettext_noop("Click and drag the mouse to draw a pattern that is symmetric across the picture.")));
}
{
return (strdup
(gettext_noop
("Click and drag the mouse to draw a pattern that is symmetric across the picture.")));
}
else
{ /* KAL_BOTH */
return (strdup(gettext_noop("Click and drag the mouse to draw with symmetric brushes (a kaleidoscope).")));
}
{ /* KAL_BOTH */
return (strdup
(gettext_noop
("Click and drag the mouse to draw with symmetric brushes (a kaleidoscope).")));
}
}
// Do the effect:
@ -183,49 +199,55 @@ static void do_kalidescope(void *ptr, int which, SDL_Surface * canvas,
int i, j;
Uint32 colr;
colr = SDL_MapRGB(canvas->format, kalidescope_r, kalidescope_g, kalidescope_b);
colr =
SDL_MapRGB(canvas->format, kalidescope_r, kalidescope_g, kalidescope_b);
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
for (xx = -8; xx < 8; xx++)
if (api->in_circle(xx, yy, 8))
{
api->putpixel(canvas, x + xx, y + yy, colr);
if (which == KAL_LR || which == KAL_BOTH)
{
if (api->in_circle(xx, yy, 8))
api->putpixel(canvas, canvas->w - 1 - x + xx, y + yy, colr);
if (which == KAL_BOTH)
{
api->putpixel(canvas, canvas->w - 1 - x + xx,
canvas->h - 1 - y + yy, colr);
}
}
if (which == KAL_UD || which == KAL_BOTH)
{
api->putpixel(canvas, x + xx, canvas->h - 1 - y + yy, colr);
}
if (which == KAL_PATTERN || which == KAL_TILES)
{
for (i = 0; i <= canvas->w; i += square_size)
for (j = 0; j <= canvas->h; j += square_size)
{
api->putpixel(canvas, x + xx, y + yy, colr);
if (which == KAL_LR || which == KAL_BOTH)
{
api->putpixel(canvas, canvas->w - 1 - x + xx, y + yy, colr);
if (which == KAL_BOTH)
{
api->putpixel(canvas, canvas->w - 1 - x + xx, canvas->h - 1 - y + yy, colr);
}
}
if (which == KAL_UD || which == KAL_BOTH)
{
api->putpixel(canvas, x + xx, canvas->h - 1 - y + yy, colr);
}
if (which == KAL_PATTERN || which == KAL_TILES)
{
for (i = 0; i <= canvas->w; i += square_size)
for (j = 0; j <= canvas->h; j += square_size)
{
api->putpixel(canvas, i + xx + x % square_size, j + yy + y % square_size, colr);
if (which == KAL_TILES)
api->putpixel(canvas, i + yy + y % square_size, j + xx + x % square_size, colr);
}
}
api->putpixel(canvas, i + xx + x % square_size,
j + yy + y % square_size, colr);
if (which == KAL_TILES)
api->putpixel(canvas, i + yy + y % square_size,
j + xx + x % square_size, colr);
}
}
}
}
}
}
// Affect the canvas on drag:
void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_kalidescope);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_kalidescope);
update_rect->x = 0;
update_rect->y = 0;
@ -237,15 +259,18 @@ void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void kalidescope_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
kalidescope_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void kalidescope_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
api->stopsound();
}
@ -258,7 +283,8 @@ void kalidescope_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void kalidescope_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void kalidescope_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
kalidescope_r = r;
kalidescope_g = g;
@ -266,22 +292,28 @@ void kalidescope_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, U
}
// Use colors:
int kalidescope_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int kalidescope_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void kalidescope_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void kalidescope_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void kalidescope_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void kalidescope_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int kalidescope_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int kalidescope_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -47,18 +47,22 @@ SDL_Surface *light_get_icon(magic_api * api, int which);
char *light_get_name(magic_api * api, int which);
int light_get_group(magic_api * api, int which);
char *light_get_description(magic_api * api, int which, int mode);
static void do_light(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_light(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void light_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void light_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void light_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void light_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void light_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void light_shutdown(magic_api * api);
void light_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int light_requires_colors(magic_api * api, int which);
void light_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void light_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void light_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void light_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int light_modes(magic_api * api, int which);
@ -73,10 +77,12 @@ int light_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/light1.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/light1.ogg",
api->data_directory);
light1_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/light2.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/light2.ogg",
api->data_directory);
light2_snd = Mix_LoadWAV(fname);
return (1);
@ -93,33 +99,41 @@ SDL_Surface *light_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/light.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/light.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *light_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *light_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Light")));
}
// Return our groups:
int light_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int light_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *light_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *light_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to draw a beam of light on your picture.")));
return (strdup
(gettext_noop
("Click and drag to draw a beam of light on your picture.")));
}
// Do the effect:
static void do_light(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
static void do_light(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
@ -129,74 +143,76 @@ static void do_light(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas
float adj;
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
for (xx = -8; xx < 8; xx++)
if (api->in_circle(xx, yy, 8))
{
pix = api->getpixel(canvas, x + xx, y + yy);
SDL_GetRGB(pix, canvas->format, &r, &g, &b);
adj = (7.99 - sqrt(abs(xx * yy))) / 128.0;
api->rgbtohsv(r, g, b, &h, &s, &v);
v = min((float) 1.0, v + adj);
if (light_h == -1 && h == -1)
{
if (api->in_circle(xx, yy, 8))
{
pix = api->getpixel(canvas, x + xx, y + yy);
SDL_GetRGB(pix, canvas->format, &r, &g, &b);
adj = (7.99 - sqrt(abs(xx * yy))) / 128.0;
api->rgbtohsv(r, g, b, &h, &s, &v);
v = min((float)1.0, v + adj);
if (light_h == -1 && h == -1)
{
new_h = -1;
new_s = 0;
new_v = v;
}
else if (light_h == -1)
{
new_h = h;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
else if (h == -1)
{
new_h = light_h;
new_s = max(0.0, light_s - adj / 2.0);
new_v = v;
}
else
{
new_h = (light_h + h) / 2;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
new_h = -1;
new_s = 0;
new_v = v;
}
else if (light_h == -1)
{
new_h = h;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
else if (h == -1)
{
new_h = light_h;
new_s = max(0.0, light_s - adj / 2.0);
new_v = v;
}
else
{
new_h = (light_h + h) / 2;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy,
SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
// Affect the canvas on drag:
void light_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_light);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_light);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 8;
update_rect->y = oy - 8;
@ -208,7 +224,8 @@ void light_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void light_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
light_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
@ -216,7 +233,8 @@ void light_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release:
void light_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
int x, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
api->playsound(light2_snd, (x * 255) / canvas->w, 255);
}
@ -237,17 +255,20 @@ void light_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
}
// Use colors:
int light_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int light_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void light_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void light_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void light_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void light_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -31,16 +31,24 @@ int lightning_requires_colors(magic_api * api, int which);
int lightning_modes(magic_api * api, int which);
void lightning_shutdown(magic_api * api);
void lightning_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void lightning_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void lightning_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void lightning_line_callback_drag(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void lightning_draw_bolt(void * ptr, SDL_Surface * canvas, SDL_Surface * snapshot, float sx, float sy, float angle, float len, int thickness);
void lightning_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
void lightning_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void lightning_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void lightning_line_callback_drag(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void lightning_draw_bolt(void *ptr, SDL_Surface * canvas,
SDL_Surface * snapshot, float sx, float sy,
float angle, float len, int thickness);
void lightning_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void lightning_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void lightning_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
Uint32 lightning_api_version(void)
@ -52,7 +60,8 @@ int lightning_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/lightning.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/lightning.ogg",
api->data_directory);
snd_effect = Mix_LoadWAV(fname);
return (1);
@ -68,32 +77,41 @@ SDL_Surface *lightning_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/lightning.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/lightning.png",
api->data_directory);
return (IMG_Load(fname));
}
char *lightning_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *lightning_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext("Lightning"));
}
int lightning_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int lightning_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_ARTISTIC;
}
char *lightning_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *lightning_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext("Click, drag, and release to draw a lightning bolt between two points."));
return
strdup(gettext
("Click, drag, and release to draw a lightning bolt between two points."));
}
int lightning_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int lightning_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
int lightning_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int lightning_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MODE_PAINT;
}
@ -107,7 +125,8 @@ void lightning_shutdown(magic_api * api ATTRIBUTE_UNUSED)
void
lightning_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
sx = x;
sy = y;
@ -117,8 +136,8 @@ lightning_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
void
lightning_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
{
/* FIXME: This could be made more efficient
(only blit and update between (sx,sy) and (x,y), though
@ -131,13 +150,15 @@ lightning_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_BlitSurface(snapshot, update_rect, canvas, update_rect);
api->line((void *)api, which, canvas, snapshot, sx, sy, x, y, 1, lightning_line_callback_drag);
api->line((void *) api, which, canvas, snapshot, sx, sy, x, y, 1,
lightning_line_callback_drag);
}
void
lightning_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
float a, b, len, angle;
int thickness;
@ -168,8 +189,9 @@ lightning_release(magic_api * api, int which ATTRIBUTE_UNUSED,
angle = -angle;
#ifdef DEBUG
printf("(%d,%d)->(%d,%d) => a = %.2f, b = %.2f, c (len) = %.2f; angle = %.2f degrees\n",
sx, sy, x, y, a, b, len, angle);
printf
("(%d,%d)->(%d,%d) => a = %.2f, b = %.2f, c (len) = %.2f; angle = %.2f degrees\n",
sx, sy, x, y, a, b, len, angle);
fflush(stdout);
#endif
@ -177,10 +199,13 @@ lightning_release(magic_api * api, int which ATTRIBUTE_UNUSED,
if (thickness < 4)
thickness = 4;
lightning_draw_bolt((void *) api, canvas, snapshot, (float) sx, (float) sy, angle, len, thickness);
lightning_draw_bolt((void *) api, canvas, snapshot, (float) sx, (float) sy,
angle, len, thickness);
}
void lightning_draw_bolt(void * ptr, SDL_Surface * canvas, SDL_Surface * snapshot, float sx, float sy, float angle, float len, int thickness)
void lightning_draw_bolt(void *ptr, SDL_Surface * canvas,
SDL_Surface * snapshot, float sx, float sy,
float angle, float len, int thickness)
{
magic_api *api = (magic_api *) ptr;
float i;
@ -199,77 +224,79 @@ void lightning_draw_bolt(void * ptr, SDL_Surface * canvas, SDL_Surface * snapsho
t = 1;
for (i = 0; i < len; i++)
{
x = x + cos(angle * M_PI / 180.0);
y = y + sin(angle * M_PI / 180.0);
angle = angle + ((float) (rand() % 15) - 7.5);
if (angle < orig_angle - 10.0)
angle = orig_angle - 10.0;
else if (angle > orig_angle + 10.0)
angle = orig_angle + 10.0;
for (yy = -t; yy <= t; yy++)
{
x = x + cos(angle * M_PI / 180.0);
y = y + sin(angle * M_PI / 180.0);
angle = angle + ((float) (rand() % 15) - 7.5);
if (angle < orig_angle - 10.0)
angle = orig_angle - 10.0;
else if (angle > orig_angle + 10.0)
angle = orig_angle + 10.0;
for (yy = -t; yy <= t; yy++)
for (xx = -t; xx <= t; xx++)
{
if (api->in_circle(xx, yy, t))
{
for (xx = -t; xx <= t; xx++)
{
if (api->in_circle(xx, yy, t))
{
float light_h, light_s;
float light_h, light_s;
light_h = lightning_h;
light_s = lightning_s;
light_h = lightning_h;
light_s = lightning_s;
SDL_GetRGB(api->getpixel(canvas, x + xx, y + yy), canvas->format, &r, &g, &b);
api->rgbtohsv(r, g, b, &h, &s, &v);
SDL_GetRGB(api->getpixel(canvas, x + xx, y + yy), canvas->format,
&r, &g, &b);
api->rgbtohsv(r, g, b, &h, &s, &v);
adj = 1.0 - (sqrt((xx * xx) + (yy * yy)) / t);
adj = 1.0 - (sqrt((xx * xx) + (yy * yy)) / t);
new_v = v + adj;
if (new_v > 1.0)
{
light_s = light_s / (new_v * 2);
new_v = 1.0;
}
new_v = v + adj;
if (new_v > 1.0)
{
light_s = light_s / (new_v * 2);
new_v = 1.0;
}
if (light_h == -1)
{
new_h = h;
new_s = (s * 25) / 100;
}
else
{
new_h = ((light_h * 75) + (h * 25)) / 100;
new_s = ((light_s * 75) + (s * 25)) / 100;
}
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
if (((rand() % 50) == 0 || (int) i == (int) (len / 2)) && thickness > 1 && len >= 4)
{
float new_angle;
if ((rand() % 10) == 0)
{
new_angle = angle + ((float) (rand() % 180) - 90.0);
}
if (light_h == -1)
{
new_h = h;
new_s = (s * 25) / 100;
}
else
{
new_angle = angle + ((float) (rand() % 90) - 45.0);
}
{
new_h = ((light_h * 75) + (h * 25)) / 100;
new_s = ((light_s * 75) + (s * 25)) / 100;
}
lightning_draw_bolt((void *) api, canvas, snapshot, x, y,
new_angle,
((len / 8) + (rand() % (int) (len / 4))),
thickness - 1
);
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy,
SDL_MapRGB(canvas->format, r, g, b));
}
}
}
if (((rand() % 50) == 0 || (int) i == (int) (len / 2)) && thickness > 1
&& len >= 4)
{
float new_angle;
if ((rand() % 10) == 0)
{
new_angle = angle + ((float) (rand() % 180) - 90.0);
}
else
{
new_angle = angle + ((float) (rand() % 90) - 45.0);
}
lightning_draw_bolt((void *) api, canvas, snapshot, x, y,
new_angle,
((len / 8) + (rand() % (int) (len / 4))),
thickness - 1);
}
}
}
@ -279,17 +306,25 @@ void lightning_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
}
void lightning_line_callback_drag(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
void lightning_line_callback_drag(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x, int y)
{
magic_api *api = (magic_api *) ptr;
api->xorpixel(canvas, x, y);
}
void lightning_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void lightning_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void lightning_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void lightning_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -45,18 +45,24 @@ SDL_Surface *metalpaint_get_icon(magic_api * api, int which);
char *metalpaint_get_name(magic_api * api, int which);
int metalpaint_get_group(magic_api * api, int which);
char *metalpaint_get_description(magic_api * api, int which, int mode);
static void do_metalpaint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_metalpaint(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void metalpaint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void metalpaint_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void metalpaint_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void metalpaint_shutdown(magic_api * api);
void metalpaint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int metalpaint_requires_colors(magic_api * api, int which);
void metalpaint_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void metalpaint_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void metalpaint_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void metalpaint_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int metalpaint_modes(magic_api * api, int which);
@ -71,7 +77,8 @@ int metalpaint_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/metalpaint.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/metalpaint.wav",
api->data_directory);
metalpaint_snd = Mix_LoadWAV(fname);
return (1);
@ -88,28 +95,34 @@ SDL_Surface *metalpaint_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/metalpaint.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/metalpaint.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Metal Paint")));
}
// Return our groups:
int metalpaint_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int metalpaint_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
char *metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag the mouse to paint with a metallic color.")));
return (strdup
(gettext_noop
("Click and drag the mouse to paint with a metallic color.")));
}
#define METALPAINT_CYCLE 32
@ -125,7 +138,8 @@ static int metalpaint_gradient[METALPAINT_CYCLE] = {
// Do the effect:
static void do_metalpaint(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
static void do_metalpaint(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -134,40 +148,43 @@ static void do_metalpaint(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
Uint8 r, g, b;
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
for (xx = -8; xx < 8; xx++)
{
n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE];
n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE];
r = (metalpaint_r * n) / 255;
g = (metalpaint_g * n) / 255;
b = (metalpaint_b * n) / 255;
r = (metalpaint_r * n) / 255;
g = (metalpaint_g * n) / 255;
b = (metalpaint_b * n) / 255;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
api->putpixel(canvas, x + xx, y + yy,
SDL_MapRGB(canvas->format, r, g, b));
}
}
}
// Affect the canvas on drag:
void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_metalpaint);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_metalpaint);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 8;
update_rect->y = oy - 8;
@ -179,15 +196,19 @@ void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void metalpaint_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
metalpaint_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void metalpaint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void metalpaint_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -199,7 +220,8 @@ void metalpaint_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void metalpaint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void metalpaint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
metalpaint_r = min(255, r + 64);
metalpaint_g = min(255, g + 64);
@ -207,22 +229,28 @@ void metalpaint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Ui
}
// Use colors:
int metalpaint_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int metalpaint_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -52,9 +52,12 @@ SDL_Surface *mirror_flip_get_icon(magic_api *, int);
char *mirror_flip_get_name(magic_api *, int);
int mirror_flip_get_group(magic_api *, int);
char *mirror_flip_get_description(magic_api *, int, int);
void mirror_flip_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
void mirror_flip_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
void mirror_flip_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
void mirror_flip_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int,
int, int, int, SDL_Rect *);
void mirror_flip_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int,
int, int, int, SDL_Rect *);
void mirror_flip_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *,
int, int, SDL_Rect *);
void mirror_flip_shutdown(magic_api *);
void mirror_flip_set_color(magic_api *, Uint8, Uint8, Uint8);
int mirror_flip_requires_colors(magic_api *, int);
@ -67,10 +70,12 @@ int mirror_flip_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/mirror.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/mirror.wav",
api->data_directory);
snd_effects[TOOL_MIRROR] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/flip.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/flip.wav",
api->data_directory);
snd_effects[TOOL_FLIP] = Mix_LoadWAV(fname);
return (1);
@ -93,13 +98,15 @@ SDL_Surface *mirror_flip_get_icon(magic_api * api, int which)
char fname[1024];
if (which == TOOL_MIRROR)
{
snprintf(fname, sizeof(fname), "%simages/magic/mirror.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/mirror.png",
api->data_directory);
}
else if (which == TOOL_FLIP)
{
snprintf(fname, sizeof(fname), "%simages/magic/flip.png", api->data_directory);
}
{
snprintf(fname, sizeof(fname), "%simages/magic/flip.png",
api->data_directory);
}
return (IMG_Load(fname));
}
@ -116,13 +123,15 @@ char *mirror_flip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (the same):
int mirror_flip_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int mirror_flip_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
// Return our descriptions, localized:
char *mirror_flip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *mirror_flip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (which == TOOL_MIRROR)
return (strdup(gettext_noop("Click to make a mirror image.")));
@ -134,19 +143,23 @@ char *mirror_flip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, i
// We affect the whole canvas, so only do things on click, not drag:
void mirror_flip_drag(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
// No-op
}
void mirror_flip_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
// No-op
}
@ -154,46 +167,47 @@ void mirror_flip_release(magic_api * api ATTRIBUTE_UNUSED,
// Affect the canvas on click:
void mirror_flip_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect)
{
int xx, yy;
SDL_Rect src, dest;
if (which == TOOL_MIRROR)
{
for (xx = 0; xx < canvas->w; xx++)
{
for (xx = 0; xx < canvas->w; xx++)
{
src.x = xx;
src.y = 0;
src.w = 1;
src.h = canvas->h;
src.x = xx;
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = canvas->w - xx - 1;
dest.y = 0;
dest.x = canvas->w - xx - 1;
dest.y = 0;
SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_MIRROR);
SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_MIRROR);
}
else if (which == TOOL_FLIP)
{
for (yy = 0; yy < canvas->h; yy++)
{
for (yy = 0; yy < canvas->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = canvas->w;
src.h = 1;
src.x = 0;
src.y = yy;
src.w = canvas->w;
src.h = 1;
dest.x = 0;
dest.y = canvas->h - yy - 1;
dest.x = 0;
dest.y = canvas->h - yy - 1;
SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_FLIP);
SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_FLIP);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
@ -213,27 +227,34 @@ void mirror_flip_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// We don't use colors:
void mirror_flip_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// We don't use colors:
int mirror_flip_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int mirror_flip_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void mirror_flip_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void mirror_flip_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int mirror_flip_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int mirror_flip_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_FULLSCREEN);
}

View file

@ -45,9 +45,12 @@
#define gettext_noop(String) String
#endif
static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y);
static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas,
int noise_AMOUNT, int x, int y);
static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void reset_mosaic_blured(SDL_Surface * canvas);
/* Prototypes */
@ -59,9 +62,12 @@ char *mosaic_get_name(magic_api *, int);
int mosaic_get_group(magic_api *, int);
char *mosaic_get_description(magic_api *, int, int);
void mosaic_paint(void *, int, SDL_Surface *, SDL_Surface *, int, int);
void mosaic_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
void mosaic_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
void mosaic_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
void mosaic_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int,
int, int, SDL_Rect *);
void mosaic_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int,
int, SDL_Rect *);
void mosaic_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int,
SDL_Rect *);
void mosaic_shutdown(magic_api *);
void mosaic_set_color(magic_api *, Uint8, Uint8, Uint8);
int mosaic_requires_colors(magic_api *, int);
@ -102,7 +108,8 @@ const int mosaic_groups[mosaic_NUM_TOOLS] = {
};
const char *mosaic_descs[mosaic_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to add a mosaic effect to parts of your picture."),
{gettext_noop
("Click and drag the mouse to add a mosaic effect to parts of your picture."),
gettext_noop("Click to add a mosaic effect to your entire picture."),},
};
@ -119,10 +126,11 @@ int mosaic_init(magic_api * api)
char fname[1024];
for (i = 0; i < mosaic_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, mosaic_snd_filenames[i]);
mosaic_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
mosaic_snd_filenames[i]);
mosaic_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -137,7 +145,8 @@ SDL_Surface *mosaic_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, mosaic_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
mosaic_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -154,7 +163,8 @@ int mosaic_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *mosaic_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *mosaic_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(mosaic_descs[which][mode - 1])));
}
@ -167,80 +177,89 @@ static int mosaic_grey(Uint8 r1, Uint8 g1, Uint8 b1)
// Do the effect for the full image
static void do_mosaic_full(void *ptr, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
SDL_Surface * last ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
magic_api *api = (magic_api *) ptr;
int x, y;
Uint32 amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
Uint32 amask =
~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
SDL_Surface *mosaic_temp = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->
BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
canvas->format->Bmask,
amask);
api->update_progress_bar();
for (y = 0; y < canvas->h; y++)
{
{
for (x = 0; x < canvas->w; x++)
{
mosaic_blur_pixel(api, mosaic_temp, canvas_noise, x, y);
}
for (x = 0; x < canvas->w; x++)
{
mosaic_blur_pixel(api, mosaic_temp, canvas_noise, x, y);
}
}
api->update_progress_bar();
for (y = 0; y < canvas->h; y++)
{
for (x = 0; x < canvas->w; x++)
{
for (x = 0; x < canvas->w; x++)
{
mosaic_sharpen_pixel(api, canvas, mosaic_temp, x, y);
}
mosaic_sharpen_pixel(api, canvas, mosaic_temp, x, y);
}
}
SDL_FreeSurface(mosaic_temp);
}
/* Paint the brush, noise is yet done at switchin,
blurs 2 pixels around the brush in order to get sharpen well done.*/
void mosaic_paint(void *ptr_to_api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
{
int i, j, pix_row_pos;
magic_api *api = (magic_api *) ptr_to_api;
for (j = max(0, y - mosaic_RADIUS - 2); j < min(canvas->h, y + mosaic_RADIUS + 2); j++)
{
pix_row_pos = j * canvas->w;
for (i = max(0, x - mosaic_RADIUS - 2); i < min(canvas->w, x + mosaic_RADIUS + 2); i++)
if (!mosaic_blured[pix_row_pos + i] && api->in_circle(i - x, j - y, mosaic_RADIUS + 2))
{
mosaic_blur_pixel(api, canvas_blur, canvas_noise, i, j);
mosaic_blured[pix_row_pos + i] = 1; /* Track what are yet blured */
}
}
for (j = max(0, y - mosaic_RADIUS - 2);
j < min(canvas->h, y + mosaic_RADIUS + 2); j++)
{
pix_row_pos = j * canvas->w;
for (i = max(0, x - mosaic_RADIUS - 2);
i < min(canvas->w, x + mosaic_RADIUS + 2); i++)
if (!mosaic_blured[pix_row_pos + i]
&& api->in_circle(i - x, j - y, mosaic_RADIUS + 2))
{
mosaic_blur_pixel(api, canvas_blur, canvas_noise, i, j);
mosaic_blured[pix_row_pos + i] = 1; /* Track what are yet blured */
}
}
for (i = x - mosaic_RADIUS; i < x + mosaic_RADIUS; i++)
for (j = y - mosaic_RADIUS; j < y + mosaic_RADIUS; j++)
if (api->in_circle(i - x, j - y, mosaic_RADIUS))
if (!api->touched(i, j))
{
mosaic_sharpen_pixel(api, canvas_sharp, canvas_blur, i, j);
api->putpixel(canvas, i, j, api->getpixel(canvas_sharp, i, j));
}
{
mosaic_sharpen_pixel(api, canvas_sharp, canvas_blur, i, j);
api->putpixel(canvas, i, j, api->getpixel(canvas_sharp, i, j));
}
}
// Affect the canvas on drag:
void mosaic_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line(api, which, canvas, last, ox, oy, x, y, 1, mosaic_paint);
@ -254,20 +273,21 @@ void mosaic_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void mosaic_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_FULLSCREEN)
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_mosaic_full(api, canvas_noise, last, which);
SDL_BlitSurface(canvas_noise, NULL, canvas, NULL);
api->playsound(mosaic_snd_effect[which], 128, 255);
}
do_mosaic_full(api, canvas_noise, last, which);
SDL_BlitSurface(canvas_noise, NULL, canvas, NULL);
api->playsound(mosaic_snd_effect[which], 128, 255);
}
else
mosaic_drag(api, which, canvas, last, x, y, x, y, update_rect);
@ -278,7 +298,8 @@ void mosaic_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -289,28 +310,31 @@ void mosaic_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < mosaic_NUM_TOOLS; i++)
{
if (mosaic_snd_effect[i] != NULL)
{
if (mosaic_snd_effect[i] != NULL)
{
Mix_FreeChunk(mosaic_snd_effect[i]);
}
Mix_FreeChunk(mosaic_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void mosaic_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int mosaic_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int mosaic_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
//Add noise to a pixel
static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y)
static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas,
int noise_AMOUNT, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -318,16 +342,21 @@ static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas, int noise_AMOUNT
double temp2[3];
int k;
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1],
&temp[2]);
for (k = 0; k < 3; k++)
{
temp2[k] = clamp(0.0, (int)temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0, 255.0);
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
{
temp2[k] =
clamp(0.0, (int) temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0,
255.0);
}
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
}
//Blur a pixel
static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int i, j, k;
@ -343,31 +372,35 @@ static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * las
};
for (k = 0; k < 3; k++)
{
blurValue[k] = 0;
}
{
blurValue[k] = 0;
}
for (i = -2; i < 3; i++)
{
for (j = -2; j < 3; j++)
{
for (j = -2; j < 3; j++)
{
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0],
&temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
}
for (k = 0; k < 3; k++)
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2]));
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, blurValue[0], blurValue[1],
blurValue[2]));
}
//Sharpen a pixel
static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -391,73 +424,85 @@ static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface *
sobel_1 = 0;
sobel_2 = 0;
for (i = -1; i < 2; i++)
{
for (j = -1; j < 2; j++)
{
for (j = -1; j < 2; j++)
{
//No need to check if inside canvas, getpixel does it for us.
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1, &b1);
grey = mosaic_grey(r1, g1, b1);
sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
//No need to check if inside canvas, getpixel does it for us.
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1,
&b1);
grey = mosaic_grey(r1, g1, b1);
sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
}
temp = sqrt(sobel_1 * sobel_1 + sobel_2 * sobel_2);
temp = (temp / 1443) * 255.0;
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, g1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, b1 + mosaic_SHARPEN * temp, 255.0)));
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format,
clamp(0.0, r1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, g1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, b1 + mosaic_SHARPEN * temp, 255.0)));
}
void mosaic_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
void mosaic_switchin(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
int y, x;
Uint32 amask;
mosaic_blured = (Uint8 *) malloc(sizeof(Uint8) * (canvas->w * canvas->h));
if (mosaic_blured == NULL)
{
fprintf(stderr, "\nError: Can't build drawing touch mask!\n");
exit(1);
}
{
fprintf(stderr, "\nError: Can't build drawing touch mask!\n");
exit(1);
}
amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
amask =
~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
canvas_noise = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
SDL_BlitSurface(canvas, NULL, canvas_noise, NULL);
for (y = 0; y < canvas->h; y++)
{
for (x = 0; x < canvas->w; x++)
{
for (x = 0; x < canvas->w; x++)
{
mosaic_noise_pixel(api, canvas_noise, mosaic_AMOUNT, x, y);
}
mosaic_noise_pixel(api, canvas_noise, mosaic_AMOUNT, x, y);
}
}
canvas_blur = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
canvas_sharp = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
reset_mosaic_blured(canvas);
}
void mosaic_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
SDL_FreeSurface(canvas_noise);
SDL_FreeSurface(canvas_blur);

File diff suppressed because it is too large Load diff

View file

@ -42,19 +42,25 @@ SDL_Surface *negative_get_icon(magic_api * api, int which);
char *negative_get_name(magic_api * api, int which);
int negative_get_group(magic_api * api, int which);
char *negative_get_description(magic_api * api, int which, int mode);
static void do_negative(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_negative(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void negative_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void negative_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void negative_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void negative_shutdown(magic_api * api);
void negative_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int negative_requires_colors(magic_api * api, int which);
void negative_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void negative_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void negative_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void negative_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int negative_modes(magic_api * api, int which);
enum
@ -76,13 +82,14 @@ const char *negative_names[negative_NUM_TOOLS] = {
const char *negative_descs[negative_NUM_TOOLS][2] = {
{
gettext_noop("Click and drag the mouse around to make your painting negative."),
gettext_noop("Click to turn your painting into its negative.")
},
gettext_noop
("Click and drag the mouse around to make your painting negative."),
gettext_noop("Click to turn your painting into its negative.")},
{
gettext_noop("Click and drag the mouse around to change colors to their opposites -- their complementary colors."),
gettext_noop("Click to turn all colors in your painting into their opposites -- their complementary colors.")
},
gettext_noop
("Click and drag the mouse around to change colors to their opposites -- their complementary colors."),
gettext_noop
("Click to turn all colors in your painting into their opposites -- their complementary colors.")},
};
@ -90,7 +97,8 @@ int negative_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/negative.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/negative.wav",
api->data_directory);
negative_snd = Mix_LoadWAV(fname);
@ -112,7 +120,8 @@ SDL_Surface *negative_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, negative_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
negative_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -123,93 +132,105 @@ char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (both the same):
int negative_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int negative_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_COLOR_FILTERS;
}
// Return our description, localized:
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
int mode_idx;
if (mode == MODE_PAINT) {
if (mode == MODE_PAINT)
{
mode_idx = 0;
} else if (mode == MODE_FULLSCREEN) {
}
else if (mode == MODE_FULLSCREEN)
{
mode_idx = 1;
} else {
}
else
{
return NULL;
}
return(strdup(gettext_noop(negative_descs[which][mode_idx])));
return (strdup(gettext_noop(negative_descs[which][mode_idx])));
}
static void negative_calc(void *ptr, int which, Uint8 r, Uint8 g, Uint8 b, Uint8 * new_r, Uint8 * new_g, Uint8 * new_b) {
static void negative_calc(void *ptr, int which, Uint8 r, Uint8 g, Uint8 b,
Uint8 * new_r, Uint8 * new_g, Uint8 * new_b)
{
float h, s, v, new_h;
magic_api *api = (magic_api *) ptr;
if (which == TOOL_NEGATIVE)
{
*new_r = 0xFF - r;
*new_g = 0xFF - g;
*new_b = 0xFF - b;
}
{
*new_r = 0xFF - r;
*new_g = 0xFF - g;
*new_b = 0xFF - b;
}
else
{
api->rgbtohsv(r, g, b, &h, &s, &v);
new_h = h + 180.0;
if (new_h >= 360.0)
{
api->rgbtohsv(r, g, b, &h, &s, &v);
new_h = h + 180.0;
if (new_h >= 360.0)
{
new_h = new_h - 360.0;
}
api->hsvtorgb(new_h, s, v, new_r, new_g, new_b);
new_h = new_h - 360.0;
}
api->hsvtorgb(new_h, s, v, new_r, new_g, new_b);
}
}
// Callback that does the negative color effect on a circle centered around x,y
static void do_negative(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_negative(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
Uint8 r, g, b, new_r, new_g, new_b;
magic_api *api = (magic_api *) ptr;
for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
if (api->in_circle(xx - x, yy - y, 16))
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
if (api->in_circle(xx - x, yy - y, 16))
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy,
SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
}
}
// Ask Tux Paint to call our 'do_negative()' callback over a line
void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
SDL_LockSurface(last);
SDL_LockSurface(canvas);
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_negative);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_negative);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -225,38 +246,43 @@ void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
// Ask Tux Paint to call our 'do_negative()' callback at a single point
void negative_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
negative_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
int xx, yy;
Uint8 r, g, b, new_r, new_g, new_b;
for (yy = 0; yy < canvas->h; yy++)
{
int xx, yy;
Uint8 r, g, b, new_r, new_g, new_b;
for (yy = 0; yy < canvas->h; yy++)
{
for (xx = 0; xx < canvas->w; xx++)
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(negative_snd, (x * 255) / canvas->w, 255);
for (xx = 0; xx < canvas->w; xx++)
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy,
SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(negative_snd, (x * 255) / canvas->w, 255);
}
}
void negative_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void negative_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -268,29 +294,33 @@ void negative_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// We don't use colors
void negative_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void negative_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// We don't use colors
int negative_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int negative_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void negative_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void negative_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void negative_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void negative_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int negative_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int negative_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}

View file

@ -71,7 +71,8 @@ const int noise_groups[noise_NUM_TOOLS] = {
};
const char *noise_descs[noise_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to add noise to parts of your picture."),
{gettext_noop
("Click and drag the mouse to add noise to parts of your picture."),
gettext_noop("Click to add noise to your entire picture."),},
};
@ -81,20 +82,26 @@ SDL_Surface *noise_get_icon(magic_api * api, int which);
char *noise_get_name(magic_api * api, int which);
int noise_get_group(magic_api * api, int which);
char *noise_get_description(magic_api * api, int which, int mode);
static void do_noise_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_noise_pixel(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which);
static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void noise_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void noise_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void noise_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void noise_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void noise_shutdown(magic_api * api);
void noise_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int noise_requires_colors(magic_api * api, int which);
void noise_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void noise_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void noise_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void noise_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int noise_modes(magic_api * api, int which);
int noise_get_tool_count(magic_api * api ATTRIBUTE_UNUSED);
@ -112,10 +119,11 @@ int noise_init(magic_api * api)
srand(time(0));
for (i = 0; i < noise_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, noise_snd_filenames[i]);
noise_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
noise_snd_filenames[i]);
noise_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -129,7 +137,8 @@ SDL_Surface *noise_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, noise_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
noise_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -146,14 +155,16 @@ int noise_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *noise_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *noise_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(noise_descs[which][mode - 1])));
}
//Do the effect for one pixel
static void do_noise_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -161,70 +172,79 @@ static void do_noise_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
double temp2[3];
int k;
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1],
&temp[2]);
for (k = 0; k < 3; k++)
{
temp2[k] = clamp(0.0, (int)temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0, 255.0);
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
{
temp2[k] =
clamp(0.0, (int) temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0,
255.0);
}
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
}
// Do the effect for the full image
static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which)
{
int x, y;
for (y = 0; y < last->h; y++)
{
for (x = 0; x < last->w; x++)
{
for (x = 0; x < last->w; x++)
{
do_noise_pixel(ptr, which, canvas, last, x, y);
}
do_noise_pixel(ptr, which, canvas, last, x, y);
}
}
}
//do the effect for the brush
static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - noise_RADIUS; yy < y + noise_RADIUS; yy++)
{
for (xx = x - noise_RADIUS; xx < x + noise_RADIUS; xx++)
{
for (xx = x - noise_RADIUS; xx < x + noise_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, noise_RADIUS) && !api->touched(xx, yy))
{
do_noise_pixel(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, noise_RADIUS)
&& !api->touched(xx, yy))
{
do_noise_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag:
void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_noise_brush);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_noise_brush);
api->playsound(noise_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - noise_RADIUS;
update_rect->y = oy - noise_RADIUS;
@ -234,25 +254,29 @@ void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void noise_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
noise_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_noise_full(api, canvas, last, which);
api->playsound(noise_snd_effect[which], 128, 255);
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_noise_full(api, canvas, last, which);
api->playsound(noise_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void noise_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void noise_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -263,32 +287,36 @@ void noise_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < noise_NUM_TOOLS; i++)
{
if (noise_snd_effect[i] != NULL)
{
if (noise_snd_effect[i] != NULL)
{
Mix_FreeChunk(noise_snd_effect[i]);
}
Mix_FreeChunk(noise_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void noise_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void noise_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int noise_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int noise_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void noise_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void noise_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void noise_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void noise_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

File diff suppressed because it is too large Load diff

View file

@ -58,15 +58,19 @@ char *pixels_get_name(magic_api * api, int which);
int pixels_get_group(magic_api * api, int which);
char *pixels_get_description(magic_api * api, int which, int mode);
void pixels_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void pixels_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void pixels_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void pixels_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void pixels_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void pixels_shutdown(magic_api * api);
void pixels_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int pixels_requires_colors(magic_api * api, int which);
void pixels_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void pixels_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void pixels_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void pixels_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int pixels_modes(magic_api * api, int which);
// No setup required:
@ -74,7 +78,8 @@ int pixels_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/pixels.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/pixels.ogg",
api->data_directory);
pixel_snd = Mix_LoadWAV(fname);
return (1);
@ -96,25 +101,30 @@ SDL_Surface *pixels_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/pixels.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/pixels.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *pixels_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *pixels_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Pixels")));
}
// Return our group (both the same):
int pixels_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int pixels_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *pixels_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *pixels_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to draw large pixels.")));
@ -123,7 +133,9 @@ char *pixels_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBU
// Do the effect:
static void do_pixels(void *ptr ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
static void do_pixels(void *ptr ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
SDL_Rect dest;
int pixel_size;
@ -135,29 +147,31 @@ static void do_pixels(void *ptr ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SD
dest.w = pixel_size;
dest.h = pixel_size;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, pixels_r, pixels_g, pixels_b));
SDL_FillRect(canvas, &dest,
SDL_MapRGB(canvas->format, pixels_r, pixels_g, pixels_b));
}
// Affect the canvas on drag:
void pixels_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_pixels);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_pixels);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = x - 64;
update_rect->y = y - 64;
@ -169,14 +183,17 @@ void pixels_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void pixels_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
pixels_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void pixels_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
api->stopsound();
}
@ -189,7 +206,8 @@ void pixels_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void pixels_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void pixels_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
pixels_r = r;
pixels_g = g;
@ -197,18 +215,21 @@ void pixels_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8
}
// Use colors:
int pixels_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int pixels_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void pixels_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void pixels_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void pixels_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
void pixels_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -57,19 +57,25 @@ char *puzzle_get_name(magic_api * api, int which);
int puzzle_get_group(magic_api * api, int which);
char *puzzle_get_description(magic_api * api, int which, int mode);
void puzzle_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void puzzle_shutdown(magic_api * api);
void puzzle_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int puzzle_requires_colors(magic_api * api, int which);
void puzzle_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void puzzle_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void puzzle_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void puzzle_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int puzzle_modes(magic_api * api, int which);
static void puzzle_draw(void *ptr, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
static void puzzle_draw(void *ptr, int which_tool, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void puzzle_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
int gcd(int a, int b);
Uint32 puzzle_api_version(void)
@ -81,7 +87,8 @@ int puzzle_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/puzzle.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/puzzle.wav",
api->data_directory);
puzzle_snd = Mix_LoadWAV(fname);
return 1;
@ -96,32 +103,41 @@ SDL_Surface *puzzle_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/puzzle.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/puzzle.png",
api->data_directory);
return (IMG_Load(fname));
}
char *puzzle_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *puzzle_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Puzzle")));
}
int puzzle_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int puzzle_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
char *puzzle_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *puzzle_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return strdup(gettext_noop("Click the part of your picture where would you like a puzzle."));
return
strdup(gettext_noop
("Click the part of your picture where would you like a puzzle."));
return strdup(gettext_noop("Click to make a puzzle in fullscreen mode."));
}
void puzzle_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void puzzle_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -131,12 +147,14 @@ void puzzle_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(puzzle_snd);
}
void puzzle_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void puzzle_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
int puzzle_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int puzzle_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
@ -148,18 +166,22 @@ int gcd(int a, int b) //greatest common divisor
return gcd(b, a % b);
}
void puzzle_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void puzzle_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{
puzzle_gcd = RATIO * gcd(canvas->w, canvas->h);
rects_w = (unsigned int)canvas->w / puzzle_gcd;
rects_h = (unsigned int)canvas->h / puzzle_gcd;
rects_w = (unsigned int) canvas->w / puzzle_gcd;
rects_h = (unsigned int) canvas->h / puzzle_gcd;
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
}
void puzzle_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void puzzle_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
SDL_FreeSurface(canvas_backup);
@ -172,7 +194,8 @@ int puzzle_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
}
static void puzzle_draw(void *ptr, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{
@ -187,59 +210,65 @@ static void puzzle_draw(void *ptr, int which_tool ATTRIBUTE_UNUSED,
y = (y / puzzle_gcd) * puzzle_gcd;
if (!api->touched(x, y))
{
srand(rand());
r = rand() % 4;
rect_that.x = x;
rect_that.y = y;
switch (r)
{
srand(rand());
case 0: //upper
if (y > puzzle_gcd)
rect_that.y = y - puzzle_gcd;
r = rand() % 4;
break;
case 1: //right
if (x < canvas->w - puzzle_gcd)
rect_that.x = x - puzzle_gcd;
rect_that.x = x;
rect_that.y = y;
break;
case 2: //lower
if (y < canvas->h - puzzle_gcd)
rect_that.y = y - puzzle_gcd;
switch (r)
{
case 0: //upper
if (y > puzzle_gcd)
rect_that.y = y - puzzle_gcd;
break;
case 1: //right
if (x < canvas->w - puzzle_gcd)
rect_that.x = x - puzzle_gcd;
break;
case 2: //lower
if (y < canvas->h - puzzle_gcd)
rect_that.y = y - puzzle_gcd;
break;
case 3: //left
if (x > puzzle_gcd)
rect_that.x = x - puzzle_gcd;
break;
}
rect_this.x = x;
rect_this.y = y;
rect_this.h = rect_this.w = puzzle_gcd;
rect_that.h = rect_that.w = puzzle_gcd;
SDL_BlitSurface(canvas, &rect_this, canvas, &rect_that);
SDL_BlitSurface(canvas_backup, &rect_that, canvas, &rect_this);
api->playsound(puzzle_snd, (x * 255) / canvas->w, 255);
break;
case 3: //left
if (x > puzzle_gcd)
rect_that.x = x - puzzle_gcd;
break;
}
rect_this.x = x;
rect_this.y = y;
rect_this.h = rect_this.w = puzzle_gcd;
rect_that.h = rect_that.w = puzzle_gcd;
SDL_BlitSurface(canvas, &rect_this, canvas, &rect_that);
SDL_BlitSurface(canvas_backup, &rect_that, canvas, &rect_this);
api->playsound(puzzle_snd, (x * 255) / canvas->w, 255);
}
}
void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect)
{
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2,
y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x - 1.5 * puzzle_gcd / 2, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x + 0.5 * puzzle_gcd, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y - 1.5 * puzzle_gcd);
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y + 0.5 * puzzle_gcd);
puzzle_draw(api, which, canvas, last, x - 1.5 * puzzle_gcd / 2,
y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x + 0.5 * puzzle_gcd,
y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2,
y - 1.5 * puzzle_gcd);
puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2,
y + 0.5 * puzzle_gcd);
update_rect->x = 0;
update_rect->y = 0;
@ -248,7 +277,8 @@ void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void puzzle_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
puzzle_drag(api, which, canvas, last, x, y, x, y, update_rect);
}

View file

@ -53,25 +53,34 @@ int rails_get_group(magic_api * api, int which);
char *rails_get_description(magic_api * api, int which, int mode);
int rails_requires_colors(magic_api * api, int which);
void rails_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void rails_shutdown(magic_api * api);
void rails_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rails_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rails_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void rails_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
inline unsigned int rails_get_segment(int x, int y);
#define POINT_TYPE typeof(((SDL_Rect *)NULL)->x)
inline void rails_extract_coords_from_segment(unsigned int segment, POINT_TYPE * x, POINT_TYPE * y);
inline void rails_extract_coords_from_segment(unsigned int segment,
POINT_TYPE * x, POINT_TYPE * y);
static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src);
static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src);
static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction);
void rails_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src,
unsigned int direction);
void rails_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
static Uint8 rails_select_image(Uint16 segment);
static void rails_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y, unsigned int segment);
static void rails_draw(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
unsigned int segment);
static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void rails_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
Uint32 rails_api_version(void)
{
@ -83,7 +92,8 @@ int rails_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
return (MODE_PAINT);
}
void rails_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void rails_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
@ -93,15 +103,19 @@ int rails_init(magic_api * api)
char fname[1024];
Uint8 i; //is always < 3, so Uint8 seems to be a good idea
rails_images = (char **)malloc(sizeof(char *) * 4);
rails_images = (char **) malloc(sizeof(char *) * 4);
for (i = 0; i < 4; i++)
rails_images[i] = (char *)malloc(sizeof(char) * 1024);
rails_images[i] = (char *) malloc(sizeof(char) * 1024);
snprintf(rails_images[0], 1024 * sizeof(char), "%simages/magic/rails_one.png", api->data_directory);
snprintf(rails_images[1], 1024 * sizeof(char), "%simages/magic/rails_three.png", api->data_directory);
snprintf(rails_images[2], 1024 * sizeof(char), "%simages/magic/rails_four.png", api->data_directory);
snprintf(rails_images[3], 1024 * sizeof(char), "%simages/magic/rails_corner.png", api->data_directory);
snprintf(rails_images[0], 1024 * sizeof(char),
"%simages/magic/rails_one.png", api->data_directory);
snprintf(rails_images[1], 1024 * sizeof(char),
"%simages/magic/rails_three.png", api->data_directory);
snprintf(rails_images[2], 1024 * sizeof(char),
"%simages/magic/rails_four.png", api->data_directory);
snprintf(rails_images[3], 1024 * sizeof(char),
"%simages/magic/rails_corner.png", api->data_directory);
rails_one = IMG_Load(rails_images[0]);
rails_three = IMG_Load(rails_images[1]);
@ -111,7 +125,8 @@ int rails_init(magic_api * api)
img_w = rails_one->w;
img_h = rails_one->h;
snprintf(fname, sizeof(fname), "%ssounds/magic/rails.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/rails.wav",
api->data_directory);
rails_snd = Mix_LoadWAV(fname);
return (1);
@ -126,34 +141,45 @@ SDL_Surface *rails_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/rails.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/rails.png",
api->data_directory);
return (IMG_Load(fname));
}
char *rails_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *rails_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Rails"));
}
int rails_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rails_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
char *rails_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *rails_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click and drag to draw train track rails on your picture."));
return
strdup(gettext_noop
("Click and drag to draw train track rails on your picture."));
}
int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void rails_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void rails_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -176,30 +202,35 @@ void rails_shutdown(magic_api * api ATTRIBUTE_UNUSED)
free(rails_status_of_segments);
}
void rails_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rails_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{
//we've to compute the quantity of segments in each direction
canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
rails_segments_x = rails_math_ceil(canvas->w, img_w);
rails_segments_y = rails_math_ceil(canvas->h, img_h);
//status_of_segments[0] will not be used, we write in rails_status_of_segments[1 to segments_x*segments_y]
rails_status_of_segments = (Uint8 *) calloc(rails_segments_x * rails_segments_y + 1, sizeof(Uint8));
rails_status_of_segments =
(Uint8 *) calloc(rails_segments_x * rails_segments_y + 1, sizeof(Uint8));
}
void rails_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rails_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
if (rails_status_of_segments != NULL)
{
free(rails_status_of_segments);
rails_status_of_segments = NULL;
}
{
free(rails_status_of_segments);
rails_status_of_segments = NULL;
}
}
// Interactivity functions
@ -208,7 +239,7 @@ inline int rails_math_ceil(int x, int y)
{
int temp;
temp = (int)x / y;
temp = (int) x / y;
if (x % y)
return temp + 1;
@ -229,10 +260,11 @@ inline unsigned int rails_get_segment(int x, int y)
}
inline void rails_extract_coords_from_segment(unsigned int segment, POINT_TYPE * x, POINT_TYPE * y)
inline void rails_extract_coords_from_segment(unsigned int segment,
POINT_TYPE * x, POINT_TYPE * y)
{ //extracts the coords of the beginning and the segment
*x = ((segment % rails_segments_x) - 1) * img_w; //useful to set update_rect as small as possible
*y = (int)(segment / rails_segments_x) * img_h;
*y = (int) (segment / rails_segments_x) * img_h;
}
static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src)
@ -255,29 +287,31 @@ static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src)
api->putpixel(dest, x, y, api->getpixel(src, y, x));
}
static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction)
static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src,
unsigned int direction)
//src and dest must have same size
{
magic_api *api = (magic_api *) ptr;
POINT_TYPE x, y;
if (direction) //rotate -90 degs
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, src->w - x - 1));
}
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, src->w - x - 1));
}
else //rotate +90 degs
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
}
{
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
}
}
void rails_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
rails_segment_modified_last = 0;
rails_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
@ -288,50 +322,51 @@ static Uint8 rails_select_image(Uint16 segment)
int take_up, take_down;
int val_up, val_down, val_left, val_right;
int from_top = 0, from_bottom = 0, from_left = 0, from_right = 0;
int from_top_right = 0, from_top_left = 0, from_bottom_right = 0, from_bottom_left = 0;
int from_top_right = 0, from_top_left = 0, from_bottom_right =
0, from_bottom_left = 0;
int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0;
//Checking from were we come...
if (rails_segment_modified_last > 0)
{
if (segment == rails_segment_modified_last + 1)
from_left = 1;
if (segment == rails_segment_modified_last - 1)
from_right = 1;
if (segment == rails_segment_modified_last - rails_segments_x)
from_bottom = 1;
if (segment == rails_segment_modified_last + rails_segments_x)
from_top = 1;
// Segments are joining by the corner
// We need to add a new segment to join by side, adding clockwise
if (segment == rails_segment_modified_last + rails_segments_x + 1)
{
if (segment == rails_segment_modified_last + 1)
from_left = 1;
if (segment == rails_segment_modified_last - 1)
from_right = 1;
if (segment == rails_segment_modified_last - rails_segments_x)
from_bottom = 1;
if (segment == rails_segment_modified_last + rails_segments_x)
from_top = 1;
// Segments are joining by the corner
// We need to add a new segment to join by side, adding clockwise
if (segment == rails_segment_modified_last + rails_segments_x + 1)
{
from_top_left = 1;
rails_segment_to_add = segment - rails_segments_x;
}
if (segment == rails_segment_modified_last + rails_segments_x - 1)
{
from_top_right = 1;
rails_segment_to_add = segment + 1;
}
if (segment == rails_segment_modified_last - rails_segments_x - 1)
{
from_bottom_right = 1;
rails_segment_to_add = segment + rails_segments_x;
}
if (segment == rails_segment_modified_last - rails_segments_x + 1)
{
from_bottom_left = 1;
rails_segment_to_add = segment - 1;
}
from_top_left = 1;
rails_segment_to_add = segment - rails_segments_x;
}
if (segment == rails_segment_modified_last + rails_segments_x - 1)
{
from_top_right = 1;
rails_segment_to_add = segment + 1;
}
if (segment == rails_segment_modified_last - rails_segments_x - 1)
{
from_bottom_right = 1;
rails_segment_to_add = segment + rails_segments_x;
}
if (segment == rails_segment_modified_last - rails_segments_x + 1)
{
from_bottom_left = 1;
rails_segment_to_add = segment - 1;
}
}
@ -343,7 +378,7 @@ static Uint8 rails_select_image(Uint16 segment)
val_up = rails_status_of_segments[take_up];
take_down = segment + rails_segments_x;
if (take_down > (signed)(rails_segments_x * rails_segments_y))
if (take_down > (signed) (rails_segments_x * rails_segments_y))
val_down = SEG_NONE;
else
val_down = rails_status_of_segments[take_down];
@ -359,9 +394,9 @@ static Uint8 rails_select_image(Uint16 segment)
val_right = rails_status_of_segments[segment + 1];
if (from_left || (val_left & SEG_RIGHT) || from_bottom_left)
{
LEFT = 1;
}
{
LEFT = 1;
}
if (from_right || (val_right & SEG_LEFT) || from_top_right)
RIGHT = 1;
if (from_top || (val_up & SEG_BOTTOM) || from_top_left)
@ -400,8 +435,10 @@ static Uint8 rails_select_image(Uint16 segment)
}
static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y ATTRIBUTE_UNUSED, unsigned int segment)
static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED,
ATTRIBUTE_UNUSED SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x,
int y ATTRIBUTE_UNUSED, unsigned int segment)
{
magic_api *api = (magic_api *) ptr;
SDL_Surface *result, *temp;
@ -412,7 +449,8 @@ static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED S
if (segment > rails_segments_x * rails_segments_y)
return;
//modification_rect.x and modification_rect.y are set by function
rails_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y);
rails_extract_coords_from_segment(segment, &modification_rect.x,
&modification_rect.y);
modification_rect.h = img_w;
modification_rect.w = img_h;
@ -424,74 +462,78 @@ static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED S
rails_status_of_segments[segment] = image; //and write it to global table
result = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask,
rails_one->format->Amask);
result =
SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h,
rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask,
rails_one->format->Bmask, rails_one->format->Amask);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask,
rails_one->format->Amask);
temp =
SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h,
rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask,
rails_one->format->Bmask, rails_one->format->Amask);
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
switch (image)
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_one, NULL, result, NULL);
break;
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_one, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
rails_rotate(api, temp, rails_one, 1);
use_temp = 1;
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
rails_rotate(api, temp, rails_one, 1);
use_temp = 1;
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(rails_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(rails_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_BOTTOM:
rails_flip(api, temp, rails_three);
use_temp = 1;
break;
case SEG_LEFT_RIGHT_BOTTOM:
rails_flip(api, temp, rails_three);
use_temp = 1;
break;
case SEG_LEFT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 0);
use_temp = 1;
break;
case SEG_LEFT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 0);
use_temp = 1;
break;
case SEG_RIGHT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 1);
use_temp = 1;
break;
case SEG_RIGHT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 1);
use_temp = 1;
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(rails_corner, NULL, result, NULL);
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(rails_corner, NULL, result, NULL);
break;
case SEG_RIGHT_BOTTOM:
rails_flip(api, temp, rails_corner);
use_temp = 1;
break;
case SEG_RIGHT_BOTTOM:
rails_flip(api, temp, rails_corner);
use_temp = 1;
break;
case SEG_LEFT_TOP:
rails_rotate(api, temp, rails_corner, 0);
use_temp = 1;
break;
case SEG_LEFT_TOP:
rails_rotate(api, temp, rails_corner, 0);
use_temp = 1;
break;
case SEG_LEFT_BOTTOM:
rails_flip_flop(api, temp, rails_corner);
use_temp = 1;
break;
}
case SEG_LEFT_BOTTOM:
rails_flip_flop(api, temp, rails_corner);
use_temp = 1;
break;
}
if (use_temp)
SDL_BlitSurface(temp, NULL, result, NULL);
@ -502,7 +544,8 @@ static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED S
api->playsound(rails_snd, (x * 255) / canvas->w, 255);
}
static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
rails_segment_modified = rails_get_segment(x, y);
@ -510,50 +553,56 @@ static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_S
if ((rails_segment_modified == rails_segment_modified_last))
return;
if (rails_segment_modified > 0)
{
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified);
}
{
rails_draw((void *) ptr, which, canvas, last, x, y,
rails_segment_modified);
}
if (rails_segment_modified_last > 0)
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last);
rails_draw((void *) ptr, which, canvas, last, x, y,
rails_segment_modified_last);
if (rails_segment_to_add > 0)
{
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_to_add);
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last);
rails_segment_to_add = 0;
}
{
rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_to_add);
rails_draw((void *) ptr, which, canvas, last, x, y,
rails_segment_modified_last);
rails_segment_to_add = 0;
}
if (rails_segment_modified > 0)
rails_segment_modified_last = rails_segment_modified;
}
void rails_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h;
// avoiding to write out of the canvas
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
&& ((signed)ox > 0) && ((signed)oy > 0))
{
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, img_w / 2, rails_draw_wrapper);
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w)
&& (oy < canvas->h) && ((signed) x > 0) && ((signed) y > 0)
&& ((signed) ox > 0) && ((signed) oy > 0))
{
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, img_w / 2,
rails_draw_wrapper);
start_x = min(ox, x);
end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
start_x = min(ox, x);
end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
segment_start = rails_get_segment(start_x - img_w, start_y - img_h);
segment_end = rails_get_segment(end_x + img_w, end_y + img_h);
segment_start = rails_get_segment(start_x - img_w, start_y - img_h);
segment_end = rails_get_segment(end_x + img_w, end_y + img_h);
x = ((segment_start % rails_segments_x) - 1) * img_w;
y = (int)(segment_start / rails_segments_x) * img_h;
w = ((segment_end % rails_segments_x) - 1) * img_w - x + img_w;
h = (int)(segment_end / rails_segments_x) * img_h - y + img_h;
x = ((segment_start % rails_segments_x) - 1) * img_w;
y = (int) (segment_start / rails_segments_x) * img_h;
w = ((segment_end % rails_segments_x) - 1) * img_w - x + img_w;
h = (int) (segment_end / rails_segments_x) * img_h - y + img_h;
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
}

View file

@ -43,7 +43,8 @@
#define gettext_noop(String) String
#endif
void rain_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
void rain_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int,
SDL_Rect *);
static const int rain_SIZE = 30;
static const int rain_AMOUNT = 200;
@ -84,19 +85,24 @@ SDL_Surface *rain_get_icon(magic_api * api, int which);
char *rain_get_name(magic_api * api, int which);
int rain_get_group(magic_api * api, int which);
char *rain_get_description(magic_api * api, int which, int mode);
static void do_rain_drop(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void rain_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_rain_drop(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void rain_linecb(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void rain_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void rain_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void rain_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void rain_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void rain_shutdown(magic_api * api);
void rain_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int rain_requires_colors(magic_api * api, int which);
void rain_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rain_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rain_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void rain_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int rain_modes(magic_api * api, int which);
Uint32 rain_api_version(void)
@ -108,9 +114,9 @@ Uint32 rain_api_version(void)
static int rain_inRainShape(double x, double y, double r)
{
if (sqrt(x * x + y * y) < (r * pow(cos(atan2(x, y)), 10.0)))
{
return 1;
}
{
return 1;
}
return 0;
}
@ -122,10 +128,11 @@ int rain_init(magic_api * api)
//Load sounds
for (i = 0; i < rain_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, rain_snd_filenames[i]);
rain_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
rain_snd_filenames[i]);
rain_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -140,7 +147,8 @@ SDL_Surface *rain_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, rain_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
rain_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -157,13 +165,15 @@ int rain_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *rain_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *rain_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(rain_descs[which][mode - 1])));
}
// Do the effect:
static void do_rain_drop(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
static void do_rain_drop(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -172,54 +182,59 @@ static void do_rain_drop(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * ca
Uint8 r, g, b;
for (yy = y - rain_SIZE / 2; yy < y + rain_SIZE / 2; yy++)
{
for (xx = x - rain_SIZE; xx < x + rain_SIZE; xx++)
{
for (xx = x - rain_SIZE; xx < x + rain_SIZE; xx++)
{
if (rain_inRainShape(xx - x, yy - y + rain_SIZE / 2, rain_SIZE))
{
//api->rgbtohsv(rain_r, rain_g, rain_b, &h, &s, &v);
//api->hsvtorgb(h, s, rain_weights[(yy-y)*((rain_SIZE*2) -1)+(xx-x)], &r, &g, &b);
SDL_GetRGB(api->getpixel(canvas, xx, yy), canvas->format, &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, clamp(0, r - 50, 255),
clamp(0, g - 50, 255), clamp(0, b + 200, 255)));
}
}
if (rain_inRainShape(xx - x, yy - y + rain_SIZE / 2, rain_SIZE))
{
//api->rgbtohsv(rain_r, rain_g, rain_b, &h, &s, &v);
//api->hsvtorgb(h, s, rain_weights[(yy-y)*((rain_SIZE*2) -1)+(xx-x)], &r, &g, &b);
SDL_GetRGB(api->getpixel(canvas, xx, yy), canvas->format, &r, &g, &b);
api->putpixel(canvas, xx, yy,
SDL_MapRGB(canvas->format, clamp(0, r - 50, 255),
clamp(0, g - 50, 255), clamp(0, b + 200,
255)));
}
}
}
}
static void rain_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void rain_linecb(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
SDL_Rect rect;
if (rand() % 10 == 0)
{
rain_click(api, which, MODE_PAINT, canvas, last,
x + (rand() % rain_SIZE * 2) - rain_SIZE, y + (rand() % rain_SIZE * 2) - rain_SIZE, &rect);
}
{
rain_click(api, which, MODE_PAINT, canvas, last,
x + (rand() % rain_SIZE * 2) - rain_SIZE,
y + (rand() % rain_SIZE * 2) - rain_SIZE, &rect);
}
}
// Affect the canvas on drag:
void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, rain_linecb);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, rain_linecb);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - rain_SIZE * 2;
update_rect->y = oy - rain_SIZE * 2;
@ -229,43 +244,48 @@ void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void rain_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
{
do_rain_drop(api, which, canvas, last, x, y);
{
do_rain_drop(api, which, canvas, last, x, y);
update_rect->x = x - rain_SIZE;
update_rect->y = y - rain_SIZE;
update_rect->w = rain_SIZE * 2;
update_rect->h = rain_SIZE * 2;
update_rect->x = x - rain_SIZE;
update_rect->y = y - rain_SIZE;
update_rect->w = rain_SIZE * 2;
update_rect->h = rain_SIZE * 2;
api->playsound(rain_snd_effect[which], (x * 255) / canvas->w, 255);
}
api->playsound(rain_snd_effect[which], (x * 255) / canvas->w, 255);
}
else
{
int i;
for (i = 0; i < rain_AMOUNT; i++)
{
int i;
for (i = 0; i < rain_AMOUNT; i++)
{
do_rain_drop(api, which, canvas, last, rand() % canvas->w, rand() % canvas->h);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(rain_snd_effect[which], 128, 255);
do_rain_drop(api, which, canvas, last, rand() % canvas->w,
rand() % canvas->h);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(rain_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void rain_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void rain_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -276,33 +296,37 @@ void rain_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < rain_NUM_TOOLS; i++)
{
if (rain_snd_effect[i] != NULL)
{
if (rain_snd_effect[i] != NULL)
{
Mix_FreeChunk(rain_snd_effect[i]);
}
Mix_FreeChunk(rain_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void rain_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void rain_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int rain_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rain_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void rain_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rain_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void rain_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rain_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -76,23 +76,29 @@ SDL_Surface *rainbow_get_icon(magic_api * api, int which);
char *rainbow_get_name(magic_api * api, int which);
int rainbow_get_group(magic_api * api, int which);
char *rainbow_get_description(magic_api * api, int which, int mode);
static void rainbow_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void rainbow_linecb(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void rainbow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void rainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void rainbow_shutdown(magic_api * api);
void rainbow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int rainbow_requires_colors(magic_api * api, int which);
void rainbow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rainbow_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void rainbow_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int rainbow_modes(magic_api * api, int which);
Uint32 rainbow_api_version(void)
@ -109,7 +115,8 @@ int rainbow_init(magic_api * api)
rainbow_color = 0;
rainbow_mix = 0;
snprintf(fname, sizeof(fname), "%ssounds/magic/rainbow.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/rainbow.wav",
api->data_directory);
rainbow_snd = Mix_LoadWAV(fname);
return (1);
@ -126,29 +133,37 @@ SDL_Surface *rainbow_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/rainbow.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/rainbow.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *rainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *rainbow_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
if (which == 0) {
if (which == 0)
{
return (strdup(gettext_noop("Rainbow")));
} else {
}
else
{
return (strdup(gettext_noop("Smooth Rainbow")));
}
}
// Return our group:
int rainbow_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rainbow_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PAINTING;
}
// Return our descriptions, localized:
char *rainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *rainbow_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("You can draw in rainbow colors!")));
}
@ -156,37 +171,43 @@ char *rainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIB
// Do the effect:
static void rainbow_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
for (xx = x - 16; xx < x + 16; xx++)
{
if (api->in_circle(xx - x, yy - y, 16))
{
api->putpixel(canvas, xx, yy, rainbow_rgb);
}
}
if (api->in_circle(xx - x, yy - y, 16))
{
api->putpixel(canvas, xx, yy, rainbow_rgb);
}
}
}
}
// Affect the canvas on drag:
void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
Uint8 r1, g1, b1, r2, g2, b2;
int rc_tmp;
if (which == 1) {
if (which == 1)
{
rainbow_mix += 1;
if (rainbow_mix > MIX_MAX) {
if (rainbow_mix > MIX_MAX)
{
rainbow_mix = 0;
rainbow_color = (rainbow_color + 1) % NUM_RAINBOW_COLORS;
}
} else {
}
else
{
rainbow_mix = 0;
rainbow_color = (rainbow_color + 1) % NUM_RAINBOW_COLORS;
}
@ -201,26 +222,30 @@ void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
b2 = rainbow_hexes[rc_tmp][2];
rainbow_rgb = SDL_MapRGB(canvas->format,
((r1 * (MIX_MAX - rainbow_mix)) + (r2 * rainbow_mix)) / MIX_MAX,
((g1 * (MIX_MAX - rainbow_mix)) + (g2 * rainbow_mix)) / MIX_MAX,
((b1 * (MIX_MAX - rainbow_mix)) + (b2 * rainbow_mix)) / MIX_MAX);
((r1 * (MIX_MAX - rainbow_mix)) +
(r2 * rainbow_mix)) / MIX_MAX,
((g1 * (MIX_MAX - rainbow_mix)) +
(g2 * rainbow_mix)) / MIX_MAX,
((b1 * (MIX_MAX - rainbow_mix)) +
(b2 * rainbow_mix)) / MIX_MAX);
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, rainbow_linecb);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
rainbow_linecb);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -232,14 +257,18 @@ void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void rainbow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
rainbow_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void rainbow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void rainbow_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -251,28 +280,33 @@ void rainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void rainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void rainbow_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int rainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void rainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rainbow_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void rainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rainbow_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int rainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rainbow_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -24,12 +24,15 @@ Mix_Chunk *realrainbow_snd;
int realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2;
SDL_Rect realrainbow_rect;
SDL_Surface *realrainbow_colors[2];
Uint8 realrainbow_blendr, realrainbow_blendg, realrainbow_blendb, realrainbow_blenda;
Uint8 realrainbow_blendr, realrainbow_blendg, realrainbow_blendb,
realrainbow_blenda;
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last,
int x1, int y1, int x2, int y2, int fulldraw, SDL_Rect * update_rect);
static void realrainbow_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x1, int y1, int x2, int y2,
int fulldraw, SDL_Rect * update_rect);
static void realrainbow_linecb(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
Uint32 realrainbow_api_version(void);
int realrainbow_init(magic_api * api);
int realrainbow_get_tool_count(magic_api * api);
@ -42,13 +45,18 @@ int realrainbow_requires_colors(magic_api * api, int which);
void realrainbow_shutdown(magic_api * api);
void realrainbow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void realrainbow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void realrainbow_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void realrainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void realrainbow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void realrainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void realrainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void realrainbow_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void realrainbow_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void realrainbow_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
Uint32 realrainbow_api_version(void)
@ -60,17 +68,21 @@ int realrainbow_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow-colors.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow-colors.png",
api->data_directory);
realrainbow_colors[0] = IMG_Load(fname);
if (realrainbow_colors[0] == NULL)
return (0);
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow-roygbiv-colors.png", api->data_directory);
snprintf(fname, sizeof(fname),
"%simages/magic/realrainbow-roygbiv-colors.png",
api->data_directory);
realrainbow_colors[1] = IMG_Load(fname);
if (realrainbow_colors[1] == NULL)
return (0);
snprintf(fname, sizeof(fname), "%ssounds/magic/realrainbow.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/realrainbow.ogg",
api->data_directory);
realrainbow_snd = Mix_LoadWAV(fname);
return (1);
@ -86,9 +98,11 @@ SDL_Surface *realrainbow_get_icon(magic_api * api, int which)
char fname[1024];
if (which == 0)
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow.png",
api->data_directory);
else
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow-roygbiv.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/realrainbow-roygbiv.png",
api->data_directory);
return (IMG_Load(fname));
}
@ -101,12 +115,14 @@ char *realrainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return (strdup(gettext_noop("ROYGBIV Rainbow")));
}
int realrainbow_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int realrainbow_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_ARTISTIC;
}
char *realrainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
char *realrainbow_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup
@ -114,12 +130,14 @@ char *realrainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which AT
("Click where you want your rainbow to start, drag to where you want it to end, and then let go to draw a rainbow.")));
}
int realrainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int realrainbow_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT_WITH_PREVIEW);
}
int realrainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int realrainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (0);
}
@ -134,14 +152,17 @@ void realrainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(realrainbow_snd);
}
void realrainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void realrainbow_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
realrainbow_x1 = x;
realrainbow_y1 = y;
@ -154,7 +175,8 @@ void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
void realrainbow_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x,
int y, SDL_Rect * update_rect)
{
int rx1, ry1, rx2, ry2;
SDL_Rect rect;
@ -164,8 +186,8 @@ void realrainbow_drag(magic_api * api, int which,
SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 0,
update_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1,
realrainbow_x2, realrainbow_y2, 0, update_rect);
memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect));
memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect));
@ -191,7 +213,8 @@ void realrainbow_drag(magic_api * api, int which,
}
void realrainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x,
int y, SDL_Rect * update_rect)
{
int rx1, ry1, rx2, ry2;
SDL_Rect rect;
@ -201,8 +224,8 @@ void realrainbow_release(magic_api * api, int which,
SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 1,
update_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1,
realrainbow_x2, realrainbow_y2, 1, update_rect);
memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect));
memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect));
@ -229,19 +252,24 @@ void realrainbow_release(magic_api * api, int which,
api->playsound(realrainbow_snd, 128, 255);
}
void realrainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void realrainbow_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void realrainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void realrainbow_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x1, int y1, int x2,
int y2, int fulldraw, SDL_Rect * update_rect)
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x1, int y1, int x2, int y2,
int fulldraw, SDL_Rect * update_rect)
{
int lowx, lowy, hix, hiy, xm, ym, xc, yc, r, a1, atan2_a, atan2_b;
int a, oa, ox, oy, nx, ny, step, thick, rr, done;
@ -249,71 +277,71 @@ void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surfa
int colorindex;
if (abs(x2 - x1) < 50)
{
if (x2 > x1)
x2 = x1 + 50;
else
x2 = x1 - 50;
}
{
if (x2 > x1)
x2 = x1 + 50;
else
x2 = x1 - 50;
}
if (y1 == y2)
{
xc = x1 + (x2 - x1) / 2;
yc = y1;
r = abs(xc - x1);
{
xc = x1 + (x2 - x1) / 2;
yc = y1;
r = abs(xc - x1);
a1 = 0;
theta = -180;
}
a1 = 0;
theta = -180;
}
else
{
if (y1 > y2)
{
if (y1 > y2)
{
lowx = x1;
lowy = y1;
hix = x2;
hiy = y2;
}
else
{
lowx = x2;
lowy = y2;
hix = x1;
hiy = y1;
}
xm = (lowx + hix) / 2;
ym = (lowy + hiy) / 2;
if (hix == lowx)
return;
slope = (float)(hiy - lowy) / (float)(hix - lowx);
yc = lowy;
xc = slope * (ym - yc) + xm;
r = abs(xc - lowx);
atan2_b = hix - xc;
atan2_a = hiy - yc;
theta = atan2(atan2_a, atan2_b) * (180.0 / M_PI);
if (slope > 0)
a1 = 0;
else
a1 = -180;
lowx = x1;
lowy = y1;
hix = x2;
hiy = y2;
}
else
{
lowx = x2;
lowy = y2;
hix = x1;
hiy = y1;
}
xm = (lowx + hix) / 2;
ym = (lowy + hiy) / 2;
if (hix == lowx)
return;
slope = (float) (hiy - lowy) / (float) (hix - lowx);
yc = lowy;
xc = slope * (ym - yc) + xm;
r = abs(xc - lowx);
atan2_b = hix - xc;
atan2_a = hiy - yc;
theta = atan2(atan2_a, atan2_b) * (180.0 / M_PI);
if (slope > 0)
a1 = 0;
else
a1 = -180;
}
if (fulldraw)
{
step = 1;
/* thick = (r / 5); */
}
{
step = 1;
/* thick = (r / 5); */
}
else
{
step = 30;
/* thick = 1; */
}
{
step = 30;
/* thick = 1; */
}
thick = (r / 5);
if (theta < a1)
@ -323,37 +351,40 @@ void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surfa
oa = a1;
for (a = (a1 + step); done < 2; a = a + step)
{
for (rr = r - (thick / 2); rr <= r + (thick / 2); rr++)
{
for (rr = r - (thick / 2); rr <= r + (thick / 2); rr++)
{
ox = (rr * cos(oa * M_PI / 180.0)) + xc;
oy = (rr * sin(oa * M_PI / 180.0)) + yc;
ox = (rr * cos(oa * M_PI / 180.0)) + xc;
oy = (rr * sin(oa * M_PI / 180.0)) + yc;
nx = (rr * cos(a * M_PI / 180.0)) + xc;
ny = (rr * sin(a * M_PI / 180.0)) + yc;
nx = (rr * cos(a * M_PI / 180.0)) + xc;
ny = (rr * sin(a * M_PI / 180.0)) + yc;
colorindex =
realrainbow_colors[which]->h - 1 - (((rr - r + (thick / 2)) * realrainbow_colors[which]->h) / thick);
colorindex =
realrainbow_colors[which]->h - 1 -
(((rr - r + (thick / 2)) * realrainbow_colors[which]->h) / thick);
SDL_GetRGBA(api->getpixel(realrainbow_colors[which], 0, colorindex),
realrainbow_colors[which]->format, &realrainbow_blendr, &realrainbow_blendg, &realrainbow_blendb,
&realrainbow_blenda);
SDL_GetRGBA(api->getpixel(realrainbow_colors[which], 0, colorindex),
realrainbow_colors[which]->format, &realrainbow_blendr,
&realrainbow_blendg, &realrainbow_blendb,
&realrainbow_blenda);
if (!fulldraw)
realrainbow_blenda = 255;
if (!fulldraw)
realrainbow_blenda = 255;
api->line((void *)api, 0, canvas, last, ox, oy, nx, ny, 1, realrainbow_linecb);
}
oa = a;
if ((step > 0 && a + step > theta) || (step < 0 && a + step < theta))
{
done++;
a = theta - step;
}
api->line((void *) api, 0, canvas, last, ox, oy, nx, ny, 1,
realrainbow_linecb);
}
oa = a;
if ((step > 0 && a + step > theta) || (step < 0 && a + step < theta))
{
done++;
a = theta - step;
}
}
update_rect->y = yc - r - thick - 2;
update_rect->h = r + thick * 2 + 4;
update_rect->x = xc - r - thick;
@ -361,7 +392,8 @@ void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surfa
}
static void realrainbow_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 origr, origg, origb;
@ -369,9 +401,15 @@ static void realrainbow_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_GetRGB(api->getpixel(last, x, y), last->format, &origr, &origg, &origb);
newr = ((realrainbow_blendr * realrainbow_blenda) / 255) + ((origr * (255 - realrainbow_blenda)) / 255);
newg = ((realrainbow_blendg * realrainbow_blenda) / 255) + ((origg * (255 - realrainbow_blenda)) / 255);
newb = ((realrainbow_blendb * realrainbow_blenda) / 255) + ((origb * (255 - realrainbow_blenda)) / 255);
newr =
((realrainbow_blendr * realrainbow_blenda) / 255) +
((origr * (255 - realrainbow_blenda)) / 255);
newg =
((realrainbow_blendg * realrainbow_blenda) / 255) +
((origg * (255 - realrainbow_blenda)) / 255);
newb =
((realrainbow_blendb * realrainbow_blenda) / 255) +
((origb * (255 - realrainbow_blenda)) / 255);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, newr, newg, newb));
}

View file

@ -60,18 +60,23 @@ char *reflection_get_name(magic_api * api, int which);
int reflection_get_group(magic_api * api, int which);
char *reflection_get_description(magic_api * api, int which, int mode);
void reflection_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void do_reflection(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect, int show_origin);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void do_reflection(magic_api * api, SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect, int show_origin);
void reflection_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void reflection_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void reflection_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void reflection_shutdown(magic_api * api);
void reflection_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int reflection_requires_colors(magic_api * api, int which);
void reflection_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void reflection_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void reflection_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void reflection_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int reflection_modes(magic_api * api, int which);
@ -80,7 +85,8 @@ int reflection_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/reflection.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/reflection.ogg",
api->data_directory);
reflection_snd = Mix_LoadWAV(fname);
return (1);
@ -105,30 +111,38 @@ SDL_Surface *reflection_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
return (IMG_Load(fname));
}
char *reflection_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *reflection_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Reflection")));
}
int reflection_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int reflection_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
char *reflection_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *reflection_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag the mouse around to add a reflection to your picture.")));
return (strdup
(gettext_noop
("Click and drag the mouse around to add a reflection to your picture.")));
}
void reflection_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect)
void reflection_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x,
int y, SDL_Rect * update_rect)
{
do_reflection(api, canvas, last, x, y, update_rect, 1);
}
void do_reflection(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect, int show_origin)
SDL_Surface * last, int x, int y, SDL_Rect * update_rect,
int show_origin)
{
float scale;
int xx, yy;
@ -149,29 +163,29 @@ void do_reflection(magic_api * api, SDL_Surface * canvas,
/* Determine what direction to go */
if (abs(x - reflection_x1) < 32)
{
/* +/-32 pixels of wiggle room before we switch from vertical to horizontal */
if (y > reflection_y1)
reflection_side = REFLECTION_SIDE_BOTTOM;
else
reflection_side = REFLECTION_SIDE_TOP;
}
{
/* +/-32 pixels of wiggle room before we switch from vertical to horizontal */
if (y > reflection_y1)
reflection_side = REFLECTION_SIDE_BOTTOM;
else
reflection_side = REFLECTION_SIDE_TOP;
}
else
{
if (x < reflection_x1)
reflection_side = REFLECTION_SIDE_LEFT;
else
reflection_side = REFLECTION_SIDE_RIGHT;
}
{
if (x < reflection_x1)
reflection_side = REFLECTION_SIDE_LEFT;
else
reflection_side = REFLECTION_SIDE_RIGHT;
}
/* If we've changed direction, reset the canvas back
to the snapshot before proceeding */
if (reflection_side != reflection_side_old)
{
SDL_BlitSurface(last, NULL, canvas, NULL);
reflection_side_old = reflection_side;
update_all = 1;
}
{
SDL_BlitSurface(last, NULL, canvas, NULL);
reflection_side_old = reflection_side;
update_all = 1;
}
/* Note: This isn't very good, and I basically
@ -179,173 +193,179 @@ void do_reflection(magic_api * api, SDL_Surface * canvas,
well enough. There's a ton of room for improvement!
-bjk 2021.11.05 */
if (reflection_side == REFLECTION_SIDE_BOTTOM)
{
/* Starting from `reflection_y1` and moving down,
we'll copy from `reflection_y1` and moving up */
scale = (float) reflection_y1 / (float) y;
for (yy = reflection_y1; yy < canvas->h; yy++)
{
/* Starting from `reflection_y1` and moving down,
we'll copy from `reflection_y1` and moving up */
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
scale = (float) reflection_y1 / (float) y;
src.x = 0;
src.y = (reflection_y1 * scale) + ((y - yy) * scale);
src.w = canvas->w;
src.h = 1;
for (yy = reflection_y1; yy < canvas->h; yy++)
{
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
if (src.y < 0)
{
src.y = yy;
}
src.x = 0;
src.y = (reflection_y1 * scale) + ((y - yy) * scale);
src.w = canvas->w;
src.h = 1;
if (src.y < 0)
{
src.y = yy;
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = reflection_y1;
update_rect->w = canvas->w;
update_rect->h = canvas->h - reflection_y1 + 1;
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = reflection_y1;
update_rect->w = canvas->w;
update_rect->h = canvas->h - reflection_y1 + 1;
}
else if (reflection_side == REFLECTION_SIDE_TOP)
{
/* Starting from `reflection_y1` and moving up,
we'll copy from `reflection_y1` and moving down */
scale = ((float) reflection_y1 / (float) y);
for (yy = reflection_y1; yy >= 0; yy--)
{
/* Starting from `reflection_y1` and moving up,
we'll copy from `reflection_y1` and moving down */
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
scale = ((float) reflection_y1 / (float) y);
src.x = 0;
src.y = (reflection_y1 / scale) + (y * scale) - (yy / scale);
src.w = canvas->w;
src.h = 1;
for (yy = reflection_y1; yy >= 0; yy--)
{
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
if (src.y >= canvas->h)
{
src.y = yy;
}
src.x = 0;
src.y = (reflection_y1 / scale) + (y * scale) - (yy / scale);
src.w = canvas->w;
src.h = 1;
if (src.y >= canvas->h)
{
src.y = yy;
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = reflection_y1;
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = reflection_y1;
}
else if (reflection_side == REFLECTION_SIDE_RIGHT)
{
/* Starting from `reflection_x1` and moving right,
we'll copy from `reflection_x1` and moving left */
scale = (float) reflection_x1 / (float) x;
for (xx = reflection_x1; xx < canvas->w; xx++)
{
/* Starting from `reflection_x1` and moving right,
we'll copy from `reflection_x1` and moving left */
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
scale = (float) reflection_x1 / (float) x;
src.x = (reflection_x1 * scale) + ((x - xx) * scale);
src.y = 0;
src.w = 1;
src.h = canvas->h;
for (xx = reflection_x1; xx < canvas->w; xx++)
{
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
if (src.x < 0)
{
src.x = xx;
}
src.x = (reflection_x1 * scale) + ((x - xx) * scale);
src.y = 0;
src.w = 1;
src.h = canvas->h;
if (src.x < 0)
{
src.x = xx;
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = reflection_x1;
update_rect->y = 0;
update_rect->w = canvas->w - reflection_x1 + 1;
update_rect->h = canvas->h;
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = reflection_x1;
update_rect->y = 0;
update_rect->w = canvas->w - reflection_x1 + 1;
update_rect->h = canvas->h;
}
else if (reflection_side == REFLECTION_SIDE_LEFT)
{
/* Starting from `reflection_x1` and left up,
we'll copy from `reflection_x1` and right down */
scale = (float) reflection_x1 / (float) x;
for (xx = reflection_x1; xx >= 0; xx--)
{
/* Starting from `reflection_x1` and left up,
we'll copy from `reflection_x1` and right down */
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
scale = (float) reflection_x1 / (float) x;
src.x = (reflection_x1 / scale) + (x * scale) - (xx / scale);
src.y = 0;
src.w = 1;
src.h = canvas->h;
for (xx = reflection_x1; xx >= 0; xx--)
{
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
if (src.x >= canvas->w)
{
src.x = xx;
}
src.x = (reflection_x1 / scale) + (x * scale) - (xx / scale);
src.y = 0;
src.w = 1;
src.h = canvas->h;
if (src.x >= canvas->w)
{
src.x = xx;
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = reflection_x1;
update_rect->h = canvas->h;
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = reflection_x1;
update_rect->h = canvas->h;
}
/* TODO: Support reflecting at arbitrary angles!
(a la linear gradient fill tool) */
if (update_all)
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
else
{
for (yy = reflection_y1 - REFLECTION_XOR_SIZE;
yy < reflection_y1 + REFLECTION_XOR_SIZE; yy++)
{
for (yy = reflection_y1 - REFLECTION_XOR_SIZE; yy < reflection_y1 + REFLECTION_XOR_SIZE; yy++)
{
if (show_origin)
api->xorpixel(canvas, reflection_x1, yy);
else
api->putpixel(canvas, reflection_x1, yy, api->getpixel(last, reflection_x1, yy));
}
for (xx = reflection_x1 - REFLECTION_XOR_SIZE; xx < reflection_x1 + REFLECTION_XOR_SIZE; xx++)
{
if (show_origin)
api->xorpixel(canvas, xx, reflection_y1);
else
api->putpixel(canvas, xx, reflection_y1, api->getpixel(last, xx, reflection_y1));
}
update_rect->x -= REFLECTION_XOR_SIZE;
update_rect->w += (REFLECTION_XOR_SIZE * 2);
update_rect->y -= REFLECTION_XOR_SIZE;
update_rect->h += (REFLECTION_XOR_SIZE * 2);
if (show_origin)
api->xorpixel(canvas, reflection_x1, yy);
else
api->putpixel(canvas, reflection_x1, yy,
api->getpixel(last, reflection_x1, yy));
}
api->playsound(reflection_snd, (x * 255) / canvas->w, (y * 255) / canvas->h);
for (xx = reflection_x1 - REFLECTION_XOR_SIZE;
xx < reflection_x1 + REFLECTION_XOR_SIZE; xx++)
{
if (show_origin)
api->xorpixel(canvas, xx, reflection_y1);
else
api->putpixel(canvas, xx, reflection_y1,
api->getpixel(last, xx, reflection_y1));
}
update_rect->x -= REFLECTION_XOR_SIZE;
update_rect->w += (REFLECTION_XOR_SIZE * 2);
update_rect->y -= REFLECTION_XOR_SIZE;
update_rect->h += (REFLECTION_XOR_SIZE * 2);
}
api->playsound(reflection_snd, (x * 255) / canvas->w,
(y * 255) / canvas->h);
}
void reflection_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (x <= 0)
x = 1;
@ -365,8 +385,8 @@ void reflection_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
}
void reflection_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
do_reflection(api, canvas, last, x, y, update_rect, 0);
}
@ -377,29 +397,35 @@ void reflection_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(reflection_snd);
}
void reflection_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
void reflection_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
int reflection_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int reflection_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void reflection_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
void reflection_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
reflection_x1 = canvas->w / 2;
reflection_y1 = canvas->h / 2;
}
void reflection_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
void reflection_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int reflection_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int reflection_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MODE_PAINT;
}

View file

@ -49,17 +49,22 @@ char *ripples_get_name(magic_api * api, int which);
int ripples_get_group(magic_api * api, int which);
char *ripples_get_description(magic_api * api, int which, int mode);
void ripples_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
static void ripples_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void ripples_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void ripples_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
static void ripples_linecb(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void ripples_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void ripples_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void ripples_shutdown(magic_api * api);
void ripples_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int ripples_requires_colors(magic_api * api, int which);
void ripples_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void ripples_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void ripples_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void ripples_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int ripples_modes(magic_api * api, int which);
Uint32 ripples_api_version(void)
@ -75,7 +80,8 @@ int ripples_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/ripples.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/ripples.ogg",
api->data_directory);
ripples_snd = Mix_LoadWAV(fname);
return (1);
@ -92,38 +98,49 @@ SDL_Surface *ripples_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/ripples.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/ripples.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *ripples_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *ripples_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Ripples")));
}
// Return our groups:
int ripples_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int ripples_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *ripples_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *ripples_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click to make ripples appear over your picture.")));
return (strdup
(gettext_noop("Click to make ripples appear over your picture.")));
}
// Affect the canvas on drag:
void ripples_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void ripples_drag(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
static void ripples_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last, int x,
int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 r, g, b;
@ -141,7 +158,8 @@ static void ripples_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
// Affect the canvas on click:
void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
float radius;
float fli;
@ -150,25 +168,26 @@ void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
radius = 100;
for (fli = 0; fli < radius; fli = fli + .25)
{
ripples_z = (10 * deg_sin(((50 * 50) / (fli + 4)) * 10));
ox = fli * deg_cos(0) + x;
oy = -fli * deg_sin(0) + y;
for (d = 0; d <= 360 + (360 / (fli + 1)); d = d + 360 / (fli + 1))
{
ripples_z = (10 * deg_sin(((50 * 50) / (fli + 4)) * 10));
nx = fli * deg_cos(d) + x;
ny = -fli * deg_sin(d) + y;
ox = fli * deg_cos(0) + x;
oy = -fli * deg_sin(0) + y;
ripples_brite = (ripples_z * 20 * deg_sin(d + 45)) / ((fli / 4) + 1);
for (d = 0; d <= 360 + (360 / (fli + 1)); d = d + 360 / (fli + 1))
{
nx = fli * deg_cos(d) + x;
ny = -fli * deg_sin(d) + y;
api->line((void *) api, which, canvas, last, ox, oy, nx, ny, 1,
ripples_linecb);
ripples_brite = (ripples_z * 20 * deg_sin(d + 45)) / ((fli / 4) + 1);
api->line((void *)api, which, canvas, last, ox, oy, nx, ny, 1, ripples_linecb);
ox = nx;
oy = ny;
}
ox = nx;
oy = ny;
}
}
update_rect->x = x - 100;
update_rect->y = y - 100;
@ -179,9 +198,12 @@ void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
}
// Affect the canvas on release:
void ripples_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void ripples_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -193,28 +215,33 @@ void ripples_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void ripples_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void ripples_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int ripples_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int ripples_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void ripples_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void ripples_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void ripples_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void ripples_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int ripples_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int ripples_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_ONECLICK);
}

View file

@ -60,18 +60,25 @@ int rosette_get_group(magic_api * api, int which);
char *rosette_get_description(magic_api * api, int which, int mode);
int rosette_requires_colors(magic_api * api, int which);
void rosette_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void rosette_shutdown(magic_api * api);
void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void rosette_draw(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void rosette_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void rosette_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void rosette_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rosette_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void rosette_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void rosette_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int rosette_modes(magic_api * api, int which);
void rosette_circle(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void rosette_circle(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
Uint32 rosette_api_version(void)
{
@ -89,7 +96,8 @@ int rosette_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/picasso.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/picasso.ogg",
api->data_directory);
rosette_snd = Mix_LoadWAV(fname);
return (1);
@ -105,9 +113,11 @@ SDL_Surface *rosette_get_icon(magic_api * api, int which)
char fname[1024];
if (!which)
snprintf(fname, sizeof(fname), "%simages/magic/rosette.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/rosette.png",
api->data_directory);
else
snprintf(fname, sizeof(fname), "%simages/magic/picasso.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/picasso.png",
api->data_directory);
return (IMG_Load(fname));
}
@ -120,12 +130,14 @@ char *rosette_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return strdup(gettext_noop("Picasso"));
}
int rosette_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rosette_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PATTERN_PAINTING;
}
char *rosette_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *rosette_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (!which)
return strdup(gettext_noop("Click and start drawing your rosette.")); //just k'scope with 3 bits?
@ -133,14 +145,18 @@ char *rosette_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int m
return strdup(gettext_noop("You can draw just like Picasso!")); //what is this actually doing?
}
int rosette_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rosette_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void rosette_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void rosette_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -152,7 +168,8 @@ void rosette_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Interactivity functions
void rosette_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -161,11 +178,14 @@ void rosette_circle(void *ptr, int which ATTRIBUTE_UNUSED,
for (yy = y - ROSETTE_R; yy < y + ROSETTE_R; yy++)
for (xx = x - ROSETTE_R; xx < x + ROSETTE_R; xx++)
if (api->in_circle(xx - x, yy - y, ROSETTE_R / 2))
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, rosette_colors.r, rosette_colors.g, rosette_colors.b));
api->putpixel(canvas, xx, yy,
SDL_MapRGB(canvas->format, rosette_colors.r,
rosette_colors.g, rosette_colors.b));
}
void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
void rosette_draw(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -173,41 +193,41 @@ void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snap
double xx, yy; //distance to the center of the image
int x1, y1, x2, y2;
xx = (double)(xmid - x);
yy = (double)(y - ymid);
xx = (double) (xmid - x);
yy = (double) (y - ymid);
if (which == 0)
{
angle = 2 * M_PI / 3; //an angle between brushes
{
angle = 2 * M_PI / 3; //an angle between brushes
x1 = (int)(xx * cos(angle) - yy * sin(angle));
y1 = (int)(xx * sin(angle) + yy * cos(angle));
x1 = (int) (xx * cos(angle) - yy * sin(angle));
y1 = (int) (xx * sin(angle) + yy * cos(angle));
x2 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int)(xx * sin(2 * angle) + yy * cos(2 * angle));
}
x2 = (int) (xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int) (xx * sin(2 * angle) + yy * cos(2 * angle));
}
else
{
angle = atan(yy / xx);
{
angle = atan(yy / xx);
if ((xx < 0) && (yy > 0))
angle += M_PI;
if ((xx < 0) && (yy > 0))
angle += M_PI;
if ((xx < 0) && (yy < 0))
angle += M_PI;
if ((xx < 0) && (yy < 0))
angle += M_PI;
if ((xx > 0) && (yy < 0))
angle += 2 * M_PI;
if ((xx > 0) && (yy < 0))
angle += 2 * M_PI;
if ((y == ymid) && (xx < 0))
angle = M_PI;
if ((y == ymid) && (xx < 0))
angle = M_PI;
x1 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y1 = (int)(xx * sin(2 * angle) - yy * cos(angle));
x1 = (int) (xx * cos(2 * angle) - yy * sin(2 * angle));
y1 = (int) (xx * sin(2 * angle) - yy * cos(angle));
x2 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int)(xx * sin(2 * angle) + yy * cos(2 * angle));
}
x2 = (int) (xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int) (xx * sin(2 * angle) + yy * cos(2 * angle));
}
rosette_circle(api, which, canvas, snapshot, x, y);
rosette_circle(api, which, canvas, snapshot, (-1) * (x1 - xmid), y1 + ymid);
@ -215,9 +235,11 @@ void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snap
}
void rosette_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, rosette_draw);
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, 1,
rosette_draw);
api->playsound(rosette_snd, (x * 255) / canvas->w, 255);
update_rect->x = update_rect->y = 0;
@ -226,25 +248,29 @@ void rosette_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void rosette_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
rosette_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void rosette_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rosette_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
xmid = canvas->w / 2;
ymid = canvas->h / 2;
}
void rosette_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void rosette_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int rosette_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int rosette_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -79,12 +79,15 @@ const char *sharpen_names[sharpen_NUM_TOOLS] = {
};
const char *sharpen_descs[sharpen_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to trace edges in parts of your picture."),
{gettext_noop
("Click and drag the mouse to trace edges in parts of your picture."),
gettext_noop("Click to trace edges in your entire picture."),},
{gettext_noop("Click and drag the mouse to sharpen parts of your picture."),
gettext_noop("Click to sharpen the entire picture."),},
{gettext_noop("Click and drag the mouse to create a black and white silhouette."),
gettext_noop("Click to create a black and white silhouette of your entire picture.")},
{gettext_noop
("Click and drag the mouse to create a black and white silhouette."),
gettext_noop
("Click to create a black and white silhouette of your entire picture.")},
};
Uint32 sharpen_api_version(void);
@ -95,22 +98,29 @@ char *sharpen_get_name(magic_api * api, int which);
int sharpen_get_group(magic_api * api, int which);
char *sharpen_get_description(magic_api * api, int which, int mode);
static int sharpen_grey(Uint8 r1, Uint8 g1, Uint8 b1);
static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_sharpen_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void do_sharpen_full(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int which);
static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void sharpen_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void sharpen_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void sharpen_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void sharpen_shutdown(magic_api * api);
void sharpen_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int sharpen_requires_colors(magic_api * api, int which);
void sharpen_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void sharpen_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void sharpen_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void sharpen_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int sharpen_modes(magic_api * api, int which);
Uint32 sharpen_api_version(void)
@ -127,10 +137,11 @@ int sharpen_init(magic_api * api)
char fname[1024];
for (i = 0; i < sharpen_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, sharpen_snd_filenames[i]);
sharpen_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
sharpen_snd_filenames[i]);
sharpen_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -146,7 +157,8 @@ SDL_Surface *sharpen_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, sharpen_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
sharpen_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -157,13 +169,15 @@ char *sharpen_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (all the same):
int sharpen_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int sharpen_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_DISTORTS;
}
// Return our descriptions, localized:
char *sharpen_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *sharpen_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(sharpen_descs[which][mode - 1])));
}
@ -175,7 +189,8 @@ static int sharpen_grey(Uint8 r1, Uint8 g1, Uint8 b1)
}
// Do the effect:
static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -198,104 +213,113 @@ static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Sur
sobel_1 = 0;
sobel_2 = 0;
for (i = -1; i < 2; i++)
{
for (j = -1; j < 2; j++)
{
for (j = -1; j < 2; j++)
{
//No need to check if inside canvas, getpixel does it for us.
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1, &b1);
grey = sharpen_grey(r1, g1, b1);
sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
//No need to check if inside canvas, getpixel does it for us.
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1,
&b1);
grey = sharpen_grey(r1, g1, b1);
sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
}
temp = sqrt(sobel_1 * sobel_1 + sobel_2 * sobel_2);
temp = (temp / 1443) * 255.0;
// set image to white where edge value is below THRESHOLD
if (which == TOOL_TRACE)
{
if (temp < THRESHOLD)
{
if (temp < THRESHOLD)
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
//Simply display the edge values - provides a nice black and white silhouette image
else if (which == TOOL_SILHOUETTE)
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp, temp, temp));
}
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp, temp, temp));
}
//Add the edge values to the original image, creating a more distinct jump in contrast at edges
else if (which == TOOL_SHARPEN)
{
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + SHARPEN * temp, 255.0),
clamp(0.0, g1 + SHARPEN * temp, 255.0),
clamp(0.0, b1 + SHARPEN * temp, 255.0)));
}
{
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1);
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format,
clamp(0.0, r1 + SHARPEN * temp, 255.0),
clamp(0.0, g1 + SHARPEN * temp, 255.0),
clamp(0.0, b1 + SHARPEN * temp, 255.0)));
}
}
// Do the effect for the full image
static void do_sharpen_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
static void do_sharpen_full(void *ptr, SDL_Surface * canvas,
SDL_Surface * last, int which)
{
magic_api * api = (magic_api *) ptr;
magic_api *api = (magic_api *) ptr;
int x, y;
for (y = 0; y < last->h; y++)
{
if (y % 10 == 0)
{
if (y % 10 == 0) {
api->update_progress_bar();
}
for (x = 0; x < last->w; x++)
{
do_sharpen_pixel(api, which, canvas, last, x, y);
}
api->update_progress_bar();
}
for (x = 0; x < last->w; x++)
{
do_sharpen_pixel(api, which, canvas, last, x, y);
}
}
}
//do the effect for the brush
static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - sharpen_RADIUS; yy < y + sharpen_RADIUS; yy++)
{
for (xx = x - sharpen_RADIUS; xx < x + sharpen_RADIUS; xx++)
{
for (xx = x - sharpen_RADIUS; xx < x + sharpen_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, sharpen_RADIUS) && !api->touched(xx, yy))
{
do_sharpen_pixel(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, sharpen_RADIUS)
&& !api->touched(xx, yy))
{
do_sharpen_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag:
void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_sharpen_brush);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_sharpen_brush);
api->playsound(sharpen_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - sharpen_RADIUS;
update_rect->y = oy - sharpen_RADIUS;
@ -305,25 +329,29 @@ void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void sharpen_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
sharpen_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_sharpen_full(api, canvas, last, which);
api->playsound(sharpen_snd_effect[which], 128, 255);
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_sharpen_full(api, canvas, last, which);
api->playsound(sharpen_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void sharpen_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void sharpen_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -334,37 +362,42 @@ void sharpen_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < sharpen_NUM_TOOLS; i++)
{
if (sharpen_snd_effect[i] != NULL)
{
if (sharpen_snd_effect[i] != NULL)
{
Mix_FreeChunk(sharpen_snd_effect[i]);
}
Mix_FreeChunk(sharpen_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void sharpen_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void sharpen_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int sharpen_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int sharpen_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void sharpen_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void sharpen_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void sharpen_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void sharpen_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int sharpen_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int sharpen_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_FULLSCREEN | MODE_PAINT);
}

View file

@ -44,7 +44,8 @@ static Mix_Chunk *shift_snd;
/* Local function prototypes: */
static void shift_doit(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect, int crosshairs);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect, int crosshairs);
Uint32 shift_api_version(void);
int shift_init(magic_api * api);
int shift_get_tool_count(magic_api * api);
@ -53,17 +54,20 @@ char *shift_get_name(magic_api * api, int which);
int shift_get_group(magic_api * api, int which);
char *shift_get_description(magic_api * api, int which, int mode);
void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void shift_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void shift_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void shift_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void shift_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void shift_shutdown(magic_api * api);
void shift_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int shift_requires_colors(magic_api * api, int which);
void shift_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void shift_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void shift_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void shift_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int shift_modes(magic_api * api, int which);
@ -79,7 +83,8 @@ int shift_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/shift.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/shift.ogg",
api->data_directory);
shift_snd = Mix_LoadWAV(fname);
return (1);
@ -92,37 +97,46 @@ int shift_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
}
// Load our icons:
SDL_Surface *shift_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
SDL_Surface *shift_get_icon(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/shift.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/shift.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *shift_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *shift_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Shift")));
}
// Return our group
int shift_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int shift_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
// Return our descriptions, localized:
char *shift_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *shift_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to shift your picture around on the canvas.")));
return (strdup
(gettext_noop
("Click and drag to shift your picture around on the canvas.")));
}
// Affect the canvas on drag:
void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
if (ox == x && oy == y)
return; /* No-op */
@ -130,8 +144,10 @@ void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
shift_doit(api, which, canvas, last, ox, oy, x, y, update_rect, 1);
}
static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
static void shift_doit(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect, int crosshairs)
{
SDL_Rect dest;
@ -162,123 +178,123 @@ static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
if (dy > 0)
{
if (dx > 0)
{
if (dx > 0)
{
/* Top Left */
/* Top Left */
dest.x = dx - canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
/* Top */
dest.x = dx;
dest.x = dx - canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Top Right */
dest.x = dx + canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
/* Top */
dest.x = dx;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Top Right */
dest.x = dx + canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
if (dx > 0)
{
/* Left */
{
/* Left */
dest.x = dx - canvas->w;
dest.y = dy;
dest.x = dx - canvas->w;
dest.y = dy;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
SDL_BlitSurface(last, NULL, canvas, &dest);
}
if (dx < 0)
{
/* Right */
{
/* Right */
dest.x = dx + canvas->w;
dest.y = dy;
dest.x = dx + canvas->w;
dest.y = dy;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
SDL_BlitSurface(last, NULL, canvas, &dest);
}
if (dy < 0)
{
if (dx > 0)
{
if (dx > 0)
{
/* Bottom Left */
/* Bottom Left */
dest.x = dx - canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
/* Bottom */
dest.x = dx;
dest.x = dx - canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Bottom Right */
dest.x = dx + canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
/* Bottom */
dest.x = dx;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Bottom Right */
dest.x = dx + canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
if (crosshairs)
{
dest.x = (canvas->w / 2) - 1;
dest.y = 0;
dest.w = 3;
dest.h = canvas->h;
{
dest.x = (canvas->w / 2) - 1;
dest.y = 0;
dest.w = 3;
dest.h = canvas->h;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
dest.x = 0;
dest.y = (canvas->h / 2) - 1;
dest.w = canvas->w;
dest.h = 3;
dest.x = 0;
dest.y = (canvas->h / 2) - 1;
dest.w = canvas->w;
dest.h = 3;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
dest.x = canvas->w / 2;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
dest.x = canvas->w / 2;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
dest.x = 0;
dest.y = canvas->h / 2;
dest.w = canvas->w;
dest.h = 1;
dest.x = 0;
dest.y = canvas->h / 2;
dest.w = canvas->w;
dest.h = 1;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
}
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
}
/* Update everything! */
@ -293,7 +309,8 @@ static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
// Affect the canvas on click:
void shift_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
shift_x = x;
shift_y = y;
@ -303,7 +320,8 @@ void shift_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release:
void shift_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 0);
api->stopsound();
@ -319,22 +337,26 @@ void shift_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Record the color from Tux Paint:
void shift_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int shift_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int shift_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void shift_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void shift_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void shift_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void shift_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -46,18 +46,22 @@ SDL_Surface *smudge_get_icon(magic_api * api, int which);
char *smudge_get_name(magic_api * api, int which);
int smudge_get_group(magic_api * api, int which);
char *smudge_get_description(magic_api * api, int which, int mode);
static void do_smudge(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_smudge(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void smudge_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void smudge_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void smudge_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void smudge_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void smudge_shutdown(magic_api * api);
void smudge_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int smudge_requires_colors(magic_api * api, int which);
void smudge_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void smudge_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void smudge_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void smudge_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int smudge_modes(magic_api * api, int which);
int smudge_get_tool_count(magic_api * api);
@ -66,7 +70,8 @@ int smudge_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/smudge.wav", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/smudge.wav",
api->data_directory);
smudge_snd = Mix_LoadWAV(fname);
return (1);
@ -89,9 +94,11 @@ SDL_Surface *smudge_get_icon(magic_api * api, int which)
char fname[1024];
if (which == 0)
snprintf(fname, sizeof(fname), "%simages/magic/smudge.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/smudge.png",
api->data_directory);
else /* if (which == 1) */
snprintf(fname, sizeof(fname), "%simages/magic/wetpaint.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/wetpaint.png",
api->data_directory);
return (IMG_Load(fname));
}
@ -115,17 +122,23 @@ int smudge_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *smudge_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *smudge_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (which == 0)
return (strdup(gettext_noop("Click and drag the mouse around to smudge the picture.")));
return (strdup
(gettext_noop
("Click and drag the mouse around to smudge the picture.")));
else /* if (which == 1) */
return (strdup(gettext_noop("Click and drag the mouse around to draw with wet, smudgy paint.")));
return (strdup
(gettext_noop
("Click and drag the mouse around to draw with wet, smudgy paint.")));
}
// Do the effect:
static void do_smudge(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_smudge(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
static double state[32][32][3];
@ -135,66 +148,80 @@ static void do_smudge(void *ptr, int which, SDL_Surface * canvas, SDL_Surface *
int xx, yy, strength;
if (which == 1)
{
/* Wet paint */
for (yy = -8; yy < 8; yy++)
for (xx = -8; xx < 8; xx++)
if (api->in_circle(xx, yy, 8))
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r, &g, &b);
//strength = (abs(xx * yy) / 8) + 6;
strength = (abs(xx * yy) / 8) + 1;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format,
(smudge_r + r * strength) / (strength + 1),
(smudge_g + g * strength) / (strength + 1),
(smudge_b + b * strength) / (strength + 1)));
}
}
{
/* Wet paint */
for (yy = -8; yy < 8; yy++)
for (xx = -8; xx < 8; xx++)
if (api->in_circle(xx, yy, 8))
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r,
&g, &b);
//strength = (abs(xx * yy) / 8) + 6;
strength = (abs(xx * yy) / 8) + 1;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format,
(smudge_r +
r * strength) /
(strength + 1),
(smudge_g +
g * strength) /
(strength + 1),
(smudge_b +
b * strength) /
(strength + 1)));
}
}
while (i--)
{
int iy = i >> 5;
int ix = i & 0x1f;
{
int iy = i >> 5;
int ix = i & 0x1f;
// is it not on the circle of radius sqrt(120) at location 16,16?
if ((ix - 16) * (ix - 16) + (iy - 16) * (iy - 16) > 120)
continue;
// it is on the circle, so grab it
// is it not on the circle of radius sqrt(120) at location 16,16?
if ((ix - 16) * (ix - 16) + (iy - 16) * (iy - 16) > 120)
continue;
// it is on the circle, so grab it
SDL_GetRGB(api->getpixel(canvas, x + ix - 16, y + iy - 16), last->format, &r, &g, &b);
state[ix][iy][0] = rate * state[ix][iy][0] + (1.0 - rate) * api->sRGB_to_linear(r);
state[ix][iy][1] = rate * state[ix][iy][1] + (1.0 - rate) * api->sRGB_to_linear(g);
state[ix][iy][2] = rate * state[ix][iy][2] + (1.0 - rate) * api->sRGB_to_linear(b);
SDL_GetRGB(api->getpixel(canvas, x + ix - 16, y + iy - 16), last->format,
&r, &g, &b);
state[ix][iy][0] =
rate * state[ix][iy][0] + (1.0 - rate) * api->sRGB_to_linear(r);
state[ix][iy][1] =
rate * state[ix][iy][1] + (1.0 - rate) * api->sRGB_to_linear(g);
state[ix][iy][2] =
rate * state[ix][iy][2] + (1.0 - rate) * api->sRGB_to_linear(b);
// opacity 100% --> new data not blended w/ existing data
api->putpixel(canvas, x + ix - 16, y + iy - 16,
SDL_MapRGB(canvas->format, api->linear_to_sRGB(state[ix][iy][0]),
api->linear_to_sRGB(state[ix][iy][1]), api->linear_to_sRGB(state[ix][iy][2])));
}
// opacity 100% --> new data not blended w/ existing data
api->putpixel(canvas, x + ix - 16, y + iy - 16,
SDL_MapRGB(canvas->format,
api->linear_to_sRGB(state[ix][iy][0]),
api->linear_to_sRGB(state[ix][iy][1]),
api->linear_to_sRGB(state[ix][iy][2])));
}
}
// Affect the canvas on drag:
void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_smudge);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_smudge);
api->playsound(smudge_snd, (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -204,15 +231,19 @@ void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void smudge_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
smudge_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on click:
void smudge_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void smudge_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -224,7 +255,8 @@ void smudge_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void smudge_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void smudge_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
smudge_r = r;
smudge_g = g;
@ -232,7 +264,8 @@ void smudge_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8
}
// Use colors:
int smudge_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int smudge_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
if (which == 0)
return 0;
@ -240,12 +273,14 @@ int smudge_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
return 1;
}
void smudge_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void smudge_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void smudge_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void smudge_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -84,19 +84,24 @@ SDL_Surface *snow_get_icon(magic_api * api, int which);
char *snow_get_name(magic_api * api, int which);
int snow_get_group(magic_api * api, int which);
char *snow_get_description(magic_api * api, int which);
static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount);
static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which, int snowAmount);
void snow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void snow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void snow_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void snow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void snow_shutdown(magic_api * api);
void snow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int snow_requires_colors(magic_api * api, int which);
void snow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void snow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void snow_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void snow_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int snow_modes(magic_api * api, int which);
Uint32 snow_api_version(void)
{
@ -112,29 +117,32 @@ int snow_init(magic_api * api)
srand(time(0));
snprintf(fname, sizeof(fname), "%simages/magic/Snow_flake4.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/Snow_flake4.png",
api->data_directory);
snow_flake1 = IMG_Load(fname);
if (snow_flake1 == NULL)
{
return (0);
}
{
return (0);
}
snprintf(fname, sizeof(fname), "%simages/magic/Snow_flake5.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/Snow_flake5.png",
api->data_directory);
snow_flake2 = IMG_Load(fname);
if (snow_flake2 == NULL)
{
return (0);
}
{
return (0);
}
if (snow_flake2 == NULL)
{
printf("meh\n");
}
{
printf("meh\n");
}
for (i = 0; i < snow_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, snow_snd_filenames[i]);
snow_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
snow_snd_filenames[i]);
snow_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -148,7 +156,8 @@ SDL_Surface *snow_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, snow_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
snow_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -158,9 +167,10 @@ char *snow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return (strdup(gettext_noop(snow_names[which])));
}
int snow_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int snow_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_DECORATIONS; /* Because we affect the whole image, and not just around the mouse */
return MAGIC_TYPE_PICTURE_DECORATIONS; /* Because we affect the whole image, and not just around the mouse */
}
// Return our descriptions, localized:
@ -170,7 +180,8 @@ char *snow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Do the effect:
static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount)
static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which, int snowAmount)
{
magic_api *api = (magic_api *) ptr;
@ -179,43 +190,48 @@ static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int whi
SDL_Rect dest;
for (i = 0; i < snowAmount; i++)
{
centre_x = rand() % canvas->w;
centre_y = rand() % canvas->h;
if (which == TOOL_SNOWBALL)
{
centre_x = rand() % canvas->w;
centre_y = rand() % canvas->h;
if (which == TOOL_SNOWBALL)
for (y = -snow_RADIUS; y < snow_RADIUS; y++)
{
for (x = -snow_RADIUS; x < snow_RADIUS; x++)
{
for (y = -snow_RADIUS; y < snow_RADIUS; y++)
{
for (x = -snow_RADIUS; x < snow_RADIUS; x++)
{
if (api->in_circle(x, y, snow_RADIUS))
{
SDL_GetRGB(api->getpixel(last, centre_x + x, centre_y + y), last->format, &r, &g, &b);
api->putpixel(canvas, centre_x + x, centre_y + y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
}
}
if (which == TOOL_SNOWFLAKE)
{
dest.x = centre_x;
dest.y = centre_y;
if (rand() % 2 == 0)
{
SDL_BlitSurface(snow_flake1, NULL, canvas, &dest);
}
else
{
SDL_BlitSurface(snow_flake2, NULL, canvas, &dest);
}
if (api->in_circle(x, y, snow_RADIUS))
{
SDL_GetRGB(api->getpixel(last, centre_x + x, centre_y + y),
last->format, &r, &g, &b);
api->putpixel(canvas, centre_x + x, centre_y + y,
SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
}
}
if (which == TOOL_SNOWFLAKE)
{
dest.x = centre_x;
dest.y = centre_y;
if (rand() % 2 == 0)
{
SDL_BlitSurface(snow_flake1, NULL, canvas, &dest);
}
else
{
SDL_BlitSurface(snow_flake2, NULL, canvas, &dest);
}
}
}
}
// Affect the canvas on drag:
void snow_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void snow_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
// No-op
}
@ -223,7 +239,8 @@ void snow_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL
// Affect the canvas on click:
void snow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect)
{
update_rect->x = 0;
update_rect->y = 0;
@ -235,9 +252,12 @@ void snow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
}
// Affect the canvas on release:
void snow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void snow_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -248,40 +268,44 @@ void snow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < snow_NUM_TOOLS; i++)
{
if (snow_snd_effect[i] != NULL)
{
if (snow_snd_effect[i] != NULL)
{
Mix_FreeChunk(snow_snd_effect[i]);
}
Mix_FreeChunk(snow_snd_effect[i]);
}
}
if (snow_flake1 != NULL)
{
SDL_FreeSurface(snow_flake1);
}
{
SDL_FreeSurface(snow_flake1);
}
if (snow_flake2 != NULL)
{
SDL_FreeSurface(snow_flake2);
}
{
SDL_FreeSurface(snow_flake2);
}
}
// Record the color from Tux Paint:
void snow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void snow_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int snow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int snow_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void snow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void snow_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void snow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void snow_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -57,15 +57,21 @@ int stretch_get_group(magic_api * api, int which);
char *stretch_get_description(magic_api * api, int which, int mode);
int stretch_requires_colors(magic_api * api, int which);
void stretch_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
void stretch_shutdown(magic_api * api);
void stretch_paint_stretch(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void stretch_paint_stretch(void *ptr_to_api, int which_tool,
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y);
void stretch_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void stretch_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void stretch_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void stretch_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void stretch_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void stretch_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void stretch_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int stretch_modes(magic_api * api, int which);
// Housekeeping functions
@ -74,7 +80,9 @@ Uint32 stretch_api_version(void)
return (TP_MAGIC_API_VERSION);
}
void stretch_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
void stretch_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
@ -82,7 +90,8 @@ int stretch_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/stretch.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/stretch.ogg",
api->data_directory);
stretch_snd = Mix_LoadWAV(fname);
return (1);
@ -97,36 +106,45 @@ SDL_Surface *stretch_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/stretch.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/stretch.png",
api->data_directory);
return (IMG_Load(fname));
}
char *stretch_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *stretch_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Stretch"));
}
int stretch_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int stretch_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
char *stretch_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *stretch_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return
strdup(gettext_noop
("Click and drag to stretch part of your picture vertically or horizontally."));
}
int stretch_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int stretch_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void stretch_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void stretch_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -137,9 +155,10 @@ void stretch_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Interactivity functions
void stretch_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
void stretch_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x,
int y, SDL_Rect * update_rect)
{
SDL_Rect src, dest;
float xx, yy;
@ -148,92 +167,94 @@ void stretch_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * can
SDL_BlitSurface(snapshot, NULL, canvas, NULL);
switch (stretch_side)
{
case STRETCH_DIRECTION_VERT:
{
case STRETCH_DIRECTION_VERT:
if (y != stretch_start_y)
{
if (y != stretch_start_y)
{
divisor1 = (float) y / (float) stretch_start_y;
divisor2 = (float) (canvas->h - y) / (float) (canvas->h - stretch_start_y);
divisor1 = (float) y / (float) stretch_start_y;
divisor2 =
(float) (canvas->h - y) / (float) (canvas->h - stretch_start_y);
for (yy = 0; yy < y; yy++)
{
src.x = 0;
src.y = (yy / divisor1);
src.w = canvas->w;
src.h = 1;
for (yy = 0; yy < y; yy++)
{
src.x = 0;
src.y = (yy / divisor1);
src.w = canvas->w;
src.h = 1;
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
for (yy = y; yy < canvas->h; yy++)
{
src.x = 0;
src.y = stretch_start_y + ((yy - y) / divisor2);
src.w = canvas->w;
src.h = 1;
for (yy = y; yy < canvas->h; yy++)
{
src.x = 0;
src.y = stretch_start_y + ((yy - y) / divisor2);
src.w = canvas->w;
src.h = 1;
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
dest.x = 0;
dest.y = yy;
dest.w = canvas->w;
dest.h = 1;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
api->playsound(stretch_snd, 128, 255);
}
break;
}
case STRETCH_DIRECTION_HORIZ:
{
if (x != stretch_start_x)
{
divisor1 = (float) x / (float) stretch_start_x;
divisor2 = (float) (canvas->w - x) / (float) (canvas->w - stretch_start_x);
for (xx = 0; xx < x; xx++)
{
src.x = (xx / divisor1);
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
for (xx = x; xx < canvas->w; xx++)
{
src.x = stretch_start_x + ((xx - x) / divisor2);
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
api->playsound(stretch_snd, (x * 255) / canvas->w, 255);
}
break;
api->playsound(stretch_snd, 128, 255);
}
break;
}
case STRETCH_DIRECTION_HORIZ:
{
if (x != stretch_start_x)
{
divisor1 = (float) x / (float) stretch_start_x;
divisor2 =
(float) (canvas->w - x) / (float) (canvas->w - stretch_start_x);
for (xx = 0; xx < x; xx++)
{
src.x = (xx / divisor1);
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
for (xx = x; xx < canvas->w; xx++)
{
src.x = stretch_start_x + ((xx - x) / divisor2);
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = xx;
dest.y = 0;
dest.w = 1;
dest.h = canvas->h;
SDL_BlitSurface(snapshot, &src, canvas, &dest);
}
api->playsound(stretch_snd, (x * 255) / canvas->w, 255);
}
break;
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
@ -241,26 +262,27 @@ void stretch_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * can
}
void stretch_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (y < canvas->h / 2)
{
if (x < y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else if (canvas->w - x < y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else
stretch_side = STRETCH_DIRECTION_VERT;
}
{
if (x < y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else if (canvas->w - x < y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else
stretch_side = STRETCH_DIRECTION_VERT;
}
else
{
if (x < canvas->h - y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else if (canvas->w - x < canvas->h - y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else
stretch_side = STRETCH_DIRECTION_VERT;
}
{
if (x < canvas->h - y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else if (canvas->w - x < canvas->h - y)
stretch_side = STRETCH_DIRECTION_HORIZ;
else
stretch_side = STRETCH_DIRECTION_VERT;
}
stretch_start_x = x;
stretch_start_y = y;
@ -268,19 +290,22 @@ void stretch_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
stretch_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
void stretch_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
void stretch_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void stretch_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
void stretch_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int stretch_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int stretch_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -10,7 +10,8 @@
unsigned int img_w, img_h;
static Uint8 string_r, string_g, string_b;
static int string_ox, string_oy;
static int string_vertex_x, string_vertex_y, string_vertex_done, string_vertex_distance;
static int string_vertex_x, string_vertex_y, string_vertex_done,
string_vertex_distance;
static SDL_Surface *canvas_backup;
enum string_tools
{
@ -24,25 +25,28 @@ Mix_Chunk *string_snd[STRING_NUMTOOLS];
// Custom function declarations
void string_callback(void *ptr, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void string_draw_triangle(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void string_draw_angle(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
void string_callback(void *ptr, int which_tool, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void string_draw_triangle(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x,
int y, SDL_Rect * update_rect);
void string_draw_angle(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void string_draw_triangle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy,
int x, int y, SDL_Rect * update_rect);
void string_draw_angle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Surface * canvas, SDL_Surface * snapshot,
int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void scale_xcoord(int *xcoord);
void scale_ycoord(int *ycoord);
void scale_coords(int *ox, int *oy, int *x, int *y);
void string_draw_wrapper(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int ox,
int oy, int x, int y, SDL_Rect * update_rect);
void string_set_vertex(int x, int y);
void compute_middle(int start_point, int end_point, int vertex, int *middle);
@ -50,7 +54,8 @@ void compute_middle(int start_point, int end_point, int vertex, int *middle);
// Prototypes for required functions
void string_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
Uint32 string_api_version(void);
@ -63,13 +68,17 @@ int string_get_group(magic_api * api, int which);
char *string_get_description(magic_api * api, int which, int mode);
int string_requires_colors(magic_api * api, int which);
void string_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect);
int string_init(magic_api * api);
void string_shutdown(magic_api * api);
void string_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void string_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void string_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
void string_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot);
void string_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot);
void string_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
// Required functions
@ -86,7 +95,8 @@ int string_modes(magic_api * api ATTRIBUTE_UNUSED, int which)
return (MODE_PAINT_WITH_PREVIEW);
}
void string_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void string_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
string_r = r;
string_g = g;
@ -105,95 +115,111 @@ SDL_Surface *string_get_icon(magic_api * api, int which)
char fname[1024];
switch (which)
{
case STRING_TOOL_FULL_BY_OFFSET:
snprintf(fname, sizeof(fname), "%simages/magic/string_art_full_by_offset.png", api->data_directory);
break;
case STRING_TOOL_TRIANGLE:
snprintf(fname, sizeof(fname), "%simages/magic/string_art_triangles.png", api->data_directory);
break;
case STRING_TOOL_ANGLE:
snprintf(fname, sizeof(fname), "%simages/magic/string_art_angles.png", api->data_directory);
break;
}
{
case STRING_TOOL_FULL_BY_OFFSET:
snprintf(fname, sizeof(fname),
"%simages/magic/string_art_full_by_offset.png",
api->data_directory);
break;
case STRING_TOOL_TRIANGLE:
snprintf(fname, sizeof(fname), "%simages/magic/string_art_triangles.png",
api->data_directory);
break;
case STRING_TOOL_ANGLE:
snprintf(fname, sizeof(fname), "%simages/magic/string_art_angles.png",
api->data_directory);
break;
}
return (IMG_Load(fname));
}
char *string_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *string_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
switch (which)
{
case STRING_TOOL_FULL_BY_OFFSET:
return strdup(gettext_noop("String edges"));
break;
case STRING_TOOL_TRIANGLE:
return strdup(gettext_noop("String corner"));
break;
default:
return strdup(gettext_noop("String 'V'"));
}
{
case STRING_TOOL_FULL_BY_OFFSET:
return strdup(gettext_noop("String edges"));
break;
case STRING_TOOL_TRIANGLE:
return strdup(gettext_noop("String corner"));
break;
default:
return strdup(gettext_noop("String 'V'"));
}
}
int string_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int string_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_ARTISTIC;
}
char *string_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *string_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
switch (which)
{
case STRING_TOOL_FULL_BY_OFFSET:
return
strdup(gettext_noop
("Click and drag to draw string art. Drag top-bottom to draw less or more lines, left or right to make a bigger hole."));
break;
case STRING_TOOL_TRIANGLE:
return strdup(gettext_noop("Click and drag to draw arrows made of string art."));
break;
default:
return strdup(gettext_noop("Draw string art arrows with free angles."));
}
{
case STRING_TOOL_FULL_BY_OFFSET:
return
strdup(gettext_noop
("Click and drag to draw string art. Drag top-bottom to draw less or more lines, left or right to make a bigger hole."));
break;
case STRING_TOOL_TRIANGLE:
return
strdup(gettext_noop
("Click and drag to draw arrows made of string art."));
break;
default:
return strdup(gettext_noop("Draw string art arrows with free angles."));
}
}
int string_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int string_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void string_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int x,
int y, SDL_Rect * update_rect)
{
int dx, dy;
if (which == STRING_TOOL_TRIANGLE)
string_draw_triangle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
string_draw_triangle((void *) api, which, canvas, snapshot, string_ox,
string_oy, x, y, update_rect);
if (which == STRING_TOOL_ANGLE)
{
if (!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
{
if (!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
{
dx = string_ox - x;
dy = string_oy - y;
y = y + dx;
x = x - dy;
}
string_draw_angle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
dx = string_ox - x;
dy = string_oy - y;
y = y + dx;
x = x - dy;
}
string_draw_angle((void *) api, which, canvas, snapshot, string_ox,
string_oy, x, y, update_rect);
}
}
int string_init(magic_api * api ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/string.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/string.ogg",
api->data_directory);
string_snd[STRING_TOOL_FULL_BY_OFFSET] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/string2.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/string2.ogg",
api->data_directory);
string_snd[STRING_TOOL_TRIANGLE] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/string3.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/string3.ogg",
api->data_directory);
string_snd[STRING_TOOL_ANGLE] = Mix_LoadWAV(fname);
return (1);
@ -207,21 +233,29 @@ void string_shutdown(magic_api * api ATTRIBUTE_UNUSED)
SDL_FreeSurface(canvas_backup);
while (i < STRING_NUMTOOLS)
{
if (string_snd[i] != NULL)
Mix_FreeChunk(string_snd[i]);
i++;
}
{
if (string_snd[i] != NULL)
Mix_FreeChunk(string_snd[i]);
i++;
}
}
void string_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
void string_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{
canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h,
canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
}
void string_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
void string_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{
SDL_FreeSurface(canvas_backup);
canvas_backup = NULL;
@ -230,15 +264,21 @@ void string_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUS
// Interactivity functions
void string_callback(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
void string_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format, string_r, string_g, string_b, 255));
api->putpixel(canvas, x, y,
SDL_MapRGBA(canvas->format, string_r, string_g, string_b,
255));
}
void string_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
void string_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect)
{
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
@ -249,8 +289,11 @@ void string_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, SDL_Sur
string_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
}
static void string_draw_full_by_offset(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
static void string_draw_full_by_offset(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface *
snapshot ATTRIBUTE_UNUSED, int x,
int y, SDL_Rect * update_rect)
{
magic_api *api = (magic_api *) ptr;
int u;
@ -260,56 +303,57 @@ static void string_draw_full_by_offset(void *ptr, int which ATTRIBUTE_UNUSED, SD
// int n=y/5;
int **a;
float step_w, step_h, aux;
int side = (int)(y / 3);
int side = (int) (y / 3);
SDL_BlitSurface(snapshot, 0, canvas, 0);
if (side < 3)
side = 3;
o = (int)(side * 4 * x / canvas->w);
step_w = canvas->w / (float)side;
step_h = canvas->h / (float)side;
o = (int) (side * 4 * x / canvas->w);
step_w = canvas->w / (float) side;
step_h = canvas->h / (float) side;
a = malloc(sizeof(int *) * side * 4 * 2);
for (i = 0; i < side * 4; i++)
{
a[i] = malloc(sizeof(int *) * 2);
if (i < side)
{
a[i] = malloc(sizeof(int *) * 2);
if (i < side)
{
a[i][0] = 0;
aux = step_h * (float)i;
a[i][1] = (int)aux;
}
else if (i < (side * 2))
{
a[i][0] = (int)((float)(i % side) * step_w);
a[i][1] = canvas->h;
}
else if (i < (int)(side * 3))
{
a[i][0] = canvas->w;
a[i][1] = (int)(canvas->h - (float)((i % side) * step_h));
}
else if (i < (int)(side * 4))
{
a[i][0] = (int)(canvas->w - ((float)((i % side) * step_w)));
a[i][1] = 0;
}
a[i][0] = 0;
aux = step_h * (float) i;
a[i][1] = (int) aux;
}
else if (i < (side * 2))
{
a[i][0] = (int) ((float) (i % side) * step_w);
a[i][1] = canvas->h;
}
else if (i < (int) (side * 3))
{
a[i][0] = canvas->w;
a[i][1] = (int) (canvas->h - (float) ((i % side) * step_h));
}
else if (i < (int) (side * 4))
{
a[i][0] = (int) (canvas->w - ((float) ((i % side) * step_w)));
a[i][1] = 0;
}
}
for (i = 0; i < side * 4; i++)
{
u = (i + o) % (side * 4);
api->line((void *)api, which, canvas, snapshot, a[i][0], a[i][1], a[u][0], a[u][1], 1, string_callback);
}
{
u = (i + o) % (side * 4);
api->line((void *) api, which, canvas, snapshot, a[i][0], a[i][1],
a[u][0], a[u][1], 1, string_callback);
}
for (i = 0; i < side * 4; i++)
{
free(a[i]);
}
{
free(a[i]);
}
free(a);
update_rect->x = 0;
@ -344,13 +388,18 @@ void scale_coords(int *ox, int *oy, int *x, int *y)
void compute_middle(int start_point, int end_point, int vertex, int *middle)
{
*middle = min(start_point, end_point) + (max(start_point, end_point) - min(start_point, end_point)) / 2;
*middle = min(*middle, vertex) + (max(*middle, vertex) - min(*middle, vertex)) / 2;
*middle =
min(start_point,
end_point) + (max(start_point, end_point) - min(start_point,
end_point)) / 2;
*middle =
min(*middle, vertex) + (max(*middle, vertex) - min(*middle, vertex)) / 2;
}
void string_draw_triangle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy,
int x, int y, SDL_Rect * update_rect)
{
int middle_x, middle_y;
@ -365,14 +414,21 @@ void string_draw_triangle_preview(magic_api * api, int which,
compute_middle(x, string_ox, string_ox, &middle_x);
compute_middle(y, string_oy, string_oy, &middle_y);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, string_ox, y, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, x, string_oy, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, middle_x, middle_y, x, string_oy, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, string_ox, y, middle_x, middle_y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox, string_oy,
string_ox, y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox, string_oy, x,
string_oy, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, middle_x, middle_y, x,
string_oy, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox, y, middle_x,
middle_y, 1, string_callback);
}
void string_draw_angle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot,
int ox ATTRIBUTE_UNUSED,
int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect)
{
int middle_x, middle_y;
int dx, dy;
@ -383,31 +439,38 @@ void string_draw_angle_preview(magic_api * api, int which,
update_rect->h = canvas->h;
SDL_BlitSurface(canvas_backup, update_rect, canvas, update_rect);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, string_vertex_x, string_vertex_y, 1,
string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox, string_oy,
string_vertex_x, string_vertex_y, 1, string_callback);
if (!string_vertex_done)
{
// if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
//{
dx = string_ox - x;
dy = string_oy - y;
y = y + dx;
x = x - dy;
}
{
// if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
//{
dx = string_ox - x;
dy = string_oy - y;
y = y + dx;
x = x - dy;
}
compute_middle(string_ox, x, string_vertex_x, &middle_x);
compute_middle(string_oy, y, string_vertex_y, &middle_y);
api->line((void *)api, which, canvas, snapshot, string_vertex_x, string_vertex_y, x, y, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, middle_x, middle_y, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, x, y, middle_x, middle_y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_vertex_x,
string_vertex_y, x, y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox, string_oy,
middle_x, middle_y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, x, y, middle_x, middle_y,
1, string_callback);
}
void string_draw_angle(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
{
float first_arm_step_x, first_arm_step_y, second_arm_step_x, second_arm_step_y;
float first_arm_step_x, first_arm_step_y, second_arm_step_x,
second_arm_step_y;
int i;
int max_wh, steps;
int max_separation = 10;
@ -419,24 +482,30 @@ void string_draw_angle(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_BlitSurface(canvas_backup, update_rect, canvas, update_rect);
max_wh =
max(max(max(string_ox, string_vertex_x), x) - min(min(string_vertex_x, x), string_ox),
max(max(string_oy, string_vertex_y), y) - min(min(string_vertex_y, y), string_oy));
max(max(max(string_ox, string_vertex_x), x) -
min(min(string_vertex_x, x), string_ox),
max(max(string_oy, string_vertex_y), y) - min(min(string_vertex_y, y),
string_oy));
steps = max_wh / max_separation;
first_arm_step_x = (float)(string_ox - string_vertex_x) / (float)steps;
first_arm_step_y = (float)(string_oy - string_vertex_y) / (float)steps;
second_arm_step_x = (float)(string_vertex_x - x) / (float)steps;
second_arm_step_y = (float)(string_vertex_y - y) / (float)steps;
first_arm_step_x = (float) (string_ox - string_vertex_x) / (float) steps;
first_arm_step_y = (float) (string_oy - string_vertex_y) / (float) steps;
second_arm_step_x = (float) (string_vertex_x - x) / (float) steps;
second_arm_step_y = (float) (string_vertex_y - y) / (float) steps;
for (i = 0; i <= steps; i++)
{
api->line((void *)api, 0, canvas, snapshot, string_ox - first_arm_step_x * i, string_oy - first_arm_step_y * i,
string_vertex_x - second_arm_step_x * i, string_vertex_y - second_arm_step_y * i, 1, string_callback);
}
{
api->line((void *) api, 0, canvas, snapshot,
string_ox - first_arm_step_x * i,
string_oy - first_arm_step_y * i,
string_vertex_x - second_arm_step_x * i,
string_vertex_y - second_arm_step_y * i, 1, string_callback);
}
}
void string_draw_triangle(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Surface * canvas, SDL_Surface * snapshot,
int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
SDL_BlitSurface(canvas_backup, 0, canvas, 0);
@ -448,19 +517,23 @@ void string_draw_triangle(magic_api * api, int which ATTRIBUTE_UNUSED,
string_oy = y;
y = string_vertex_y;
string_draw_angle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
string_draw_angle((void *) api, which, canvas, snapshot, string_ox,
string_oy, x, y, update_rect);
}
void string_draw_wrapper(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int ox,
int oy, int x, int y, SDL_Rect * update_rect)
{
if (which == STRING_TOOL_FULL_BY_OFFSET)
string_draw_full_by_offset((void *)api, which, canvas, snapshot, x, y, update_rect);
string_draw_full_by_offset((void *) api, which, canvas, snapshot, x, y,
update_rect);
else if (which == STRING_TOOL_TRIANGLE)
string_draw_triangle_preview((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
string_draw_triangle_preview((void *) api, which, canvas, snapshot, ox,
oy, x, y, update_rect);
else if (which == STRING_TOOL_ANGLE)
string_draw_angle_preview((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
string_draw_angle_preview((void *) api, which, canvas, snapshot, ox, oy,
x, y, update_rect);
}
void string_set_vertex(int x, int y)
@ -472,24 +545,27 @@ void string_set_vertex(int x, int y)
dx = max(string_ox, x) - min(string_ox, x);
dy = max(string_oy, y) - min(string_oy, y);
if (dx + dy > string_vertex_distance)
{
string_vertex_distance = dx + dy;
string_vertex_x = x;
string_vertex_y = y;
}
{
string_vertex_distance = dx + dy;
string_vertex_x = x;
string_vertex_y = y;
}
if (dx + dy + 30 < string_vertex_distance)
string_vertex_done = 1;
}
void string_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy,
int x, int y, SDL_Rect * update_rect)
{
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
&& ((signed)ox > 0) && ((signed)oy > 0))
{
string_set_vertex(x, y);
string_draw_wrapper((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
api->playsound(string_snd[which], (x * 255) / canvas->w, 255);
if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w)
&& (oy < canvas->h) && ((signed) x > 0) && ((signed) y > 0)
&& ((signed) ox > 0) && ((signed) oy > 0))
{
string_set_vertex(x, y);
string_draw_wrapper((void *) api, which, canvas, snapshot, ox, oy, x, y,
update_rect);
api->playsound(string_snd[which], (x * 255) / canvas->w, 255);
}
}
}

View file

@ -76,10 +76,13 @@ const char *tint_names[tint_NUM_TOOLS] = {
};
const char *tint_descs[tint_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse around to change the color of parts of your picture."),
{gettext_noop
("Click and drag the mouse around to change the color of parts of your picture."),
gettext_noop("Click to change the color of your entire picture."),},
{gettext_noop("Click and drag the mouse around to turn parts of your picture into white and a color you choose."),
gettext_noop("Click to turn your entire picture into white and a color you choose.")}
{gettext_noop
("Click and drag the mouse around to turn parts of your picture into white and a color you choose."),
gettext_noop
("Click to turn your entire picture into white and a color you choose.")}
};
int tint_init(magic_api * api);
@ -90,20 +93,26 @@ char *tint_get_name(magic_api * api, int which);
int tint_get_group(magic_api * api, int which);
char *tint_get_description(magic_api * api, int which, int mode);
static int tint_grey(Uint8 r1, Uint8 g1, Uint8 b1);
static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which);
static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void tint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tint_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void tint_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tint_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tint_shutdown(magic_api * api);
void tint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int tint_requires_colors(magic_api * api, int which);
void tint_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tint_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tint_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void tint_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int tint_modes(magic_api * api, int which);
Uint32 tint_api_version(void)
@ -118,10 +127,11 @@ int tint_init(magic_api * api)
char fname[1024];
for (i = 0; i < tint_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, tint_snd_filenames[i]);
tint_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
tint_snd_filenames[i]);
tint_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
@ -135,7 +145,8 @@ SDL_Surface *tint_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, tint_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
tint_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -146,13 +157,15 @@ char *tint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our group (both the same):
int tint_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tint_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_COLOR_FILTERS;
}
// Return our descriptions, localized:
char *tint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
char *tint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode)
{
return (strdup(gettext_noop(tint_descs[which][mode - 1])));
}
@ -163,7 +176,8 @@ static int tint_grey(Uint8 r1, Uint8 g1, Uint8 b1)
return 0.3 * r1 + .59 * g1 + 0.11 * b1;
}
static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -176,81 +190,88 @@ static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surfac
int greyValue = tint_grey(r, g, b);
if (which == TOOL_TINT)
{
api->rgbtohsv(tint_r, tint_g, tint_b, &h, &s, &v);
api->hsvtorgb(h, s, greyValue / 255.0, &r, &g, &b);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
}
{
api->rgbtohsv(tint_r, tint_g, tint_b, &h, &s, &v);
api->hsvtorgb(h, s, greyValue / 255.0, &r, &g, &b);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
}
else if (which == TOOL_THRESHOLD)
{
int thresholdValue = (tint_max - tint_min) / 2;
{
int thresholdValue = (tint_max - tint_min) / 2;
if (greyValue < thresholdValue)
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, tint_r, tint_g, tint_b));
}
else
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
if (greyValue < thresholdValue)
{
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, tint_r, tint_g, tint_b));
}
else
{
api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
}
}
// Do the effect:
static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last,
int which)
{
int x, y;
for (y = 0; y < last->h; y++)
{
for (x = 0; x < last->w; x++)
{
for (x = 0; x < last->w; x++)
{
do_tint_pixel(ptr, which, canvas, last, x, y);
}
do_tint_pixel(ptr, which, canvas, last, x, y);
}
}
}
static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y)
{
int xx, yy;
magic_api *api = (magic_api *) ptr;
for (yy = y - tint_RADIUS; yy < y + tint_RADIUS; yy++)
{
for (xx = x - tint_RADIUS; xx < x + tint_RADIUS; xx++)
{
for (xx = x - tint_RADIUS; xx < x + tint_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, tint_RADIUS) && !api->touched(xx, yy))
{
do_tint_pixel(api, which, canvas, last, xx, yy);
}
}
if (api->in_circle(xx - x, yy - y, tint_RADIUS)
&& !api->touched(xx, yy))
{
do_tint_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag:
void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_tint_brush);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_tint_brush);
api->playsound(tint_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - tint_RADIUS;
update_rect->y = oy - tint_RADIUS;
@ -260,25 +281,29 @@ void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void tint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
tint_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_tint_full(api, canvas, last, which);
api->playsound(tint_snd_effect[which], 128, 255);
}
{
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
do_tint_full(api, canvas, last, which);
api->playsound(tint_snd_effect[which], 128, 255);
}
}
// Affect the canvas on release:
void tint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void tint_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -289,16 +314,17 @@ void tint_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < tint_NUM_TOOLS; i++)
{
if (tint_snd_effect[i] != NULL)
{
if (tint_snd_effect[i] != NULL)
{
Mix_FreeChunk(tint_snd_effect[i]);
}
Mix_FreeChunk(tint_snd_effect[i]);
}
}
}
// Record the color from Tux Paint:
void tint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void tint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
tint_r = r;
tint_g = g;
@ -306,39 +332,42 @@ void tint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
}
// Use colors:
int tint_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tint_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void tint_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
void tint_switchin(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
int x, y;
Uint8 r1, g1, b1;
for (y = 0; y < canvas->h; y++)
{
for (x = 0; x < canvas->w; x++)
{
for (x = 0; x < canvas->w; x++)
{
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r1, &g1, &b1);
{
int greyValue = tint_grey(r1, g1, b1);
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r1, &g1, &b1);
{
int greyValue = tint_grey(r1, g1, b1);
if (greyValue < tint_min)
{
tint_min = greyValue;
}
if (greyValue > tint_max)
{
tint_max = greyValue;
}
}
if (greyValue < tint_min)
{
tint_min = greyValue;
}
if (greyValue > tint_max)
{
tint_max = greyValue;
}
}
}
}
}
void tint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void tint_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -84,18 +84,24 @@ SDL_Surface *toothpaste_get_icon(magic_api * api, int which);
char *toothpaste_get_name(magic_api * api, int which);
int toothpaste_get_group(magic_api * api, int which);
char *toothpaste_get_description(magic_api * api, int which, int mode);
static void do_toothpaste(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_toothpaste(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y);
void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void toothpaste_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void toothpaste_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void toothpaste_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void toothpaste_shutdown(magic_api * api);
void toothpaste_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int toothpaste_requires_colors(magic_api * api, int which);
void toothpaste_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void toothpaste_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void toothpaste_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void toothpaste_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int toothpaste_modes(magic_api * api, int which);
Uint32 toothpaste_api_version(void)
@ -113,30 +119,36 @@ int toothpaste_init(magic_api * api)
//Load sounds
for (i = 0; i < toothpaste_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, toothpaste_snd_filenames[i]);
toothpaste_snd_effect[i] = Mix_LoadWAV(fname);
}
{
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory,
toothpaste_snd_filenames[i]);
toothpaste_snd_effect[i] = Mix_LoadWAV(fname);
}
//Set up weights
pi = acos(0.0) * 2;
toothpaste_weights = (double *)malloc(toothpaste_RADIUS * 2 * toothpaste_RADIUS * 2 * sizeof(double));
toothpaste_weights =
(double *) malloc(toothpaste_RADIUS * 2 * toothpaste_RADIUS * 2 *
sizeof(double));
if (toothpaste_weights == NULL)
{
return (0);
}
{
return (0);
}
for (k = -toothpaste_RADIUS; k < +toothpaste_RADIUS; k++)
{
for (j = -toothpaste_RADIUS; j < +toothpaste_RADIUS; j++)
{
for (j = -toothpaste_RADIUS; j < +toothpaste_RADIUS; j++)
{
if (api->in_circle(j, k, toothpaste_RADIUS))
{
toothpaste_weights[(k + toothpaste_RADIUS) * ((toothpaste_RADIUS * 2) - 1) + (j + toothpaste_RADIUS)] =
((fabs(atan2((double)(j), (double)(k)))) / pi);
}
}
if (api->in_circle(j, k, toothpaste_RADIUS))
{
toothpaste_weights[(k +
toothpaste_RADIUS) * ((toothpaste_RADIUS * 2) -
1) + (j +
toothpaste_RADIUS)] =
((fabs(atan2((double) (j), (double) (k)))) / pi);
}
}
}
return (1);
}
@ -151,7 +163,8 @@ SDL_Surface *toothpaste_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, toothpaste_icon_filenames[which]);
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory,
toothpaste_icon_filenames[which]);
return (IMG_Load(fname));
}
@ -168,13 +181,15 @@ int toothpaste_get_group(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *toothpaste_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *toothpaste_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop(toothpaste_descs[which])));
}
// Do the effect:
static void do_toothpaste(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
static void do_toothpaste(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
@ -186,30 +201,37 @@ static void do_toothpaste(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
Uint8 r, g, b;
for (yy = y - toothpaste_RADIUS; yy < y + toothpaste_RADIUS; yy++)
{
for (xx = x - toothpaste_RADIUS; xx < x + toothpaste_RADIUS; xx++)
{
for (xx = x - toothpaste_RADIUS; xx < x + toothpaste_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, toothpaste_RADIUS) && !api->touched(xx, yy))
{
if (api->in_circle(xx - x, yy - y, toothpaste_RADIUS)
&& !api->touched(xx, yy))
{
api->rgbtohsv(toothpaste_r, toothpaste_g, toothpaste_b, &h, &s, &v);
api->hsvtorgb(h, s,
toothpaste_weights[(yy - y + toothpaste_RADIUS) * ((toothpaste_RADIUS * 2) - 1) +
(xx - x + toothpaste_RADIUS)], &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
api->rgbtohsv(toothpaste_r, toothpaste_g, toothpaste_b, &h, &s, &v);
api->hsvtorgb(h, s,
toothpaste_weights[(yy - y +
toothpaste_RADIUS) *
((toothpaste_RADIUS * 2) - 1) + (xx -
x +
toothpaste_RADIUS)],
&r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
}
}
// Affect the canvas on drag:
void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_toothpaste);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_toothpaste);
api->playsound(toothpaste_snd_effect[which], (x * 255) / canvas->w, 255);
@ -222,16 +244,20 @@ void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click:
void toothpaste_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
toothpaste_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void toothpaste_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void toothpaste_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -242,21 +268,22 @@ void toothpaste_shutdown(magic_api * api ATTRIBUTE_UNUSED)
int i;
for (i = 0; i < toothpaste_NUM_TOOLS; i++)
{
if (toothpaste_snd_effect[i] != NULL)
{
if (toothpaste_snd_effect[i] != NULL)
{
Mix_FreeChunk(toothpaste_snd_effect[i]);
}
Mix_FreeChunk(toothpaste_snd_effect[i]);
}
}
if (toothpaste_weights != NULL)
{
free(toothpaste_weights);
toothpaste_weights = NULL;
}
{
free(toothpaste_weights);
toothpaste_weights = NULL;
}
}
// Record the color from Tux Paint:
void toothpaste_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
void toothpaste_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g,
Uint8 b)
{
toothpaste_r = r;
toothpaste_g = g;
@ -264,23 +291,29 @@ void toothpaste_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Ui
}
// Use colors:
int toothpaste_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int toothpaste_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
void toothpaste_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void toothpaste_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void toothpaste_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void toothpaste_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
int toothpaste_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int toothpaste_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT);
}

View file

@ -64,13 +64,18 @@ typedef struct
float x, y;
} Point2D;
static void tornado_predrag(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y);
static void tornado_predrag(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y);
static void tornado_drawbase(magic_api * api, SDL_Surface * canvas);
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last,
int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final);
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y);
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int top_x, int top_y,
int minx, int maxx, int bottom_x, int bottom_y,
int final);
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x,
int y);
static Point2D tornado_PointOnCubicBezier(Point2D * cp, float t);
static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve);
static void tornado_colorize_cloud(magic_api * api);
static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas);
Uint32 tornado_api_version(void);
@ -88,17 +93,21 @@ char *tornado_get_description(magic_api * api, int which, int mode);
void tornado_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void tornado_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tornado_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void tornado_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tornado_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void tornado_shutdown(magic_api * api);
void tornado_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int tornado_requires_colors(magic_api * api, int which);
void tornado_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tornado_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tornado_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void tornado_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int tornado_modes(magic_api * api, int which);
@ -120,13 +129,16 @@ int tornado_init(magic_api * api)
tornado_click_snd = Mix_LoadWAV(fname);
*/
snprintf(fname, sizeof(fname), "%ssounds/magic/tornado_release.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/tornado_release.ogg",
api->data_directory);
tornado_release_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%simages/magic/tornado_base.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/tornado_base.png",
api->data_directory);
tornado_base = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%simages/magic/tornado_cloud.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/tornado_cloud.png",
api->data_directory);
tornado_cloud = IMG_Load(fname);
return (1);
@ -143,32 +155,41 @@ SDL_Surface *tornado_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/tornado.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/tornado.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our names, localized:
char *tornado_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *tornado_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Tornado")));
}
// Return our groups:
int tornado_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tornado_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_ARTISTIC;
}
// Return our descriptions, localized:
char *tornado_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
char *tornado_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Click and drag to draw a tornado funnel on your picture.")));
return (strdup
(gettext_noop
("Click and drag to draw a tornado funnel on your picture.")));
}
// Affect the canvas on drag:
static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y)
static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox,
int oy, int x, int y)
{
if (x < tornado_min_x)
tornado_min_x = x;
@ -187,22 +208,23 @@ static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canv
// Determine which way to bend first:
//
if (tornado_side_decided == 0)
{
if (x < tornado_bottom_x - 10)
{
if (x < tornado_bottom_x - 10)
{
tornado_side_first = SIDE_LEFT;
tornado_side_decided = 1;
}
else if (x > tornado_bottom_x + 10)
{
tornado_side_first = SIDE_RIGHT;
tornado_side_decided = 1;
}
tornado_side_first = SIDE_LEFT;
tornado_side_decided = 1;
}
else if (x > tornado_bottom_x + 10)
{
tornado_side_first = SIDE_RIGHT;
tornado_side_decided = 1;
}
}
}
void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int ox, int oy,
int x, int y, SDL_Rect * update_rect)
{
tornado_predrag(api, canvas, last, ox, oy, x, y);
@ -215,7 +237,8 @@ void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * can
/* Draw the base and the stalk (low-quality) for now: */
tornado_drawstalk(api, canvas, last,
x, y, tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y, !(api->button_down()));
x, y, tornado_min_x, tornado_max_x, tornado_bottom_x,
tornado_bottom_y, !(api->button_down()));
tornado_drawbase(api, canvas);
@ -227,7 +250,8 @@ void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * can
// Affect the canvas on click:
void tornado_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
tornado_min_x = x;
tornado_max_x = x;
@ -246,7 +270,8 @@ void tornado_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release:
void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
/* Don't let tornado be too low compared to base: */
@ -266,7 +291,8 @@ void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
/* Draw high-quality stalk, and tornado: */
tornado_drawstalk(api, canvas, last, x, y, tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y, 1);
tornado_drawstalk(api, canvas, last, x, y, tornado_min_x, tornado_max_x,
tornado_bottom_x, tornado_bottom_y, 1);
tornado_drawtornado(api, canvas, x, y);
@ -282,7 +308,8 @@ void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
}
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y)
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x,
int y)
{
SDL_Surface *aux_surf;
SDL_Rect dest;
@ -295,7 +322,8 @@ static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, in
SDL_FreeSurface(aux_surf);
}
static void tornado_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas)
static void tornado_drawbase(magic_api * api ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{
SDL_Rect dest;
@ -308,16 +336,19 @@ static void tornado_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas)
{
Uint8 r, g, b, a;
float f = (float)rand() * 255 / RAND_MAX;
float f = (float) rand() * 255 / RAND_MAX;
SDL_GetRGBA(pixel, canvas->format, &r, &g, &b, &a);
return (SDL_MapRGBA(canvas->format,
(tornado_r + r + (Uint8) f * 2) / 4,
(tornado_g + g + (Uint8) f * 2) / 4, (tornado_b + b + (Uint8) f * 2) / 4, a));
(tornado_g + g + (Uint8) f * 2) / 4,
(tornado_b + b + (Uint8) f * 2) / 4, a));
}
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last,
int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final)
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int top_x, int top_y,
int minx, int maxx, int bottom_x, int bottom_y,
int final)
{
Point2D control_points[4];
Point2D *curve;
@ -335,15 +366,15 @@ static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface
control_points[0].y = top_y;
if (tornado_side_first == SIDE_LEFT)
{
control_points[1].x = minx;
control_points[2].x = maxx;
}
{
control_points[1].x = minx;
control_points[2].x = maxx;
}
else
{
control_points[1].x = maxx;
control_points[2].x = minx;
}
{
control_points[1].x = maxx;
control_points[2].x = minx;
}
control_points[1].y = ((bottom_y - top_y) / 3) + top_y;
control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y;
@ -367,58 +398,68 @@ static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface
/* Draw the curve: */
for (i = 0; i < n_points - 1; i++)
{
if (final == 0)
{
if (final == 0)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
}
else
{
ii = n_points - i;
/* min 10 pixels then ii^2 / 2000 or 4 * ii^2 / canvas->w,
don't let the top of funnel be wider than the half of canvas */
if (n_points * n_points / 2000 > canvas->w / 4)
ww = 4 * n_points * n_points / canvas->w;
else
ww = 2000;
left = min(curve[i].x, curve[i + 1].x) - 5 - ii * ii / ww;
right = max(curve[i].x, curve[i + 1].x) + 5 + ii * ii / ww;
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
rotation += 3;
/* The body of the tornado: 3x 1y rotation + some random particles */
for (p = dest.x; p < dest.x + dest.w; p++)
{
if ((float)rand() * 100 / RAND_MAX > 10)
{
api->putpixel(canvas, p, dest.y, api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y));
}
else
{
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y),
canvas));
}
}
/* Some random particles flying around the tornado */
for (p = dest.x - dest.w * 20 / 100; p < dest.x + dest.w + dest.w * 20 / 100; p++)
{
if ((float)rand() * 100 / RAND_MAX < 5 && ((p < dest.x) || (p > dest.w)))
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y), canvas));
}
dest.x = curve[i].x;
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
}
else
{
ii = n_points - i;
/* min 10 pixels then ii^2 / 2000 or 4 * ii^2 / canvas->w,
don't let the top of funnel be wider than the half of canvas */
if (n_points * n_points / 2000 > canvas->w / 4)
ww = 4 * n_points * n_points / canvas->w;
else
ww = 2000;
left = min(curve[i].x, curve[i + 1].x) - 5 - ii * ii / ww;
right = max(curve[i].x, curve[i + 1].x) + 5 + ii * ii / ww;
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
rotation += 3;
/* The body of the tornado: 3x 1y rotation + some random particles */
for (p = dest.x; p < dest.x + dest.w; p++)
{
if ((float) rand() * 100 / RAND_MAX > 10)
{
api->putpixel(canvas, p, dest.y,
api->getpixel(last,
dest.x + (p - dest.x + rotation) % dest.w,
dest.y));
}
else
{
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last,
dest.x + (p - dest.x +
rotation) % dest.w,
dest.y), canvas));
}
}
/* Some random particles flying around the tornado */
for (p = dest.x - dest.w * 20 / 100;
p < dest.x + dest.w + dest.w * 20 / 100; p++)
{
if ((float) rand() * 100 / RAND_MAX < 5
&& ((p < dest.x) || (p > dest.w)))
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last,
dest.x + (p - dest.x +
rotation) % dest.w,
dest.y), canvas));
}
}
free(curve);
}
@ -452,7 +493,8 @@ void tornado_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
}
// Use colors:
int tornado_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tornado_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 1;
}
@ -507,7 +549,8 @@ static Point2D tornado_PointOnCubicBezier(Point2D * cp, float t)
<sizeof(Point2D) numberOfPoints>
*/
static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints,
Point2D * curve)
{
float dt;
int i;
@ -530,7 +573,9 @@ static void tornado_colorize_cloud(magic_api * api)
/* Create a surface to render into: */
amask = ~(tornado_cloud->format->Rmask | tornado_cloud->format->Gmask | tornado_cloud->format->Bmask);
amask =
~(tornado_cloud->format->Rmask | tornado_cloud->format->
Gmask | tornado_cloud->format->Bmask);
tornado_cloud_colorized =
SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -538,7 +583,8 @@ static void tornado_colorize_cloud(magic_api * api)
tornado_cloud->h,
tornado_cloud->format->BitsPerPixel,
tornado_cloud->format->Rmask,
tornado_cloud->format->Gmask, tornado_cloud->format->Bmask, amask);
tornado_cloud->format->Gmask,
tornado_cloud->format->Bmask, amask);
/* Render the new cloud: */
@ -546,33 +592,39 @@ static void tornado_colorize_cloud(magic_api * api)
SDL_LockSurface(tornado_cloud_colorized);
for (y = 0; y < tornado_cloud->h; y++)
{
for (x = 0; x < tornado_cloud->w; x++)
{
for (x = 0; x < tornado_cloud->w; x++)
{
SDL_GetRGBA(api->getpixel(tornado_cloud, x, y), tornado_cloud->format, &r, &g, &b, &a);
SDL_GetRGBA(api->getpixel(tornado_cloud, x, y), tornado_cloud->format,
&r, &g, &b, &a);
api->putpixel(tornado_cloud_colorized, x, y,
SDL_MapRGBA(tornado_cloud_colorized->format,
(tornado_r + r * 2) / 3, (tornado_g + g * 2) / 3, (tornado_b + b * 2) / 3, a));
}
api->putpixel(tornado_cloud_colorized, x, y,
SDL_MapRGBA(tornado_cloud_colorized->format,
(tornado_r + r * 2) / 3,
(tornado_g + g * 2) / 3,
(tornado_b + b * 2) / 3, a));
}
}
SDL_UnlockSurface(tornado_cloud_colorized);
SDL_UnlockSurface(tornado_cloud);
}
void tornado_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void tornado_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void tornado_switchout(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void tornado_switchout(magic_api * api, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
api->stopsound();
}
int tornado_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tornado_modes(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT_WITH_PREVIEW);
}

View file

@ -46,14 +46,18 @@ int tv_get_group(magic_api * api, int which);
char *tv_get_description(magic_api * api, int which, int mode);
int tv_requires_colors(magic_api * api, int which);
void tv_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
SDL_Rect * update_rect);
void tv_shutdown(magic_api * api);
void tv_paint_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void tv_do_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void tv_paint_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void tv_do_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas,
SDL_Surface * snapshot, int x, int y);
void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void tv_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void tv_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void tv_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tv_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int tv_modes(magic_api * api, int which);
@ -74,7 +78,8 @@ int tv_init(magic_api * api ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/tv.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/tv.ogg",
api->data_directory);
tv_snd = Mix_LoadWAV(fname);
return (1);
@ -89,12 +94,14 @@ SDL_Surface *tv_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/tv.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/tv.png",
api->data_directory);
return (IMG_Load(fname));
}
char *tv_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *tv_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("TV"));
}
@ -104,24 +111,32 @@ int tv_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
return MAGIC_TYPE_DISTORTS;
}
char *tv_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *tv_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return strdup(gettext_noop("Click and drag to make parts of your picture look like they are on television."));
return
strdup(gettext_noop
("Click and drag to make parts of your picture look like they are on television."));
else
return strdup(gettext_noop("Click to make your picture look like it's on television."));
return
strdup(gettext_noop
("Click to make your picture look like it's on television."));
}
int tv_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int tv_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void tv_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -133,64 +148,68 @@ void tv_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Interactivity functions
void tv_do_tv(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x, int y)
{
magic_api *api = (magic_api *) ptr_to_api;
Uint8 r, g, b, i;
for (i = 0; i < 2; i++)
{
/* Convert the line below to their red/green/blue elements */
SDL_GetRGB(api->getpixel(snapshot, x, y + i), snapshot->format, &r, &g,
&b);
if (x % 3 == 0)
{
/* Convert the line below to their red/green/blue elements */
SDL_GetRGB(api->getpixel(snapshot, x, y + i), snapshot->format, &r, &g, &b);
if (x % 3 == 0)
{
/* Red */
g = 0;
b = 0;
}
else if (x % 3 == 1)
{
/* Green */
r = 0;
b = 0;
}
else
{
/* Blue */
r = 0;
g = 0;
}
r = r / (i + 1);
g = g / (i + 1);
b = b / (i + 1);
api->putpixel(canvas, x, y + i, SDL_MapRGB(canvas->format, r, g, b));
/* Red */
g = 0;
b = 0;
}
else if (x % 3 == 1)
{
/* Green */
r = 0;
b = 0;
}
else
{
/* Blue */
r = 0;
g = 0;
}
r = r / (i + 1);
g = g / (i + 1);
b = b / (i + 1);
api->putpixel(canvas, x, y + i, SDL_MapRGB(canvas->format, r, g, b));
}
}
void tv_paint_tv(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{
int i, j;
magic_api *api = (magic_api *) ptr_to_api;
y = (y - (y % 2));
y = (y - (y % 2));
for (i = x - RADIUS; i < x + RADIUS; i++)
{
for (j = y - RADIUS; j < y + RADIUS; j += 2)
{
for (j = y - RADIUS; j < y + RADIUS; j += 2)
{
if (api->in_circle(i - x, j - y, RADIUS) && !api->touched(i, j))
{
tv_do_tv(api, 0, canvas, snapshot, i, j);
}
}
if (api->in_circle(i - x, j - y, RADIUS) && !api->touched(i, j))
{
tv_do_tv(api, 0, canvas, snapshot, i, j);
}
}
}
}
void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, tv_paint_tv);
@ -202,36 +221,39 @@ void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void tv_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
if (mode == MODE_FULLSCREEN)
{
for (y = 0; y < canvas->h; y += 2)
{
for (y = 0; y < canvas->h; y += 2)
{
for (x = 0; x < canvas->w; x++)
{
tv_do_tv(api, which, canvas, last, x, y);
}
}
for (x = 0; x < canvas->w; x++)
{
tv_do_tv(api, which, canvas, last, x, y);
}
}
update_rect->w = canvas->w;
update_rect->h = canvas->h;
update_rect->x = update_rect->y = 0;
api->playsound(tv_snd, 128, 255);
}
update_rect->w = canvas->w;
update_rect->h = canvas->h;
update_rect->x = update_rect->y = 0;
api->playsound(tv_snd, 128, 255);
}
else
{
tv_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
{
tv_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
}
void tv_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void tv_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void tv_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void tv_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{

View file

@ -46,16 +46,19 @@ char *waves_get_name(magic_api * api, int which);
int waves_get_group(magic_api * api, int which);
char *waves_get_description(magic_api * api, int which, int mode);
void waves_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
void waves_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void waves_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void waves_click(magic_api * api, int which, int mode, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void waves_release(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
void waves_shutdown(magic_api * api);
void waves_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int waves_requires_colors(magic_api * api, int which);
void waves_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void waves_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void waves_switchin(magic_api * api, int which, int mode,
SDL_Surface * canvas);
void waves_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int waves_modes(magic_api * api, int which);
Uint32 waves_api_version(void)
@ -69,10 +72,12 @@ int waves_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/waves.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/waves.ogg",
api->data_directory);
waves_snd[0] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%ssounds/magic/wavelet.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/wavelet.ogg",
api->data_directory);
waves_snd[1] = Mix_LoadWAV(fname);
@ -91,15 +96,18 @@ SDL_Surface *waves_get_icon(magic_api * api, int which)
char fname[1024];
if (!which)
snprintf(fname, sizeof(fname), "%simages/magic/waves.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/waves.png",
api->data_directory);
else
snprintf(fname, sizeof(fname), "%simages/magic/wavelet.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/wavelet.png",
api->data_directory);
return (IMG_Load(fname));
}
// Return our group (both the same):
int waves_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int waves_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_PICTURE_WARPS;
}
@ -114,7 +122,8 @@ char *waves_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
}
// Return our descriptions, localized:
char *waves_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
char *waves_get_description(magic_api * api ATTRIBUTE_UNUSED, int which,
int mode ATTRIBUTE_UNUSED)
{
if (!which)
return (strdup
@ -126,9 +135,10 @@ char *waves_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mod
}
void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect)
void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which,
SDL_Surface * canvas, SDL_Surface * last,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x,
int y, SDL_Rect * update_rect)
{
int xx, yy;
SDL_Rect src, dest;
@ -138,46 +148,46 @@ void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canva
SDL_BlitSurface(last, NULL, canvas, NULL);
if (which == 0)
{
//waves effect
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
for (yy = 0; yy < canvas->h; yy++)
{
//waves effect
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
xx = sin((yy * height) * M_PI / 180.0) * width;
for (yy = 0; yy < canvas->h; yy++)
{
xx = sin((yy * height) * M_PI / 180.0) * width;
src.x = 0;
src.y = yy;
src.w = canvas->w;
src.h = 1;
src.x = 0;
src.y = yy;
src.w = canvas->w;
src.h = 1;
dest.x = xx;
dest.y = yy;
dest.x = xx;
dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest);
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
else
{
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
for (xx = 0; xx < canvas->w; xx++)
{
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
yy = sin((xx * height) * M_PI / 180.0) * width;
for (xx = 0; xx < canvas->w; xx++)
{
yy = sin((xx * height) * M_PI / 180.0) * width;
src.x = xx;
src.y = 0;
src.w = 1;
src.h = canvas->h;
src.x = xx;
src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = xx;
dest.y = yy;
dest.x = xx;
dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest);
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
@ -186,16 +196,20 @@ void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canva
// Affect the canvas on click:
void waves_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect)
{
waves_drag(api, which, canvas, last, x, y, x, y, update_rect);
api->playsound(waves_snd[which], 128, 255);
}
// Affect the canvas on release:
void waves_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
void waves_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -209,23 +223,27 @@ void waves_shutdown(magic_api * api ATTRIBUTE_UNUSED)
}
// Record the color from Tux Paint:
void waves_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
void waves_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{
}
// Use colors:
int waves_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int waves_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void waves_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void waves_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void waves_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void waves_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -43,19 +43,23 @@ int xor_get_group(magic_api * api, int which);
char *xor_get_description(magic_api * api, int which, int mode);
void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void xor_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void xor_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
SDL_Surface * canvas, SDL_Surface * last, int x, int y,
SDL_Rect * update_rect);
void xor_shutdown(magic_api * api);
void xor_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int xor_requires_colors(magic_api * api, int which);
void xor_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void xor_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void xor_switchout(magic_api * api, int which, int mode,
SDL_Surface * canvas);
int xor_modes(magic_api * api, int which);
Uint32 xor_api_version(void)
@ -67,7 +71,8 @@ int xor_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%ssounds/magic/xor.ogg", api->data_directory);
snprintf(fname, sizeof(fname), "%ssounds/magic/xor.ogg",
api->data_directory);
xor_snd = Mix_LoadWAV(fname);
return (1);
@ -82,31 +87,38 @@ SDL_Surface *xor_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/xor.png", api->data_directory);
snprintf(fname, sizeof(fname), "%simages/magic/xor.png",
api->data_directory);
return (IMG_Load(fname));
}
char *xor_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *xor_get_name(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return (strdup(gettext_noop("Xor Colors")));
}
int xor_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int xor_get_group(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return MAGIC_TYPE_COLOR_FILTERS;
}
char *xor_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *xor_get_description(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode)
{
if (mode == MODE_PAINT)
return (strdup(gettext_noop("Click and drag to draw a XOR effect")));
else
return (strdup(gettext_noop("Click to draw a XOR effect on the whole picture")));
return (strdup
(gettext_noop
("Click to draw a XOR effect on the whole picture")));
}
static void do_xor(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 r, g, b, xor;
@ -116,52 +128,55 @@ static void do_xor(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r, &g, &b);
api->rgbtohsv(r, g, b, &hue, &sat, &val);
if (sat == 0)
xor = (2 * (int)hue + (x ^ y)) % 360;
xor = (2 * (int) hue + (x ^ y)) % 360;
else
xor = ((int)hue + (x ^ y)) % 360;
xor = ((int) hue + (x ^ y)) % 360;
api->hsvtorgb(xor, 1, 1, &r, &g, &b);
pixel = SDL_MapRGB(canvas->format, r, g, b);
api->putpixel(canvas, x, y, pixel);
}
static void do_xor_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(xx + x, yy + y))
do_xor(api, which, canvas, last, x + xx, y + yy);
}
}
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(xx + x, yy + y))
do_xor(api, which, canvas, last, x + xx, y + yy);
}
}
}
}
void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x,
int y, SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_xor_circle);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1,
do_xor_circle);
if (ox > x)
{
int tmp = ox;
{
int tmp = ox;
ox = x;
x = tmp;
}
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
{
int tmp = oy;
oy = y;
y = tmp;
}
oy = y;
y = tmp;
}
update_rect->x = ox - 16;
update_rect->y = oy - 16;
@ -172,29 +187,32 @@ void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
}
void xor_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect)
{
if (mode == MODE_PAINT)
xor_drag(api, which, canvas, last, x, y, x, y, update_rect);
else
{
int xx, yy;
{
int xx, yy;
for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++)
do_xor(api, which, canvas, last, xx, yy);
for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++)
do_xor(api, which, canvas, last, xx, yy);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(xor_snd, (x * 255) / canvas->w, 255);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(xor_snd, (x * 255) / canvas->w, 255);
}
}
void xor_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED,
int y ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{
}
@ -204,22 +222,25 @@ void xor_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(xor_snd);
}
void xor_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
void xor_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED,
Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
{
}
int xor_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int xor_requires_colors(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED)
{
return 0;
}
void xor_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void xor_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}
void xor_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
void xor_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
}

View file

@ -19,25 +19,26 @@
#include <android/asset_manager_jni.h>
#include "android_assets.h"
AAssetManager * asset_manager = NULL;
char* nativelibdir = NULL;
AAssetManager *asset_manager = NULL;
char *nativelibdir = NULL;
AAssetDir * open_asset_dir(char * dirname)
AAssetDir *open_asset_dir(char *dirname)
{
return AAssetManager_openDir(asset_manager, dirname);
}
char* get_nativelibdir()
char *get_nativelibdir()
{
return nativelibdir;
return nativelibdir;
}
void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_file_names)
void load_assets_dir(char *dirname, tp_ftw_str ** ffilenames,
unsigned *num_file_names)
{
AAssetDir* assetDir = AAssetManager_openDir(asset_manager, dirname);
const char* filename = (const char*)NULL;
tp_ftw_str * filenames = NULL;
AAssetDir *assetDir = AAssetManager_openDir(asset_manager, dirname);
const char *filename = (const char *) NULL;
tp_ftw_str *filenames = NULL;
unsigned max_file_names = 0;
int fulllen = 0;
*num_file_names = 0;
@ -46,7 +47,7 @@ void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_f
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL)
{
char *cp;
fulllen = strlen(filename) + 1;
if (*num_file_names == max_file_names)
@ -66,7 +67,12 @@ void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_f
*ffilenames = filenames;
}
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env, jclass clazz, jobject mgr)
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv *
env,
jclass
clazz,
jobject
mgr)
{
asset_manager = AAssetManager_fromJava(env, mgr);
@ -76,7 +82,12 @@ JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env,
return 1;
}
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env, jclass clazz, jstring path)
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv *
env,
jclass
clazz,
jstring
path)
{
const char *cpath = (*env)->GetStringUTFChars(env, path, NULL);
nativelibdir = strdup(cpath);
@ -84,21 +95,24 @@ JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env,
}
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale))
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, const char *dirname,
void (*fn)(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count,
const char *restrict const locale))
{
unsigned num_file_names = 0;
char * dir = "data/brushes";
char *dir = "data/brushes";
char buf[TP_FTW_PATHSIZE];
unsigned dirlen = strlen(dirname);
memcpy(buf, dir, dirlen);
tp_ftw_str * filenames = NULL;
tp_ftw_str *filenames = NULL;
load_assets_dir(dirname, &filenames, &num_file_names);
fn(screen, texture, renderer, dir, dirlen, filenames, num_file_names, NULL);
@ -107,12 +121,14 @@ void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Re
void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale))
void load_from_assets(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, const char *dirname,
void (*fn)(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count,
const char *restrict const locale))
{
unsigned num_file_names = 0;
// char * dir = "data/stamps/cartoon/tux";
@ -121,8 +137,9 @@ void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *
memcpy(buf, dirname, dirlen);
tp_ftw_str * filenames = NULL;
tp_ftw_str *filenames = NULL;
load_assets_dir(dirname, &filenames, &num_file_names);
fn(screen, texture, renderer, dirname, dirlen, filenames, num_file_names, NULL);
fn(screen, texture, renderer, dirname, dirlen, filenames, num_file_names,
NULL);
}

View file

@ -18,7 +18,7 @@
#define TP_ANDROID_ASSETS
#include <jni.h>
#include "debug.h"
#include "debug.h"
#include "dirwalk.h"
#include "progressbar.h"
#include <android/asset_manager.h>
@ -28,27 +28,43 @@
#define ASSETS_BRUSHES_DIR "data/brushes"
#define ASSETS_STAMPS_DIR "stamps/cartoon/tux"
AAssetDir * open_asset_dir(char * dirname);
char* get_nativelibdir();
AAssetDir *open_asset_dir(char *dirname);
char *get_nativelibdir();
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale) );
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, const char *dirname,
void (*fn)(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count,
const char *restrict const locale));
void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale) );
void load_from_assets(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, const char *dirname,
void (*fn)(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir,
unsigned dirlen, tp_ftw_str * files,
unsigned count,
const char *restrict const locale));
void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_file_names);
void load_assets_dir(char *dirname, tp_ftw_str ** ffilenames,
unsigned *num_file_names);
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env, jclass clazz, jobject mgr);
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv *
env,
jclass
clazz,
jobject
mgr);
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env, jclass clazz, jstring path);
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv *
env,
jclass
clazz,
jstring
path);
#endif

View file

@ -30,58 +30,67 @@
#include <string.h>
// This implementation may be simple, but can work fine for all of Android devices
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n){
int length = strnlen (s, n);
// w is the index of pwcs, s is the index of s
int w = 0, c = 0;
size_t mbstowcs(wchar_t *__restrict pwcs, const char *__restrict s, size_t n)
{
int length = strnlen(s, n);
// w is the index of pwcs, s is the index of s
int w = 0, c = 0;
while (1) {
pwcs[w] = '\0';
char first = s[c];
int len = 0;
if ((first & 0x80) == 0) {
pwcs[w] = (wchar_t)s[c];
len = 1;
}
else if ((first & 0xe0) == 0xc0) {
pwcs[w] |= first & 0x1f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
len = 2;
}
else if ((first & 0xf0) == 0xe0) {
pwcs[w] |= first & 0x0f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+2] & 0x3f;
len = 3;
}
else if ((first & 0xf8) == 0xf0) {
pwcs[w] |= first & 0x07;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+2] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+3] & 0x3f;
len = 4;
}
else {
return -1;
}
while (1)
{
pwcs[w] = '\0';
char first = s[c];
int len = 0;
if ((first & 0x80) == 0)
{
pwcs[w] = (wchar_t) s[c];
len = 1;
}
else if ((first & 0xe0) == 0xc0)
{
pwcs[w] |= first & 0x1f;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 1] & 0x3f;
len = 2;
}
else if ((first & 0xf0) == 0xe0)
{
pwcs[w] |= first & 0x0f;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 2] & 0x3f;
len = 3;
}
else if ((first & 0xf8) == 0xf0)
{
pwcs[w] |= first & 0x07;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 2] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c + 3] & 0x3f;
len = 4;
}
else
{
return -1;
}
c += len;
w++;
c += len;
w++;
if (c > length){
pwcs[w] = '\0';
return -1;
}
if (c == length){
pwcs[w] = '\0';
return w;
}
}
if (c > length)
{
pwcs[w] = '\0';
return -1;
}
if (c == length)
{
pwcs[w] = '\0';
return w;
}
}
}

View file

@ -31,6 +31,6 @@ Anyway, using our own implementation of "mbstowcs" can fix this problem.
#undef mbsrtowcs
// redefine mbstowcs function
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n);
size_t mbstowcs(wchar_t *__restrict pwcs, const char *__restrict s, size_t n);
#endif

View file

@ -19,7 +19,7 @@
(See COPYING.txt)
*/
// Based on JNI and PrintHelper class
// https://developer.android.com/reference/android/support/v4/print/PrintHelper.html
// https://developer.android.com/training/printing/photos.html
@ -31,58 +31,80 @@
/* FIXME: Is this check still needed after the change from android/support/v4 to AndroidX
and being Android 5 the minimum version we support? */
// Since Print work is based on Java PrintHelper class, which may not be supported on some old versions
int IsPrinterAvailable( void )
int IsPrinterAvailable(void)
{
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mPrintHelperClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mPrintHelperClass =
(*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
if (mPrintHelperClass == NULL)
return 0;
if (mPrintHelperClass == NULL)
return 0;
jmethodID mSupportMethod = (*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint", "()Z");
jboolean support = (*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);
jmethodID mSupportMethod =
(*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint",
"()Z");
jboolean support =
(*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);
return support ? 1 : 0;
return support ? 1 : 0;
}
// This function is based on
// (1) convert surface to Java BitMap object
// (2) call Java PrintHelper to do print job.
const char *SurfacePrint(SDL_Surface *surface)
const char *SurfacePrint(SDL_Surface * surface)
{
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mBitmapClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap");
jmethodID mCreateMethod = (*mEnv)->GetStaticMethodID(mEnv, mBitmapClass, "createBitmap", "([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jintArray mSurfaceArray = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h);
(*mEnv)->SetIntArrayRegion(mEnv,mSurfaceArray, 0, surface->w * surface->h, surface->pixels);
jclass mConfigClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap$Config");
jfieldID mConfigField = (*mEnv)->GetStaticFieldID(mEnv, mConfigClass , "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
jobject mConfig = (*mEnv)->GetStaticObjectField(mEnv, mConfigClass, mConfigField);
jobject mBitMap = (*mEnv)->CallStaticObjectMethod(mEnv, mBitmapClass, mCreateMethod, mSurfaceArray, surface->w, surface->h, mConfig);
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mBitmapClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap");
jmethodID mCreateMethod =
(*mEnv)->GetStaticMethodID(mEnv, mBitmapClass, "createBitmap",
"([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jintArray mSurfaceArray =
(*mEnv)->NewIntArray(mEnv, surface->w * surface->h);
(*mEnv)->SetIntArrayRegion(mEnv, mSurfaceArray, 0, surface->w * surface->h,
surface->pixels);
jclass mConfigClass =
(*mEnv)->FindClass(mEnv, "android/graphics/Bitmap$Config");
jfieldID mConfigField =
(*mEnv)->GetStaticFieldID(mEnv, mConfigClass, "ARGB_8888",
"Landroid/graphics/Bitmap$Config;");
jobject mConfig =
(*mEnv)->GetStaticObjectField(mEnv, mConfigClass, mConfigField);
jobject mBitMap =
(*mEnv)->CallStaticObjectMethod(mEnv, mBitmapClass, mCreateMethod,
mSurfaceArray, surface->w, surface->h,
mConfig);
jobject mContext = (jobject)SDL_AndroidGetActivity();
jclass mPrintClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
// sometimes android v4 support library may be not ready
if (mPrintClass == NULL)
return "There is no androidX support library.";
jmethodID mInitMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "<init>", "(Landroid/content/Context;)V");
jobject mPrint = (*mEnv)->NewObject(mEnv, mPrintClass, mInitMethod, mContext);
jmethodID mPrintMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "printBitmap", "(Ljava/lang/String;Landroid/graphics/Bitmap;)V");
jobject mContext = (jobject) SDL_AndroidGetActivity();
jclass mPrintClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
// sometimes android v4 support library may be not ready
if (mPrintClass == NULL)
return "There is no androidX support library.";
jmethodID mInitMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "<init>",
"(Landroid/content/Context;)V");
jobject mPrint =
(*mEnv)->NewObject(mEnv, mPrintClass, mInitMethod, mContext);
jmethodID mPrintMethod =
(*mEnv)->GetMethodID(mEnv, mPrintClass, "printBitmap",
"(Ljava/lang/String;Landroid/graphics/Bitmap;)V");
/* Thanks to n.collins for the explaination on the int signature
on https://stackoverflow.com/questions/13468041/android-how-to-call-java-method-from-jni-with-int-and-int-parameters --Pere */
jmethodID msetScaleMode = (*mEnv)->GetMethodID(mEnv, mPrintClass, "setScaleMode", "(I)V");
jfieldID mScaleModeField = (*mEnv)->GetStaticFieldID(mEnv, mPrintClass, "SCALE_MODE_FIT", "I");
jint mScaleModeInt = (*mEnv)->GetStaticIntField(mEnv, mPrintClass, mScaleModeField);
(*mEnv)->CallVoidMethod(mEnv, mPrint, msetScaleMode, mScaleModeInt);
/* Thanks to n.collins for the explaination on the int signature
on https://stackoverflow.com/questions/13468041/android-how-to-call-java-method-from-jni-with-int-and-int-parameters --Pere */
jmethodID msetScaleMode =
(*mEnv)->GetMethodID(mEnv, mPrintClass, "setScaleMode", "(I)V");
jfieldID mScaleModeField =
(*mEnv)->GetStaticFieldID(mEnv, mPrintClass, "SCALE_MODE_FIT", "I");
jint mScaleModeInt =
(*mEnv)->GetStaticIntField(mEnv, mPrintClass, mScaleModeField);
(*mEnv)->CallVoidMethod(mEnv, mPrint, msetScaleMode, mScaleModeInt);
jstring mString = (*mEnv)->NewStringUTF(mEnv, "TuxPaint");
(*mEnv)->CallVoidMethod(mEnv, mPrint, mPrintMethod, mString, mBitMap);
jstring mString = (*mEnv)->NewStringUTF(mEnv, "TuxPaint");
(*mEnv)->CallVoidMethod(mEnv, mPrint, mPrintMethod, mString, mBitMap);
// clean up
(*mEnv)->DeleteLocalRef(mEnv, mSurfaceArray);
(*mEnv)->DeleteLocalRef(mEnv, mConfig);
(*mEnv)->DeleteLocalRef(mEnv, mPrint);
(*mEnv)->DeleteLocalRef(mEnv, mString);
return NULL;
// clean up
(*mEnv)->DeleteLocalRef(mEnv, mSurfaceArray);
(*mEnv)->DeleteLocalRef(mEnv, mConfig);
(*mEnv)->DeleteLocalRef(mEnv, mPrint);
(*mEnv)->DeleteLocalRef(mEnv, mString);
return NULL;
}

View file

@ -1,7 +1,7 @@
/* android_print.h */
/* printing support for Tux Paint */
/* android_print.h */
/* printing support for Tux Paint */
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -17,15 +17,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
*/
*/
#ifndef __ANDROID_PRINT_H__
#define __ANDROID_PRINT_H__
#include "SDL.h"
extern const char *SurfacePrint(SDL_Surface *surface);
extern const char *SurfacePrint(SDL_Surface * surface);
extern int IsPrinterAvailable(void);
#endif /* __ANDROID_PRINT__ */
#endif /* __ANDROID_PRINT__ */

View file

@ -129,9 +129,8 @@
/* h/t https://tutel.me/c/programming/questions/45349079/how+to+use+__attribute__fallthrough+correctly+in+gcc */
#ifndef FALLTHROUGH
#if defined(__GNUC__) && __GNUC__ >= 7
#define FALL_THROUGH __attribute__ ((fallthrough))
#define FALL_THROUGH __attribute__ ((fallthrough))
#else
#define FALL_THROUGH ((void)0)
#define FALL_THROUGH ((void)0)
#endif /* __GNUC__ >= 7 */
#endif

View file

@ -97,8 +97,8 @@ void do_setcursor(SDL_Cursor * c)
void free_cursor(SDL_Cursor ** cursor)
{
if (*cursor)
{
SDL_FreeCursor(*cursor);
*cursor = NULL;
}
{
SDL_FreeCursor(*cursor);
*cursor = NULL;
}
}

View file

@ -79,8 +79,10 @@ extern char *strcasestr(const char *haystack, const char *needle);
* @param screen Screen surface, for animating progress bar.
* FIXME
*/
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files, unsigned i,
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen,
tp_ftw_str * files, unsigned i,
const char *restrict const locale)
{
dirlen = dirlen;
@ -90,188 +92,209 @@ void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer
#else
while (i--)
#endif
{
int loadable = 0;
const char *restrict const cp = strchr(files[i].str, '.');
show_progress_bar_(screen, texture, renderer);
if (cp)
{
int loadable = 0;
const char *restrict const cp = strchr(files[i].str, '.');
// need gcc 3.4 for the restrict in this location
const char * /*restrict */ const suffixes[] =
{ "ttc", "dfont", "pfa", "pfb", "otf", "ttf", };
int j = sizeof suffixes / sizeof suffixes[0];
show_progress_bar_(screen, texture, renderer);
if (cp)
while (j--)
{
// only check part, because of potential .gz or .bz2 suffix
if (!strncasecmp(cp + 1, suffixes[j], strlen(suffixes[j])))
{
// need gcc 3.4 for the restrict in this location
const char * /*restrict */ const suffixes[] =
{ "ttc", "dfont", "pfa", "pfb", "otf", "ttf", };
int j = sizeof suffixes / sizeof suffixes[0];
while (j--)
{
// only check part, because of potential .gz or .bz2 suffix
if (!strncasecmp(cp + 1, suffixes[j], strlen(suffixes[j])))
{
loadable = 1;
break;
}
}
loadable = 1;
break;
}
if (!loadable)
}
}
if (!loadable)
{
if (strcasestr(files[i].str, "/rsrc"))
loadable = 1;
}
// Loadable: TrueType (.ttf), OpenType (.otf), Type1 (.pfa and .pfb),
// and various useless bitmap fonts. Compressed files (with .gz or .bz2)
// should also work. A *.dfont is pretty much a Mac resource fork in a normal
// file, and may load with some library versions.
if (loadable)
{
char fname[512];
TuxPaint_Font *font;
snprintf(fname, sizeof fname, "%s/%s", dir, files[i].str);
#ifdef DEBUG
printf("%s:%d - Loading font: %s (locale is: %s)\n", __FILE__, __LINE__, fname, (locale ? locale : "NULL")); //EP
fflush(stdout);
#endif
if (locale && strstr(fname, "locale") && !all_locale_fonts)
{
char fname_check[512];
/* We're (probably) loading from our locale fonts folder; ONLY load our locale's font */
snprintf(fname_check, sizeof fname_check, "%s/%s.ttf", dir, locale);
#ifdef DEBUG
printf("%s:%d - checking \"%s\" vs \"%s\"\n", __FILE__, __LINE__, fname_check, fname); //EP
#endif
if (strcmp(fname, fname_check) == 0)
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
else
font = NULL;
}
else
{
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
}
if (font)
{
const char *restrict const family =
TuxPaint_Font_FontFaceFamilyName(font);
const char *restrict const style =
TuxPaint_Font_FontFaceStyleName(font);
#ifdef DEBUG
if (font->typ == FONT_TYPE_TTF)
{
if (strcasestr(files[i].str, "/rsrc"))
loadable = 1;
int numfaces = TTF_FontFaces(font->ttf_font);
if (numfaces != 1)
printf("%s:%d - Found %d faces in %s, %s, %s\n", __FILE__,
__LINE__, numfaces, files[i].str, family, style);
printf("%s:%d - success: tpf: 0x%x tpf->ttf_font: 0x%x\n", __FILE__, __LINE__, (unsigned int) (intptr_t) font, (unsigned int) (intptr_t) font->ttf_font); //EP added (intptr_t) to avoid warning on x64
}
// Loadable: TrueType (.ttf), OpenType (.otf), Type1 (.pfa and .pfb),
// and various useless bitmap fonts. Compressed files (with .gz or .bz2)
// should also work. A *.dfont is pretty much a Mac resource fork in a normal
// file, and may load with some library versions.
if (loadable)
{
char fname[512];
TuxPaint_Font *font;
snprintf(fname, sizeof fname, "%s/%s", dir, files[i].str);
#ifdef DEBUG
printf("%s:%d - Loading font: %s (locale is: %s)\n", __FILE__, __LINE__, fname, (locale ? locale : "NULL")); //EP
fflush(stdout);
#endif
if (locale && strstr(fname, "locale") && !all_locale_fonts)
{
char fname_check[512];
/* We're (probably) loading from our locale fonts folder; ONLY load our locale's font */
snprintf(fname_check, sizeof fname_check, "%s/%s.ttf", dir, locale);
#ifdef DEBUG
printf("%s:%d - checking \"%s\" vs \"%s\"\n", __FILE__, __LINE__, fname_check, fname); //EP
#endif
if (strcmp(fname, fname_check) == 0)
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
else
font = NULL;
}
else
{
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
}
if (font)
{
const char *restrict const family = TuxPaint_Font_FontFaceFamilyName(font);
const char *restrict const style = TuxPaint_Font_FontFaceStyleName(font);
#ifdef DEBUG
if (font->typ == FONT_TYPE_TTF)
{
int numfaces = TTF_FontFaces(font->ttf_font);
if (numfaces != 1)
printf("%s:%d - Found %d faces in %s, %s, %s\n", __FILE__, __LINE__, numfaces, files[i].str, family, style);
printf("%s:%d - success: tpf: 0x%x tpf->ttf_font: 0x%x\n", __FILE__, __LINE__, (unsigned int)(intptr_t) font, (unsigned int)(intptr_t) font->ttf_font); //EP added (intptr_t) to avoid warning on x64
}
#ifndef NO_SDLPANGO
else
printf("%s:%d - success: tpf: 0x%x tpf->pango_context: 0x%x\n", __FILE__, __LINE__, (unsigned int)(intptr_t) font, (unsigned int)(intptr_t) font->pango_context);
else
printf("%s:%d - success: tpf: 0x%x tpf->pango_context: 0x%x\n",
__FILE__, __LINE__, (unsigned int) (intptr_t) font,
(unsigned int) (intptr_t) font->pango_context);
#endif
#endif
// These fonts crash Tux Paint via a library bug.
int blacklisted = !strcmp("Zapfino", family) || !strcmp("Elvish Ring NFI", family);
// These fonts crash Tux Paint via a library bug.
int blacklisted = !strcmp("Zapfino", family)
|| !strcmp("Elvish Ring NFI", family);
// First, the blacklist. We list font families that can crash Tux Paint
// via bugs in the SDL_ttf library. We also test fonts to be sure that
// they have both uppercase and lowercase letters. Note that we do not
// test for "Aa", because it is OK if uppercase and lowercase are the
// same (but not nice -- such fonts get a low score later).
//
// Most locales leave the blacklist strings alone: "QX" and "qx"
// (it is less destructive to use the scoring strings instead)
//
// Locales that absolutely require all fonts to have some
// extra characters should use "QX..." and "qx...", where "..."
// are some characters you absolutely require in all fonts.
//
// Locales with absolutely NO use for ASCII may use "..." and "...",
// where "..." are some characters you absolutely require in
// all fonts. This would be the case for a locale in which it is
// impossible for a user to type ASCII letters.
//
// Most translators should use scoring instead.
if (!charset_works(font, gettext("qx")) || !charset_works(font, gettext("QX")))
blacklisted = 1;
// First, the blacklist. We list font families that can crash Tux Paint
// via bugs in the SDL_ttf library. We also test fonts to be sure that
// they have both uppercase and lowercase letters. Note that we do not
// test for "Aa", because it is OK if uppercase and lowercase are the
// same (but not nice -- such fonts get a low score later).
//
// Most locales leave the blacklist strings alone: "QX" and "qx"
// (it is less destructive to use the scoring strings instead)
//
// Locales that absolutely require all fonts to have some
// extra characters should use "QX..." and "qx...", where "..."
// are some characters you absolutely require in all fonts.
//
// Locales with absolutely NO use for ASCII may use "..." and "...",
// where "..." are some characters you absolutely require in
// all fonts. This would be the case for a locale in which it is
// impossible for a user to type ASCII letters.
//
// Most translators should use scoring instead.
if (!charset_works(font, gettext("qx"))
|| !charset_works(font, gettext("QX")))
blacklisted = 1;
if (!blacklisted)
{
if (num_font_styles == num_font_styles_max)
{
num_font_styles_max = num_font_styles_max * 5 / 4 + 30;
user_font_styles = realloc(user_font_styles, num_font_styles_max * sizeof *user_font_styles);
}
user_font_styles[num_font_styles] = malloc(sizeof *user_font_styles[num_font_styles]);
user_font_styles[num_font_styles]->directory = strdup(dir);
user_font_styles[num_font_styles]->filename = files[i].str; // steal it (mark NULL below)
user_font_styles[num_font_styles]->family = strdup(family);
user_font_styles[num_font_styles]->style = strdup(style);
user_font_styles[num_font_styles]->score = 0;
if (!blacklisted)
{
if (num_font_styles == num_font_styles_max)
{
num_font_styles_max = num_font_styles_max * 5 / 4 + 30;
user_font_styles =
realloc(user_font_styles,
num_font_styles_max * sizeof *user_font_styles);
}
user_font_styles[num_font_styles] =
malloc(sizeof *user_font_styles[num_font_styles]);
user_font_styles[num_font_styles]->directory = strdup(dir);
user_font_styles[num_font_styles]->filename = files[i].str; // steal it (mark NULL below)
user_font_styles[num_font_styles]->family = strdup(family);
user_font_styles[num_font_styles]->style = strdup(style);
user_font_styles[num_font_styles]->score = 0;
// TODO: weight specification
// TODO: weight specification
// Now we score fonts to ensure that the best ones will be placed at
// the top of the list. The user will see them first. This sorting is
// especially important for users who have scroll buttons disabled.
// Translators should do whatever is needed to put crummy fonts last.
// Now we score fonts to ensure that the best ones will be placed at
// the top of the list. The user will see them first. This sorting is
// especially important for users who have scroll buttons disabled.
// Translators should do whatever is needed to put crummy fonts last.
// distinct uppercase and lowercase (e.g., 'o' vs. 'O')
user_font_styles[num_font_styles]->score += charset_works(font, gettext("oO"));
// distinct uppercase and lowercase (e.g., 'o' vs. 'O')
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("oO"));
// common punctuation (e.g., '?', '!', '.', ',', etc.)
user_font_styles[num_font_styles]->score += charset_works(font, gettext(",.?!"));
// common punctuation (e.g., '?', '!', '.', ',', etc.)
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext(",.?!"));
// uncommon punctuation (e.g., '@', '#', '*', etc.)
user_font_styles[num_font_styles]->score += charset_works(font, gettext("`\%_@$~#{<(^&*"));
// uncommon punctuation (e.g., '@', '#', '*', etc.)
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("`\%_@$~#{<(^&*"));
// digits (e.g., '0', '1' and '7')
user_font_styles[num_font_styles]->score += charset_works(font, gettext("017"));
// digits (e.g., '0', '1' and '7')
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("017"));
// distinct circle-like characters (e.g., 'O' (capital oh) vs. '0' (zero))
user_font_styles[num_font_styles]->score += charset_works(font, gettext("O0"));
// distinct circle-like characters (e.g., 'O' (capital oh) vs. '0' (zero))
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("O0"));
// distinct line-like characters (e.g., 'l' (lowercase elle) vs. '1' (one) vs. 'I' (capital aye))
user_font_styles[num_font_styles]->score += charset_works(font, gettext("1Il|"));
// distinct line-like characters (e.g., 'l' (lowercase elle) vs. '1' (one) vs. 'I' (capital aye))
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("1Il|"));
// translation spares -- design not finalized
// translation spares -- design not finalized
#if 0
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<1>spare-1a"));
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<1>spare-1b"));
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<9>spare-9a")) * 9;
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<9>spare-9b")) * 9;
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("<1>spare-1a"));
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("<1>spare-1b"));
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("<9>spare-9a")) * 9;
user_font_styles[num_font_styles]->score +=
charset_works(font, gettext("<9>spare-9b")) * 9;
#endif
// this really should be dynamic, avoiding the need for a special build
#ifdef OLPC_XO
// Maybe German adds a "\xc2\xb7" (middle dot) and colon here? The key wouldn't change though.
user_font_styles[num_font_styles]->score += charset_works(font, "\xc3\x97\xc3\xb7"); // multiply and divide
// Maybe German adds a "\xc2\xb7" (middle dot) and colon here? The key wouldn't change though.
user_font_styles[num_font_styles]->score += charset_works(font, "\xc3\x97\xc3\xb7"); // multiply and divide
#endif
// FIXME: add topology tests ('A' has one hole, 'B' has two holes, etc.)
// FIXME: add topology tests ('A' has one hole, 'B' has two holes, etc.)
num_font_styles++;
num_font_styles++;
//printf("Accepted: %s, %s, %s, score(%d)\n", files[i].str, family, style, user_font_styles[num_font_styles]->score);
files[i].str = NULL; // so free() won't crash -- we stole the memory
}
else
{
#ifdef DEBUG
fprintf(stderr, "Font is too defective: %s, %s, %s\n", files[i].str, family, style);
#endif
}
TuxPaint_Font_CloseFont(font);
}
else
{
#ifdef DEBUG
fprintf(stderr, "could not open %s\n", files[i].str);
#endif
}
files[i].str = NULL; // so free() won't crash -- we stole the memory
}
free(files[i].str);
else
{
#ifdef DEBUG
fprintf(stderr, "Font is too defective: %s, %s, %s\n", files[i].str,
family, style);
#endif
}
TuxPaint_Font_CloseFont(font);
}
else
{
#ifdef DEBUG
fprintf(stderr, "could not open %s\n", files[i].str);
#endif
}
}
free(files[i].str);
}
free(files);
}
@ -305,10 +328,17 @@ int compare_ftw_str(const void *v1, const void *v2)
* @param fn Callback function to invoke
* @param locale Locale, to pass to callback function when applicable (i.e., for fonts), else NULL
*/
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, char *restrict const dir,
unsigned dirlen, int rsrc, void (*fn) (SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale),
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, char *restrict const dir,
unsigned dirlen, int rsrc, void (*fn)(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const
dir, unsigned dirlen,
tp_ftw_str * files,
unsigned count,
const char *restrict const
locale),
const char *restrict const locale)
{
DIR *d;
@ -335,173 +365,177 @@ void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer
AAssetDir *adir;
if (!d) /* Fallback into assets */
{
/* Remove the trailing '/' */
dlen = strlen(dir) - 1;
di = strndup(dir, dlen);
adir = open_asset_dir(di);
if (!adir)
return;
}
{
/* Remove the trailing '/' */
dlen = strlen(dir) - 1;
di = strndup(dir, dlen);
adir = open_asset_dir(di);
if (!adir)
return;
}
#else
if (!d)
return;
#endif
for (;;)
{
struct dirent *f;
{
struct dirent *f;
if (d)
f = readdir(d);
int filetype = TP_FTW_UNKNOWN;
if (d)
f = readdir(d);
int filetype = TP_FTW_UNKNOWN;
#ifdef __ANDROID__
char *afilename;
char *afilename;
if (!d)
{
afilename = AAssetDir_getNextFileName(adir);
if (afilename)
{
f = malloc(sizeof(struct dirent));
strncpy(f->d_name, afilename, sizeof(f->d_name));
f->d_type = DT_REG;
if (!d)
{
afilename = AAssetDir_getNextFileName(adir);
if (afilename)
{
f = malloc(sizeof(struct dirent));
strncpy(f->d_name, afilename, sizeof(f->d_name));
f->d_type = DT_REG;
/* There is not _DIRENT_HAVE_D_NAMLEN currently on Android 4.3, but who knows in the future... */
/* There is not _DIRENT_HAVE_D_NAMLEN currently on Android 4.3, but who knows in the future... */
#if defined(_DIRENT_HAVE_D_NAMLEN)
f->d_namlen = strlen(f->d_name);
f->d_namlen = strlen(f->d_name);
#endif
/* AAssetDir_getNextFileName() only lists files, not (sub)dirs,
and we don't put any device or special file inside assets,
so it is a regular file */
filetype = TP_FTW_NORMAL;
}
else
break;
}
#endif
if (!f)
/* AAssetDir_getNextFileName() only lists files, not (sub)dirs,
and we don't put any device or special file inside assets,
so it is a regular file */
filetype = TP_FTW_NORMAL;
}
else
break;
if (f->d_name[0] == '.')
continue;
}
#endif
if (!f)
break;
if (f->d_name[0] == '.')
continue;
// Linux and BSD can often provide file type info w/o the stat() call
#ifdef DT_UNKNOWN
switch (f->d_type)
{
default:
continue;
case DT_REG:
if (!rsrc) // if maybe opening resource files, need st_size
filetype = TP_FTW_NORMAL;
break;
case DT_DIR:
filetype = TP_FTW_DIRECTORY;
break;
case DT_UNKNOWN:
case DT_LNK:
;
}
switch (f->d_type)
{
default:
continue;
case DT_REG:
if (!rsrc) // if maybe opening resource files, need st_size
filetype = TP_FTW_NORMAL;
break;
case DT_DIR:
filetype = TP_FTW_DIRECTORY;
break;
case DT_UNKNOWN:
case DT_LNK:
;
}
#else
#warning Failed to see DT_UNKNOWN
#endif
#if defined(_DIRENT_HAVE_D_NAMLEN) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
d_namlen = f->d_namlen;
d_namlen = f->d_namlen;
#else
d_namlen = strlen(f->d_name);
d_namlen = strlen(f->d_name);
#endif
add_rsrc = 0;
add_rsrc = 0;
if (filetype == TP_FTW_UNKNOWN)
{
struct stat sbuf;
if (filetype == TP_FTW_UNKNOWN)
{
struct stat sbuf;
memcpy(dir + dirlen, f->d_name, d_namlen + 1);
if (stat(dir, &sbuf))
continue; // oh well... try the next one
if (S_ISDIR(sbuf.st_mode))
filetype = TP_FTW_DIRECTORY;
else if (S_ISREG(sbuf.st_mode))
{
filetype = TP_FTW_NORMAL;
if (rsrc && !sbuf.st_size)
add_rsrc = 5; // 5 is length of "/rsrc"
}
else
continue; // was a device file or somesuch
}
if (filetype == TP_FTW_NORMAL)
{
char *cp;
if (num_file_names == max_file_names)
{
max_file_names = max_file_names * 5 / 4 + 30;
file_names = realloc(file_names, max_file_names * sizeof *file_names);
}
cp = malloc(d_namlen + add_rsrc + 1);
memcpy(cp, f->d_name, d_namlen);
if (add_rsrc)
memcpy(cp + d_namlen, "/rsrc", 6);
else
cp[d_namlen] = '\0';
file_names[num_file_names].str = cp;
file_names[num_file_names].len = d_namlen;
num_file_names++;
}
if (filetype == TP_FTW_DIRECTORY)
{
char *cp;
if (num_dir_names == max_dir_names)
{
max_dir_names = max_dir_names * 5 / 4 + 3;
dir_names = realloc(dir_names, max_dir_names * sizeof *dir_names);
}
cp = malloc(d_namlen + 1);
memcpy(cp, f->d_name, d_namlen + 1);
dir_names[num_dir_names].str = cp;
dir_names[num_dir_names].len = d_namlen;
num_dir_names++;
}
memcpy(dir + dirlen, f->d_name, d_namlen + 1);
if (stat(dir, &sbuf))
continue; // oh well... try the next one
if (S_ISDIR(sbuf.st_mode))
filetype = TP_FTW_DIRECTORY;
else if (S_ISREG(sbuf.st_mode))
{
filetype = TP_FTW_NORMAL;
if (rsrc && !sbuf.st_size)
add_rsrc = 5; // 5 is length of "/rsrc"
}
else
continue; // was a device file or somesuch
}
if (filetype == TP_FTW_NORMAL)
{
char *cp;
if (num_file_names == max_file_names)
{
max_file_names = max_file_names * 5 / 4 + 30;
file_names = realloc(file_names, max_file_names * sizeof *file_names);
}
cp = malloc(d_namlen + add_rsrc + 1);
memcpy(cp, f->d_name, d_namlen);
if (add_rsrc)
memcpy(cp + d_namlen, "/rsrc", 6);
else
cp[d_namlen] = '\0';
file_names[num_file_names].str = cp;
file_names[num_file_names].len = d_namlen;
num_file_names++;
}
if (filetype == TP_FTW_DIRECTORY)
{
char *cp;
if (num_dir_names == max_dir_names)
{
max_dir_names = max_dir_names * 5 / 4 + 3;
dir_names = realloc(dir_names, max_dir_names * sizeof *dir_names);
}
cp = malloc(d_namlen + 1);
memcpy(cp, f->d_name, d_namlen + 1);
dir_names[num_dir_names].str = cp;
dir_names[num_dir_names].len = d_namlen;
num_dir_names++;
}
}
closedir(d);
show_progress_bar_(screen, texture, renderer);
dir[dirlen] = '\0'; // repair it (clobbered for stat() call above)
if (1 || file_names) // Now ALWAYS calling callback function, so stamp loader can notice top-level directories (even if there are only subdirs, and no files, inside) -bjk 2007.05.16
{
{
// let callee sort and keep the string
#if 0
qsort(file_names, num_file_names, sizeof *file_names, compare_ftw_str);
while (num_file_names--)
{
free(file_names[num_file_names].str);
}
free(file_names);
qsort(file_names, num_file_names, sizeof *file_names, compare_ftw_str);
while (num_file_names--)
{
free(file_names[num_file_names].str);
}
free(file_names);
#else
#ifdef __ANDROID__
if (dlen != dirlen) /* First case only happens in Android files coming from assets */
fn(screen, texture, renderer, di, dlen, file_names, num_file_names, locale);
else
if (dlen != dirlen) /* First case only happens in Android files coming from assets */
fn(screen, texture, renderer, di, dlen, file_names, num_file_names,
locale);
else
#endif
fn(screen, texture, renderer, dir, dirlen, file_names, num_file_names, locale);
fn(screen, texture, renderer, dir, dirlen, file_names, num_file_names,
locale);
#endif
}
}
if (dir_names)
{
qsort(dir_names, num_dir_names, sizeof *dir_names, compare_ftw_str);
while (num_dir_names--)
{
qsort(dir_names, num_dir_names, sizeof *dir_names, compare_ftw_str);
while (num_dir_names--)
{
memcpy(dir + dirlen, dir_names[num_dir_names].str, dir_names[num_dir_names].len + 1);
tp_ftw(screen, texture, renderer, dir, dirlen + dir_names[num_dir_names].len, rsrc, fn, locale);
free(dir_names[num_dir_names].str);
}
free(dir_names);
memcpy(dir + dirlen, dir_names[num_dir_names].str,
dir_names[num_dir_names].len + 1);
tp_ftw(screen, texture, renderer, dir,
dirlen + dir_names[num_dir_names].len, rsrc, fn, locale);
free(dir_names[num_dir_names].str);
}
free(dir_names);
}
}

View file

@ -45,14 +45,23 @@ typedef struct tp_ftw_str
} tp_ftw_str;
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files, unsigned i,
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen,
tp_ftw_str * files, unsigned i,
const char *restrict const locale);
int compare_ftw_str(const void *v1, const void *v2);
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, char *restrict const dir,
unsigned dirlen, int rsrc, void (*fn) (SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files,
unsigned count, const char *restrict const locale),
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, char *restrict const dir,
unsigned dirlen, int rsrc, void (*fn)(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const
dir, unsigned dirlen,
tp_ftw_str * files,
unsigned count,
const char *restrict const
locale),
const char *restrict const locale);
#endif

View file

@ -64,63 +64,73 @@
#define QUEUE_SIZE_CHUNK 1024
typedef struct queue_s {
typedef struct queue_s
{
int x, y, y_outside;
} queue_t;
queue_t * queue;
queue_t *queue;
int queue_size = 0, queue_end = 0;
/* Local function prototypes: */
SDL_Surface * global_screen, * global_last, * global_canvas;
SDL_Surface *global_screen, *global_last, *global_canvas;
Uint32 global_old_colr, global_cur_colr;
Uint8 * global_touched;
Uint8 *global_touched;
int global_extent_x1, global_extent_y1, global_extent_x2, global_extent_y2;
int global_prog_anim;
double colors_close(SDL_Surface * canvas, Uint32 c1, Uint32 c2);
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct);
void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, int x, int y, int y_outside);
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y, Uint32 draw_color, Uint8 * touched);
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr,
double pct);
void simulate_flood_fill_outside_check(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer, int x, int y,
int y_outside);
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y,
Uint32 draw_color, Uint8 * touched);
void init_queue(void);
void add_to_queue(int x, int y, int y_outside);
int remove_from_queue(int * x, int * y, int * y_outside);
int remove_from_queue(int *x, int *y, int *y_outside);
void cleanup_queue(void);
void init_queue(void) {
void init_queue(void)
{
queue_size = 0;
queue_end = 0;
queue = (queue_t *) malloc(sizeof(queue_t) * QUEUE_SIZE_CHUNK);
if (queue == NULL)
{
fprintf(stderr, "Fill queue cannot be malloc()'d\n");
return;
}
{
fprintf(stderr, "Fill queue cannot be malloc()'d\n");
return;
}
queue_size = QUEUE_SIZE_CHUNK;
}
void add_to_queue(int x, int y, int y_outside) {
void add_to_queue(int x, int y, int y_outside)
{
/* Reallocate if we need more space */
if (queue_end + 1 > queue_size)
{
queue_t *tmp;
tmp =
(queue_t *) realloc(queue,
sizeof(queue_t) * (queue_size + QUEUE_SIZE_CHUNK));
if (tmp == NULL)
{
queue_t * tmp;
tmp = (queue_t *) realloc(queue, sizeof(queue_t) * (queue_size + QUEUE_SIZE_CHUNK));
if (tmp == NULL)
{
fprintf(stderr, "Fill queue cannot be realloc()'d\n");
return;
}
queue_size += QUEUE_SIZE_CHUNK;
#ifdef DEBUG
printf("queue_size = %d\n", queue_size);
fflush(stdout);
#endif
queue = tmp;
fprintf(stderr, "Fill queue cannot be realloc()'d\n");
return;
}
queue_size += QUEUE_SIZE_CHUNK;
#ifdef DEBUG
printf("queue_size = %d\n", queue_size);
fflush(stdout);
#endif
queue = tmp;
}
queue[queue_end].x = x;
queue[queue_end].y = y;
@ -130,14 +140,15 @@ void add_to_queue(int x, int y, int y_outside) {
#ifdef DEBUG
if (queue_end % 100 == 0)
{
printf("queue_end = %d\n", queue_end);
fflush(stdout);
}
{
printf("queue_end = %d\n", queue_end);
fflush(stdout);
}
#endif
}
int remove_from_queue(int * x, int * y, int * y_outside) {
int remove_from_queue(int *x, int *y, int *y_outside)
{
if (queue_end == 0)
return 0;
@ -149,16 +160,17 @@ int remove_from_queue(int * x, int * y, int * y_outside) {
#ifdef DEBUG
if (queue_end % 100 == 0)
{
printf("queue_end = %d\n", queue_end);
fflush(stdout);
}
{
printf("queue_end = %d\n", queue_end);
fflush(stdout);
}
#endif
return 1;
}
void cleanup_queue(void) {
void cleanup_queue(void)
{
if (queue != NULL)
free(queue);
@ -177,51 +189,60 @@ double colors_close(SDL_Surface * canvas, Uint32 c1, Uint32 c2)
Uint8 r1, g1, b1, r2, g2, b2;
if (c1 == c2)
{
/* Get it over with quick, if possible! */
{
/* Get it over with quick, if possible! */
return 0.0;
}
return 0.0;
}
else
{
double r, g, b;
{
double r, g, b;
SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
// use distance in linear RGB space
r = sRGB_to_linear_table[r1] - sRGB_to_linear_table[r2];
r *= r;
g = sRGB_to_linear_table[g1] - sRGB_to_linear_table[g2];
g *= g;
b = sRGB_to_linear_table[b1] - sRGB_to_linear_table[b2];
b *= b;
// use distance in linear RGB space
r = sRGB_to_linear_table[r1] - sRGB_to_linear_table[r2];
r *= r;
g = sRGB_to_linear_table[g1] - sRGB_to_linear_table[g2];
g *= g;
b = sRGB_to_linear_table[b1] - sRGB_to_linear_table[b2];
b *= b;
// easy to confuse:
// dark grey, brown, purple
// light grey, tan
// red, orange
return (r + g + b);
}
// easy to confuse:
// dark grey, brown, purple
// light grey, tan
// red, orange
return (r + g + b);
}
}
int would_flood_fill(SDL_Surface * canvas, Uint32 cur_colr, Uint32 old_colr)
{
if (colors_close(canvas, cur_colr, old_colr) < COLOR_MATCH_NARROW)
{
return 0;
} else {
return 1;
}
{
return 0;
}
else
{
return 1;
}
}
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched)
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, SDL_Surface * last,
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
Uint8 * touched)
{
simulate_flood_fill(screen, texture, renderer, last, canvas, x, y, cur_colr, old_colr, x1, y1, x2, y2, touched);
simulate_flood_fill(screen, texture, renderer, last, canvas, x, y, cur_colr,
old_colr, x1, y1, x2, y2, touched);
}
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct) {
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr,
double pct)
{
Uint8 old_r, old_g, old_b, draw_r, draw_g, draw_b, new_r, new_g, new_b;
SDL_GetRGB(draw_colr, canvas->format, &draw_r, &draw_g, &draw_b);
@ -235,7 +256,12 @@ Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct
return SDL_MapRGB(canvas->format, new_r, new_g, new_b);
}
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * extent_x1, int * extent_y1, int * extent_x2, int * extent_y2, Uint8 * touched) {
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, SDL_Surface * last,
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
Uint32 old_colr, int *extent_x1, int *extent_y1,
int *extent_x2, int *extent_y2, Uint8 * touched)
{
int y_outside;
/* Get ready */
@ -257,9 +283,10 @@ void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Render
/* Do the work (possibly queuing more, as we go) */
while (remove_from_queue(&x, &y, &y_outside))
{
simulate_flood_fill_outside_check(screen, texture, renderer, x, y, y_outside);
}
{
simulate_flood_fill_outside_check(screen, texture, renderer, x, y,
y_outside);
}
cleanup_queue();
*extent_x1 = global_extent_x1;
@ -268,7 +295,10 @@ void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Render
*extent_y2 = global_extent_y2;
}
void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, int x, int y, int y_outside)
void simulate_flood_fill_outside_check(SDL_Surface * screen,
SDL_Texture * texture,
SDL_Renderer * renderer, int x, int y,
int y_outside)
{
int fillL, fillR, narrowFillL, narrowFillR, i, outside, just_queued;
double in_line, closeness;
@ -287,13 +317,13 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
return;
if (y < global_extent_y1)
{
global_extent_y1 = y;
}
{
global_extent_y1 = y;
}
if (y > global_extent_y2)
{
global_extent_y2 = y;
}
{
global_extent_y2 = y;
}
fillL = x;
@ -303,139 +333,172 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
global_prog_anim++;
if ((global_prog_anim % 8) == 0)
{
show_progress_bar_(screen, texture, renderer);
{
show_progress_bar_(screen, texture, renderer);
}
}
if ((global_prog_anim % 800) == 1) /* Always lay sound _once_ */
if ((global_prog_anim % 800) == 1) /* Always lay sound _once_ */
playsound(global_canvas, 1, SND_FILL, 1, x, SNDDIST_NEAR);
#ifdef DEBUG_WATCH
if (global_prog_anim % 100 == 0)
{
SDL_BlitSurface(global_canvas, NULL, global_screen, NULL);
SDL_Flip(global_screen);
}
{
SDL_BlitSurface(global_canvas, NULL, global_screen, NULL);
SDL_Flip(global_screen);
}
#endif
/* Find left side, filling along the way */
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL /* - 1 */, y);
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last,
fillL /* - 1 */ , y);
in_line = colors_close(global_canvas, px_colr, global_old_colr);
outside = 0;
while (in_line < COLOR_MATCH_WIDE && outside < WIDE_MATCH_THRESHOLD)
{
if (in_line > COLOR_MATCH_NARROW)
{
if (in_line > COLOR_MATCH_NARROW) {
outside++;
} else {
narrowFillL = fillL;
}
if (global_touched != NULL) {
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
}
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
fillL--;
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
if (fillL >= 0)
{
in_line = colors_close(global_canvas, px_colr, global_old_colr);
}
else
{
in_line = 3.0;
}
outside++;
}
else
{
narrowFillL = fillL;
}
if (global_touched != NULL)
{
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
}
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y,
blend(global_canvas,
global_cur_colr,
px_colr,
(1.0 - in_line)));
fillL--;
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
if (fillL >= 0)
{
in_line = colors_close(global_canvas, px_colr, global_old_colr);
}
else
{
in_line = 3.0;
}
}
if (fillL >= 0)
{
if (global_touched != NULL)
{
if (global_touched != NULL)
{
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
}
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
}
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y,
blend(global_canvas,
global_cur_colr,
px_colr,
(1.0 - in_line)));
}
if (fillL < global_extent_x1)
{
global_extent_x1 = fillL;
}
{
global_extent_x1 = fillL;
}
fillL++;
/* Find right side, filling along the way */
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR + 1, y);
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillR + 1, y);
in_line = colors_close(global_canvas, px_colr, global_old_colr);
outside = 0;
while (in_line < COLOR_MATCH_WIDE && outside < WIDE_MATCH_THRESHOLD)
{
if (in_line > COLOR_MATCH_NARROW)
{
if (in_line > COLOR_MATCH_NARROW) {
outside++;
} else {
narrowFillR = fillR;
}
if (global_touched != NULL) {
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
}
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
fillR++;
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
if (fillR < global_canvas->w)
{
in_line = colors_close(global_canvas, px_colr, global_old_colr);
}
else
{
in_line = 3.0;
}
outside++;
}
else
{
narrowFillR = fillR;
}
if (global_touched != NULL)
{
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
}
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y,
blend(global_canvas,
global_cur_colr,
px_colr,
(1.0 - in_line)));
fillR++;
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
if (fillR < global_canvas->w)
{
in_line = colors_close(global_canvas, px_colr, global_old_colr);
}
else
{
in_line = 3.0;
}
}
if (fillR < global_canvas->w)
{
if (global_touched != NULL)
{
if (global_touched != NULL)
{
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
touch_byt = (255 - ((Uint8) (in_line * 85)));
if (touch_byt == 0)
touch_byt = 1;
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
}
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
}
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y,
blend(global_canvas,
global_cur_colr,
px_colr,
(1.0 - in_line)));
}
if (fillR > global_extent_x2)
{
global_extent_x2 = fillR;
}
{
global_extent_x2 = fillR;
}
fillR--;
@ -444,69 +507,74 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
just_queued = 0;
if (y > 0)
{
for (i = narrowFillL; i <= narrowFillR; i++)
{
for (i = narrowFillL; i <= narrowFillR; i++)
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, i, y - 1);
closeness = colors_close(global_canvas, px_colr, global_old_colr);
if (closeness < COLOR_MATCH_NARROW ||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD))
{
if (!just_queued
&& (global_touched == NULL
|| !global_touched[((y - 1) * global_canvas->w) + i]))
{
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, i, y - 1);
closeness = colors_close(global_canvas, px_colr, global_old_colr);
if (closeness < COLOR_MATCH_NARROW ||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD)
)
{
if (!just_queued && (global_touched == NULL || !global_touched[((y - 1) * global_canvas->w) + i]))
{
add_to_queue(i, y - 1, y_outside + 1);
just_queued = 1;
}
else
{
just_queued = 0;
}
}
else
{
just_queued = 0;
}
add_to_queue(i, y - 1, y_outside + 1);
just_queued = 1;
}
else
{
just_queued = 0;
}
}
else
{
just_queued = 0;
}
}
}
/* Continue filling downwards from this scanline */
just_queued = 0;
if (y < global_canvas->h - 1)
{
for (i = narrowFillL; i <= narrowFillR; i++)
{
for (i = narrowFillL; i <= narrowFillR; i++)
px_colr =
getpixels[global_last->format->BytesPerPixel] (global_last, i, y + 1);
closeness = colors_close(global_canvas, px_colr, global_old_colr);
if (closeness < COLOR_MATCH_NARROW ||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD))
{
if (!just_queued
&& (global_touched == NULL
|| !global_touched[((y + 1) * global_canvas->w) + i]))
{
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, i, y + 1);
closeness = colors_close(global_canvas, px_colr, global_old_colr);
if (closeness < COLOR_MATCH_NARROW ||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD)
)
{
if (!just_queued && (global_touched == NULL || !global_touched[((y + 1) * global_canvas->w) + i]))
{
add_to_queue(i, y + 1, y_outside + 1);
just_queued = 1;
}
else
{
just_queued = 0;
}
}
else
{
just_queued = 0;
}
add_to_queue(i, y + 1, y_outside + 1);
just_queued = 1;
}
else
{
just_queued = 0;
}
}
else
{
just_queued = 0;
}
}
}
}
void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
int x_left, int y_top, int x_right, int y_bottom,
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched
) {
int x_left, int y_top, int x_right, int y_bottom,
int x1, int y1, int x2, int y2, Uint32 draw_color,
Uint8 * touched)
{
Uint32 old_colr, new_colr;
int xx, yy;
Uint8 draw_r, draw_g, draw_b, old_r, old_g, old_b, new_r, new_g, new_b;
@ -521,9 +589,12 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
C2 = (A * x2) + (B * y2);
/* FIXME: C2 should be larger than C1? */
for (yy = y_top; yy <= y_bottom; yy++) {
for (xx = x_left; xx <= x_right; xx++) {
if (touched[(yy * canvas->w) + xx]) {
for (yy = y_top; yy <= y_bottom; yy++)
{
for (xx = x_left; xx <= x_right; xx++)
{
if (touched[(yy * canvas->w) + xx])
{
/* Get the old color, and blend it (with a distance-based ratio) with the target color */
old_colr = getpixels[last->format->BytesPerPixel] (last, xx, yy);
SDL_GetRGB(old_colr, last->format, &old_r, &old_g, &old_b);
@ -532,13 +603,18 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
https://stackoverflow.com/questions/521493/creating-a-linear-gradient-in-2d-array) */
C = (A * xx) + (B * yy);
if (C < C1) {
if (C < C1)
{
/* At/beyond the click spot (opposite direction of mouse); solid color */
ratio = 0.0;
} else if (C >= C2) {
}
else if (C >= C2)
{
/* At/beyond the mouse; completely faded out */
ratio = 1.0;
} else {
}
else
{
/* The actual gradient... */
ratio = (C - C1) / (C2 - C1);
}
@ -546,9 +622,15 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
/* Apply fuzziness at any antialiased edges we detected */
ratio = (ratio * ((float) touched[yy * canvas->w + xx] / 255.0));
new_r = (Uint8) (((float) old_r) * ratio + ((float) draw_r * (1.0 - ratio)));
new_g = (Uint8) (((float) old_g) * ratio + ((float) draw_g * (1.0 - ratio)));
new_b = (Uint8) (((float) old_b) * ratio + ((float) draw_b * (1.0 - ratio)));
new_r =
(Uint8) (((float) old_r) * ratio +
((float) draw_r * (1.0 - ratio)));
new_g =
(Uint8) (((float) old_g) * ratio +
((float) draw_g * (1.0 - ratio)));
new_b =
(Uint8) (((float) old_b) * ratio +
((float) draw_b * (1.0 - ratio)));
new_colr = SDL_MapRGB(canvas->format, new_r, new_g, new_b);
putpixels[canvas->format->BytesPerPixel] (canvas, xx, yy, new_colr);
@ -557,27 +639,32 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
}
}
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y, Uint32 draw_color, Uint8 * touched) {
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y,
Uint32 draw_color, Uint8 * touched)
{
int xx, yy;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
for (xx = -16; xx < 16; xx++)
{
if ((xx * xx) + (yy * yy) < (16 * 16) &&
touched[((y + yy) * canvas->w) + (x + xx)])
{
putpixels[canvas->format->BytesPerPixel] (canvas, x + xx, y + yy, draw_color);
}
}
if ((xx * xx) + (yy * yy) < (16 * 16) &&
touched[((y + yy) * canvas->w) + (x + xx)])
{
putpixels[canvas->format->BytesPerPixel] (canvas, x + xx, y + yy,
draw_color);
}
}
}
}
void draw_brush_fill(SDL_Surface * canvas,
int x_left ATTRIBUTE_UNUSED, int y_top ATTRIBUTE_UNUSED, int x_right ATTRIBUTE_UNUSED, int y_bottom ATTRIBUTE_UNUSED,
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched,
int * up_x1, int * up_y1, int * up_x2, int * up_y2
) {
int x_left ATTRIBUTE_UNUSED, int y_top ATTRIBUTE_UNUSED,
int x_right ATTRIBUTE_UNUSED,
int y_bottom ATTRIBUTE_UNUSED, int x1, int y1, int x2,
int y2, Uint32 draw_color, Uint8 * touched, int *up_x1,
int *up_y1, int *up_x2, int *up_y2)
{
int dx, dy;
int y;
int orig_x1, orig_y1, orig_x2, orig_y2, tmp;
@ -593,60 +680,60 @@ void draw_brush_fill(SDL_Surface * canvas,
dy = y2 - y1;
if (dx != 0)
{
m = ((float) dy) / ((float) dx);
b = y1 - m * x1;
if (x2 >= x1)
dx = 1;
else
dx = -1;
while (x1 != x2)
{
m = ((float)dy) / ((float)dx);
b = y1 - m * x1;
y1 = m * x1 + b;
y2 = m * (x1 + dx) + b;
if (x2 >= x1)
dx = 1;
else
dx = -1;
while (x1 != x2)
{
y1 = m * x1 + b;
y2 = m * (x1 + dx) + b;
if (y1 > y2)
{
for (y = y1; y >= y2; y--)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
}
else
{
for (y = y1; y <= y2; y++)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
}
x1 = x1 + dx;
}
}
else
{
if (y1 > y2)
{
y = y1;
y1 = y2;
y2 = y;
}
{
for (y = y1; y >= y2; y--)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
}
else
{
for (y = y1; y <= y2; y++)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
}
for (y = y1; y <= y2; y++)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
x1 = x1 + dx;
}
}
else
{
if (y1 > y2)
{
y = y1;
y1 = y2;
y2 = y;
}
for (y = y1; y <= y2; y++)
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
}
if (orig_x1 > orig_x2)
{
tmp = orig_x1;
orig_x1 = orig_x2;
orig_x2 = tmp;
}
{
tmp = orig_x1;
orig_x1 = orig_x2;
orig_x2 = tmp;
}
if (orig_y1 > orig_y2)
{
tmp = orig_y1;
orig_y1 = orig_y2;
orig_y2 = tmp;
}
{
tmp = orig_y1;
orig_y1 = orig_y2;
orig_y2 = tmp;
}
*up_x1 = orig_x1 - 16;
*up_y1 = orig_y1 - 16;
@ -654,9 +741,10 @@ void draw_brush_fill(SDL_Surface * canvas,
*up_y2 = orig_y2 + 16;
}
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_right, int y_bottom,
int x, int y, Uint32 draw_color, Uint8 * touched
) {
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top,
int x_right, int y_bottom, int x, int y,
Uint32 draw_color, Uint8 * touched)
{
Uint32 old_colr, new_colr;
int xx, yy;
float xd, yd, dist, rad, ratio;
@ -666,7 +754,8 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
xd = max(abs(x - x_right), abs(x - x_left));
yd = max(abs(y - y_bottom), abs(y - y_top));
rad = sqrt(xd * xd + yd * yd);
if (rad == 0) {
if (rad == 0)
{
return;
}
@ -674,27 +763,38 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
SDL_GetRGB(draw_color, canvas->format, &draw_r, &draw_g, &draw_b);
/* Traverse the flood-filled zone */
for (yy = y_top; yy <= y_bottom; yy++) {
for (xx = x_left; xx <= x_right; xx++) {
for (yy = y_top; yy <= y_bottom; yy++)
{
for (xx = x_left; xx <= x_right; xx++)
{
/* Only alter the pixels within the flood itself */
if (touched[(yy * canvas->w) + xx]) {
if (touched[(yy * canvas->w) + xx])
{
/* Determine the distance from the click point */
xd = fabs((float) (xx - x));
yd = fabs((float) (yy - y));
dist = sqrt(xd * xd + yd * yd);
if (dist < rad) {
if (dist < rad)
{
ratio = (dist / rad);
/* Get the old color, and blend it (with a distance-based ratio) with the target color */
old_colr = getpixels[canvas->format->BytesPerPixel] (canvas, xx, yy);
old_colr =
getpixels[canvas->format->BytesPerPixel] (canvas, xx, yy);
SDL_GetRGB(old_colr, canvas->format, &old_r, &old_g, &old_b);
/* Apply fuzziness at any antialiased edges we detected */
ratio = (ratio * ((float) touched[yy * canvas->w + xx] / 255.0));
new_r = (Uint8) (((float) old_r) * ratio + ((float) draw_r * (1.00 - ratio)));
new_g = (Uint8) (((float) old_g) * ratio + ((float) draw_g * (1.00 - ratio)));
new_b = (Uint8) (((float) old_b) * ratio + ((float) draw_b * (1.00 - ratio)));
new_r =
(Uint8) (((float) old_r) * ratio +
((float) draw_r * (1.00 - ratio)));
new_g =
(Uint8) (((float) old_g) * ratio +
((float) draw_g * (1.00 - ratio)));
new_b =
(Uint8) (((float) old_b) * ratio +
((float) draw_b * (1.00 - ratio)));
new_colr = SDL_MapRGB(canvas->format, new_r, new_g, new_b);
putpixels[canvas->format->BytesPerPixel] (canvas, xx, yy, new_colr);
@ -703,4 +803,3 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
}
}
}

View file

@ -37,17 +37,26 @@
#include "SDL.h"
int would_flood_fill(SDL_Surface * canvas, Uint32 cur_colr, Uint32 old_colr);
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched);
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched);
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, SDL_Surface * last,
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
Uint8 * touched);
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, SDL_Surface * last,
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
Uint8 * touched);
void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
int x_left, int y_top, int x_right, int y_bottom,
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched);
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_right, int y_bottom,
int x, int y, Uint32 draw_color, Uint8 * touched);
void draw_brush_fill(SDL_Surface * canvas,
int x_left, int y_top, int x_right, int y_bottom,
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched,
int * up_x1, int * up_y1, int * up_x2, int * up_y2);
int x_left, int y_top, int x_right, int y_bottom,
int x1, int y1, int x2, int y2, Uint32 draw_color,
Uint8 * touched);
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top,
int x_right, int y_bottom, int x, int y,
Uint32 draw_color, Uint8 * touched);
void draw_brush_fill(SDL_Surface * canvas, int x_left, int y_top, int x_right,
int y_bottom, int x1, int y1, int x2, int y2,
Uint32 draw_color, Uint8 * touched, int *up_x1,
int *up_y1, int *up_x2, int *up_y2);
#endif

View file

@ -38,7 +38,8 @@
#define gettext_noop(String) String
#endif
enum {
enum
{
FILL_FLOOD,
FILL_BRUSH,
FILL_GRADIENT_LINEAR,
@ -56,8 +57,10 @@ const char *const fill_names[NUM_FILLS] = {
const char *const fill_tips[NUM_FILLS] = {
gettext_noop("Click to fill an area with a solid color."),
gettext_noop("Click and drag to fill an area by hand, using a brush."),
gettext_noop("Click and drag to fill an area with a linear gradient (from the chosen color to transparent)."),
gettext_noop("Click to fill an area with a radial gradient (from the chosen color to transparent).")
gettext_noop
("Click and drag to fill an area with a linear gradient (from the chosen color to transparent)."),
gettext_noop
("Click to fill an area with a radial gradient (from the chosen color to transparent).")
};
const char *const fill_img_fnames[NUM_FILLS] = {
@ -68,4 +71,3 @@ const char *const fill_img_fnames[NUM_FILLS] = {
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -121,9 +121,11 @@ int TuxPaint_Font_FontHeight(TuxPaint_Font * tpf);
#ifdef FORKED_FONTS
void reliable_write(int fd, const void *buf, size_t count);
void run_font_scanner(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
void run_font_scanner(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer,
const char *restrict const locale);
void receive_some_font_info(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer);
void receive_some_font_info(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer);
#endif
//////////////////////////////////////////////////////////////////////
@ -191,7 +193,8 @@ TuxPaint_Font *getfonthandle(int desire);
int charset_works(TuxPaint_Font * font, const char *s);
TuxPaint_Font *TuxPaint_Font_OpenFont(const char *pangodesc, const char *ttffilename, int size);
TuxPaint_Font *TuxPaint_Font_OpenFont(const char *pangodesc,
const char *ttffilename, int size);
void TuxPaint_Font_CloseFont(TuxPaint_Font * tpf);
const char *TuxPaint_Font_FontFaceFamilyName(TuxPaint_Font * tpf);
const char *TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf);
@ -199,10 +202,12 @@ const char *TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf);
#ifdef NO_SDLPANGO
TuxPaint_Font *load_locale_font(TuxPaint_Font * fallback, int size);
#else
void sdl_color_to_pango_color(SDL_Color sdl_color, SDLPango_Matrix * pango_color);
void sdl_color_to_pango_color(SDL_Color sdl_color,
SDLPango_Matrix * pango_color);
#endif
int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, void *vp,
int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer, void *vp,
const char *restrict const locale);
#endif

View file

@ -87,35 +87,40 @@ char *get_fname(const char *const name, int kind)
{
char f[512];
// const char *restrict const dir;
const char * dir;
const char *dir;
if (kind == DIR_SAVE) {
if (kind == DIR_SAVE)
{
dir = savedir;
} else if (kind == DIR_DATA) {
}
else if (kind == DIR_DATA)
{
dir = datadir;
} else if (kind == DIR_EXPORT || kind == DIR_EXPORT_PARENT) {
}
else if (kind == DIR_EXPORT || kind == DIR_EXPORT_PARENT)
{
dir = exportdir;
}
snprintf(f, sizeof(f),
"%s%c%s",
dir, (*name) ? '/' : '\0', /* Some mkdir()'s don't like trailing slashes */
name);
snprintf(f, sizeof(f), "%s%c%s", dir, (*name) ? '/' : '\0', /* Some mkdir()'s don't like trailing slashes */
name);
if (kind == DIR_EXPORT_PARENT) {
if (kind == DIR_EXPORT_PARENT)
{
int len, i, stop;
stop = -1;
len = strlen(f);
for (i = len - 1; i >= 0 && stop == -1; i--) {
for (i = len - 1; i >= 0 && stop == -1; i--)
{
if (f[i] == '/')
stop = i;
}
if (stop != -1) {
if (stop != -1)
{
f[stop] = '\0';
}
}
return strdup(f);
}

View file

@ -16,52 +16,50 @@
#define write_num(fd, n) write((fd), (uint8_t []) {(n) & 0xFF, (n) >> 8}, 2)
static uint8_t vga[0x30] = {
0x00, 0x00, 0x00,
0xAA, 0x00, 0x00,
0x00, 0xAA, 0x00,
0xAA, 0x55, 0x00,
0x00, 0x00, 0xAA,
0xAA, 0x00, 0xAA,
0x00, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55,
0xFF, 0x55, 0x55,
0x55, 0xFF, 0x55,
0xFF, 0xFF, 0x55,
0x55, 0x55, 0xFF,
0xFF, 0x55, 0xFF,
0x55, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00,
0xAA, 0x00, 0x00,
0x00, 0xAA, 0x00,
0xAA, 0x55, 0x00,
0x00, 0x00, 0xAA,
0xAA, 0x00, 0xAA,
0x00, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA,
0x55, 0x55, 0x55,
0xFF, 0x55, 0x55,
0x55, 0xFF, 0x55,
0xFF, 0xFF, 0x55,
0x55, 0x55, 0xFF,
0xFF, 0x55, 0xFF,
0x55, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
};
struct Node {
uint16_t key;
struct Node *children[];
struct Node
{
uint16_t key;
struct Node *children[];
};
typedef struct Node Node;
static Node *
new_node(uint16_t key, int degree)
static Node *new_node(uint16_t key, int degree)
{
Node *node = calloc(1, sizeof(*node) + degree * sizeof(Node *));
if (node)
node->key = key;
return node;
Node *node = calloc(1, sizeof(*node) + degree * sizeof(Node *));
if (node)
node->key = key;
return node;
}
static Node *
new_trie(int degree, int *nkeys)
static Node *new_trie(int degree, int *nkeys)
{
Node *root = new_node(0, degree);
/* Create nodes for single pixels. */
for (*nkeys = 0; *nkeys < degree; (*nkeys)++)
root->children[*nkeys] = new_node(*nkeys, degree);
*nkeys += 2; /* skip clear code and stop code */
return root;
Node *root = new_node(0, degree);
/* Create nodes for single pixels. */
for (*nkeys = 0; *nkeys < degree; (*nkeys)++)
root->children[*nkeys] = new_node(*nkeys, degree);
*nkeys += 2; /* skip clear code and stop code */
return root;
}
static void
del_trie(Node *root, int degree)
static void del_trie(Node * root, int degree)
{
int i;
@ -72,191 +70,261 @@ del_trie(Node *root, int degree)
free(root);
}
static void put_loop(ge_GIF *gif, uint16_t loop);
static void put_loop(ge_GIF * gif, uint16_t loop);
#define OR_ABORT if (res == -1) { fprintf(stderr, "Cannot write to GIF\n"); return(NULL); }
#define OR_ABORT2 if (res == -1) { fprintf(stderr, "Cannot write to GIF\n"); return; }
ge_GIF *
ge_new_gif(
const char *fname, uint16_t width, uint16_t height,
uint8_t *palette, int depth, int loop
)
ge_GIF *ge_new_gif(const char *fname, uint16_t width, uint16_t height,
uint8_t * palette, int depth, int loop)
{
int i, r, g, b, v;
ssize_t res;
ge_GIF *gif = calloc(1, sizeof(*gif) + 2*width*height);
if (!gif)
goto no_gif;
gif->w = width; gif->h = height;
gif->depth = depth > 1 ? depth : 2;
gif->frame = (uint8_t *) &gif[1];
gif->back = &gif->frame[width*height];
gif->fd = creat(fname, 0666);
if (gif->fd == -1)
goto no_fd;
int i, r, g, b, v;
ssize_t res;
ge_GIF *gif = calloc(1, sizeof(*gif) + 2 * width * height);
if (!gif)
goto no_gif;
gif->w = width;
gif->h = height;
gif->depth = depth > 1 ? depth : 2;
gif->frame = (uint8_t *) & gif[1];
gif->back = &gif->frame[width * height];
gif->fd = creat(fname, 0666);
if (gif->fd == -1)
goto no_fd;
#ifdef _WIN32
setmode(gif->fd, O_BINARY);
setmode(gif->fd, O_BINARY);
#endif
res = write(gif->fd, "GIF89a", 6); OR_ABORT;
res = write_num(gif->fd, width); OR_ABORT;
res = write_num(gif->fd, height); OR_ABORT;
res = write(gif->fd, (uint8_t []) {0xF0 | (depth-1), 0x00, 0x00}, 3); OR_ABORT;
if (palette) {
res = write(gif->fd, palette, 3 << depth); OR_ABORT;
} else if (depth <= 4) {
res = write(gif->fd, vga, 3 << depth); OR_ABORT;
} else {
res = write(gif->fd, vga, sizeof(vga)); OR_ABORT;
i = 0x10;
for (r = 0; r < 6; r++) {
for (g = 0; g < 6; g++) {
for (b = 0; b < 6; b++) {
res = write(gif->fd, (uint8_t []) {r*51, g*51, b*51}, 3); OR_ABORT;
if (++i == 1 << depth)
goto done_gct;
}
}
}
for (i = 1; i <= 24; i++) {
v = i * 0xFF / 25;
res = write(gif->fd, (uint8_t []) {v, v, v}, 3); OR_ABORT;
res = write(gif->fd, "GIF89a", 6);
OR_ABORT;
res = write_num(gif->fd, width);
OR_ABORT;
res = write_num(gif->fd, height);
OR_ABORT;
res = write(gif->fd, (uint8_t[])
{
0xF0 | (depth - 1), 0x00, 0x00}
, 3);
OR_ABORT;
if (palette)
{
res = write(gif->fd, palette, 3 << depth);
OR_ABORT;
}
else if (depth <= 4)
{
res = write(gif->fd, vga, 3 << depth);
OR_ABORT;
}
else
{
res = write(gif->fd, vga, sizeof(vga));
OR_ABORT;
i = 0x10;
for (r = 0; r < 6; r++)
{
for (g = 0; g < 6; g++)
{
for (b = 0; b < 6; b++)
{
res = write(gif->fd, (uint8_t[])
{
r * 51, g * 51, b * 51}
, 3);
OR_ABORT;
if (++i == 1 << depth)
goto done_gct;
}
}
}
for (i = 1; i <= 24; i++)
{
v = i * 0xFF / 25;
res = write(gif->fd, (uint8_t[])
{
v, v, v}
, 3);
OR_ABORT;
}
}
done_gct:
if (loop >= 0 && loop <= 0xFFFF)
put_loop(gif, (uint16_t) loop);
return gif;
if (loop >= 0 && loop <= 0xFFFF)
put_loop(gif, (uint16_t) loop);
return gif;
no_fd:
free(gif);
free(gif);
no_gif:
return NULL;
return NULL;
}
static void
put_loop(ge_GIF *gif, uint16_t loop)
static void put_loop(ge_GIF * gif, uint16_t loop)
{
ssize_t res;
ssize_t res;
res = write(gif->fd, (uint8_t []) {'!', 0xFF, 0x0B}, 3); OR_ABORT2;
res = write(gif->fd, "NETSCAPE2.0", 11); OR_ABORT2;
res = write(gif->fd, (uint8_t []) {0x03, 0x01}, 2); OR_ABORT2;
res = write_num(gif->fd, loop); OR_ABORT2;
res = write(gif->fd, "\0", 1); OR_ABORT2;
res = write(gif->fd, (uint8_t[])
{
'!', 0xFF, 0x0B}, 3);
OR_ABORT2;
res = write(gif->fd, "NETSCAPE2.0", 11);
OR_ABORT2;
res = write(gif->fd, (uint8_t[])
{
0x03, 0x01}, 2);
OR_ABORT2;
res = write_num(gif->fd, loop);
OR_ABORT2;
res = write(gif->fd, "\0", 1);
OR_ABORT2;
}
/* Add packed key to buffer, updating offset and partial.
* gif->offset holds position to put next *bit*
* gif->partial holds bits to include in next byte */
static void
put_key(ge_GIF *gif, uint16_t key, int key_size)
static void put_key(ge_GIF * gif, uint16_t key, int key_size)
{
int byte_offset, bit_offset, bits_to_write;
ssize_t res;
int byte_offset, bit_offset, bits_to_write;
ssize_t res;
byte_offset = gif->offset / 8;
bit_offset = gif->offset % 8;
gif->partial |= ((uint32_t) key) << bit_offset;
bits_to_write = bit_offset + key_size;
while (bits_to_write >= 8) {
gif->buffer[byte_offset++] = gif->partial & 0xFF;
if (byte_offset == 0xFF) {
res = write(gif->fd, "\xFF", 1); OR_ABORT2;
res = write(gif->fd, gif->buffer, 0xFF); OR_ABORT2;
byte_offset = 0;
}
gif->partial >>= 8;
bits_to_write -= 8;
byte_offset = gif->offset / 8;
bit_offset = gif->offset % 8;
gif->partial |= ((uint32_t) key) << bit_offset;
bits_to_write = bit_offset + key_size;
while (bits_to_write >= 8)
{
gif->buffer[byte_offset++] = gif->partial & 0xFF;
if (byte_offset == 0xFF)
{
res = write(gif->fd, "\xFF", 1);
OR_ABORT2;
res = write(gif->fd, gif->buffer, 0xFF);
OR_ABORT2;
byte_offset = 0;
}
gif->offset = (gif->offset + key_size) % (0xFF * 8);
gif->partial >>= 8;
bits_to_write -= 8;
}
gif->offset = (gif->offset + key_size) % (0xFF * 8);
}
static void end_key(ge_GIF * gif)
{
int byte_offset;
ssize_t res;
byte_offset = gif->offset / 8;
if (gif->offset % 8)
gif->buffer[byte_offset++] = gif->partial & 0xFF;
res = write(gif->fd, (uint8_t[])
{
byte_offset}
, 1);
OR_ABORT2;
res = write(gif->fd, gif->buffer, byte_offset);
OR_ABORT2;
res = write(gif->fd, "\0", 1);
OR_ABORT2;
gif->offset = gif->partial = 0;
}
static void
end_key(ge_GIF *gif)
put_image(ge_GIF * gif, uint16_t w, uint16_t h, uint16_t x, uint16_t y)
{
int byte_offset;
ssize_t res;
int nkeys, key_size, i, j;
Node *node, *child, *root;
ssize_t res;
int degree = 1 << gif->depth;
byte_offset = gif->offset / 8;
if (gif->offset % 8)
gif->buffer[byte_offset++] = gif->partial & 0xFF;
res = write(gif->fd, (uint8_t []) {byte_offset}, 1); OR_ABORT2;
res = write(gif->fd, gif->buffer, byte_offset); OR_ABORT2;
res = write(gif->fd, "\0", 1); OR_ABORT2;
gif->offset = gif->partial = 0;
}
static void
put_image(ge_GIF *gif, uint16_t w, uint16_t h, uint16_t x, uint16_t y)
{
int nkeys, key_size, i, j;
Node *node, *child, *root;
ssize_t res;
int degree = 1 << gif->depth;
res = write(gif->fd, ",", 1); OR_ABORT2;
res = write_num(gif->fd, x); OR_ABORT2;
res = write_num(gif->fd, y); OR_ABORT2;
res = write_num(gif->fd, w); OR_ABORT2;
res = write_num(gif->fd, h); OR_ABORT2;
res = write(gif->fd, (uint8_t []) {0x00, gif->depth}, 2); OR_ABORT2;
root = node = new_trie(degree, &nkeys);
key_size = gif->depth + 1;
put_key(gif, degree, key_size); /* clear code */
for (i = y; i < y+h; i++) {
for (j = x; j < x+w; j++) {
uint8_t pixel = gif->frame[i*gif->w+j] & (degree - 1);
child = node->children[pixel];
if (child) {
node = child;
} else {
put_key(gif, node->key, key_size);
if (nkeys < 0x1000) {
if (nkeys == (1 << key_size))
key_size++;
node->children[pixel] = new_node(nkeys++, degree);
} else {
put_key(gif, degree, key_size); /* clear code */
del_trie(root, degree);
root = node = new_trie(degree, &nkeys);
key_size = gif->depth + 1;
}
node = root->children[pixel];
}
res = write(gif->fd, ",", 1);
OR_ABORT2;
res = write_num(gif->fd, x);
OR_ABORT2;
res = write_num(gif->fd, y);
OR_ABORT2;
res = write_num(gif->fd, w);
OR_ABORT2;
res = write_num(gif->fd, h);
OR_ABORT2;
res = write(gif->fd, (uint8_t[])
{
0x00, gif->depth}, 2);
OR_ABORT2;
root = node = new_trie(degree, &nkeys);
key_size = gif->depth + 1;
put_key(gif, degree, key_size); /* clear code */
for (i = y; i < y + h; i++)
{
for (j = x; j < x + w; j++)
{
uint8_t pixel = gif->frame[i * gif->w + j] & (degree - 1);
child = node->children[pixel];
if (child)
{
node = child;
}
else
{
put_key(gif, node->key, key_size);
if (nkeys < 0x1000)
{
if (nkeys == (1 << key_size))
key_size++;
node->children[pixel] = new_node(nkeys++, degree);
}
else
{
put_key(gif, degree, key_size); /* clear code */
del_trie(root, degree);
root = node = new_trie(degree, &nkeys);
key_size = gif->depth + 1;
}
node = root->children[pixel];
}
}
put_key(gif, node->key, key_size);
put_key(gif, degree + 1, key_size); /* stop code */
end_key(gif);
del_trie(root, degree);
}
put_key(gif, node->key, key_size);
put_key(gif, degree + 1, key_size); /* stop code */
end_key(gif);
del_trie(root, degree);
}
static int
get_bbox(ge_GIF *gif, uint16_t *w, uint16_t *h, uint16_t *x, uint16_t *y)
get_bbox(ge_GIF * gif, uint16_t * w, uint16_t * h, uint16_t * x, uint16_t * y)
{
int i, j, k;
int left, right, top, bottom;
left = gif->w; right = 0;
top = gif->h; bottom = 0;
k = 0;
for (i = 0; i < gif->h; i++) {
for (j = 0; j < gif->w; j++, k++) {
if (gif->frame[k] != gif->back[k]) {
if (j < left) left = j;
if (j > right) right = j;
if (i < top) top = i;
if (i > bottom) bottom = i;
}
}
}
if (left != gif->w && top != gif->h) {
*x = left; *y = top;
*w = right - left + 1;
*h = bottom - top + 1;
return 1;
} else {
return 0;
int i, j, k;
int left, right, top, bottom;
left = gif->w;
right = 0;
top = gif->h;
bottom = 0;
k = 0;
for (i = 0; i < gif->h; i++)
{
for (j = 0; j < gif->w; j++, k++)
{
if (gif->frame[k] != gif->back[k])
{
if (j < left)
left = j;
if (j > right)
right = j;
if (i < top)
top = i;
if (i > bottom)
bottom = i;
}
}
}
if (left != gif->w && top != gif->h)
{
*x = left;
*y = top;
*w = right - left + 1;
*h = bottom - top + 1;
return 1;
}
else
{
return 0;
}
}
/* (From the docs)
@ -267,46 +335,52 @@ get_bbox(ge_GIF *gif, uint16_t *w, uint16_t *h, uint16_t *x, uint16_t *y)
* a minimum of `delay` == 6. If `delay` == 0, no delay information will be stored
* for the frame. This can be used when creating still (single-frame) GIF images.
*/
static void
set_delay(ge_GIF *gif, uint16_t d)
static void set_delay(ge_GIF * gif, uint16_t d)
{
ssize_t res;
ssize_t res;
res = write(gif->fd, (uint8_t []) {'!', 0xF9, 0x04, 0x04}, 4); OR_ABORT2;
res = write_num(gif->fd, d); OR_ABORT2;
res = write(gif->fd, "\0\0", 2); OR_ABORT2;
res = write(gif->fd, (uint8_t[])
{
'!', 0xF9, 0x04, 0x04}, 4);
OR_ABORT2;
res = write_num(gif->fd, d);
OR_ABORT2;
res = write(gif->fd, "\0\0", 2);
OR_ABORT2;
}
void
ge_add_frame(ge_GIF *gif, uint16_t delay)
void ge_add_frame(ge_GIF * gif, uint16_t delay)
{
uint16_t w, h, x, y;
uint8_t *tmp;
uint16_t w, h, x, y;
uint8_t *tmp;
if (delay)
set_delay(gif, delay);
if (gif->nframes == 0) {
w = gif->w;
h = gif->h;
x = y = 0;
} else if (!get_bbox(gif, &w, &h, &x, &y)) {
/* image's not changed; save one pixel just to add delay */
w = h = 1;
x = y = 0;
}
put_image(gif, w, h, x, y);
gif->nframes++;
tmp = gif->back;
gif->back = gif->frame;
gif->frame = tmp;
if (delay)
set_delay(gif, delay);
if (gif->nframes == 0)
{
w = gif->w;
h = gif->h;
x = y = 0;
}
else if (!get_bbox(gif, &w, &h, &x, &y))
{
/* image's not changed; save one pixel just to add delay */
w = h = 1;
x = y = 0;
}
put_image(gif, w, h, x, y);
gif->nframes++;
tmp = gif->back;
gif->back = gif->frame;
gif->frame = tmp;
}
void
ge_close_gif(ge_GIF* gif)
void ge_close_gif(ge_GIF * gif)
{
ssize_t res;
ssize_t res;
res = write(gif->fd, ";", 1); OR_ABORT2;
close(gif->fd);
free(gif);
res = write(gif->fd, ";", 1);
OR_ABORT2;
close(gif->fd);
free(gif);
}

View file

@ -3,22 +3,21 @@
#include <stdint.h>
typedef struct ge_GIF {
uint16_t w, h;
int depth;
int fd;
int offset;
int nframes;
uint8_t *frame, *back;
uint32_t partial;
uint8_t buffer[0xFF];
typedef struct ge_GIF
{
uint16_t w, h;
int depth;
int fd;
int offset;
int nframes;
uint8_t *frame, *back;
uint32_t partial;
uint8_t buffer[0xFF];
} ge_GIF;
ge_GIF *ge_new_gif(
const char *fname, uint16_t width, uint16_t height,
uint8_t *palette, int depth, int loop
);
void ge_add_frame(ge_GIF *gif, uint16_t delay);
void ge_close_gif(ge_GIF* gif);
ge_GIF *ge_new_gif(const char *fname, uint16_t width, uint16_t height,
uint8_t * palette, int depth, int loop);
void ge_add_frame(ge_GIF * gif, uint16_t delay);
void ge_close_gif(ge_GIF * gif);
#endif /* GIFENC_H */

View file

@ -60,10 +60,16 @@ static char *android_locale()
static char android_locale_buf[32];
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mLocaleClass = (*mEnv)->FindClass(mEnv, "java/util/Locale");
jmethodID mGetDefaultMethod = (*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault", "()Ljava/util/Locale;");
jobject mLocaleObject = (*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod);
jmethodID mToStringMethod = (*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString", "()Ljava/lang/String;");
jstring mLocaleString = (*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod);
jmethodID mGetDefaultMethod =
(*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault",
"()Ljava/util/Locale;");
jobject mLocaleObject =
(*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod);
jmethodID mToStringMethod =
(*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString",
"()Ljava/lang/String;");
jstring mLocaleString =
(*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod);
const char *locale = (*mEnv)->GetStringUTFChars(mEnv, mLocaleString, 0);
strcpy(android_locale_buf, locale);
@ -484,7 +490,9 @@ static void show_lang_usage(int exitcode)
const char *const prg = "tuxpaint";
/* FIXME: All this should REALLY be array-based!!! */
fprintf(f, "\n" "Usage: %s [--lang LANGUAGE]\n" "\n" "LANGUAGE may be one of:\n"
fprintf(f,
"\n" "Usage: %s [--lang LANGUAGE]\n" "\n"
"LANGUAGE may be one of:\n"
/* C */ " english american-english\n"
/* ach */ " acholi acoli\n"
/* af */ " afrikaans\n"
@ -505,7 +513,8 @@ static void show_lang_usage(int exitcode)
/* brx */ " bodo\n"
/* nb */ " bokmal\n"
/* bs */ " bosnian\n"
/* pt_BR */ " brazilian brazilian-portuguese portugues-brazilian\n"
/* pt_BR */
" brazilian brazilian-portuguese portugues-brazilian\n"
/* br */ " breton brezhoneg\n"
/* en_GB */ " british british-english\n"
/* bg_BG */ " bulgarian\n"
@ -562,7 +571,8 @@ static void show_lang_usage(int exitcode)
/* mni */ " manipuri-bengali\n"
/* mni@meiteimayek */ " manipuri-meitei-mayek\n"
/* nr */ " marathi\n"
/* es_MX */ " mexican mexican-spanish espanol-mejicano\n"
/* es_MX */
" mexican mexican-spanish espanol-mejicano\n"
/* mn */ " mongolian\n"
/* nr */ " ndebele\n"
/* ne */ " nepali\n"
@ -760,7 +770,8 @@ static void show_locale_usage(FILE * f, const char *const prg)
" wa_BE (Walloon)\n"
" wo_SN (Wolof)\n"
" cy_GB (Welsh Cymraeg)\n"
" xh_ZA (Xhosa)\n" " zam (Zapoteco-Miahuatlan)\n" " zu_ZA (Zulu)\n" "\n", prg);
" xh_ZA (Xhosa)\n" " zam (Zapoteco-Miahuatlan)\n"
" zu_ZA (Zulu)\n" "\n", prg);
}
/**
@ -785,10 +796,10 @@ static int search_int_array(int l, int *array)
int i;
for (i = 0; array[i] != -1; i++)
{
if (array[i] == l)
return 1;
}
{
if (array[i] == l)
return 1;
}
return 0;
}
@ -804,18 +815,19 @@ static void ctype_utf8(void)
#ifndef _WIN32
/* FIXME: should this iterate over more locales?
A zapotec speaker may have es_MX.UTF-8 available but not have en_US.UTF-8 for example */
const char *names[] = { "en_US.UTF8", "en_US.UTF-8", "UTF8", "UTF-8", "C.UTF-8" };
const char *names[] =
{ "en_US.UTF8", "en_US.UTF-8", "UTF8", "UTF-8", "C.UTF-8" };
int i = sizeof(names) / sizeof(names[0]);
for (;;)
{
if (iswprint((wchar_t) 0xf7)) // division symbol -- which is in Latin-1 :-/
return;
if (--i < 0)
break;
setlocale(LC_CTYPE, names[i]);
setlocale(LC_MESSAGES, names[i]);
}
{
if (iswprint((wchar_t) 0xf7)) // division symbol -- which is in Latin-1 :-/
return;
if (--i < 0)
break;
setlocale(LC_CTYPE, names[i]);
setlocale(LC_MESSAGES, names[i]);
}
fprintf(stderr, "Failed to find a locale with iswprint() working!\n");
#endif
}
@ -828,13 +840,14 @@ static void ctype_utf8(void)
*/
static const char *language_to_locale(const char *langstr)
{
int i = sizeof language_to_locale_array / sizeof language_to_locale_array[0];
int i =
sizeof language_to_locale_array / sizeof language_to_locale_array[0];
while (i--)
{
if (!strcmp(langstr, language_to_locale_array[i].language))
return language_to_locale_array[i].locale;
}
{
if (!strcmp(langstr, language_to_locale_array[i].language))
return language_to_locale_array[i].locale;
}
if (strcmp(langstr, "help") == 0 || strcmp(langstr, "list") == 0)
show_lang_usage(0);
fprintf(stderr, "%s is an invalid language\n", langstr);
@ -854,34 +867,37 @@ static const char *language_to_locale(const char *langstr)
*/
static const char *locale_to_closest_locale(const char *inlocale)
{
const int numlocale = sizeof(language_to_locale_array) / sizeof(language_to_locale_array[0]);
const char* outlocale = NULL;
const int numlocale =
sizeof(language_to_locale_array) / sizeof(language_to_locale_array[0]);
const char *outlocale = NULL;
int outlocale_score = 0;
int i = 0;
int j = 0;
/* find the locale with the longest string match */
for (i = 0; i < numlocale; i++)
{
const char *candidate = language_to_locale_array[i].locale;
for (j = 0; j < (int) strlen(inlocale) && j < (int) strlen(candidate);
j++)
{
const char* candidate = language_to_locale_array[i].locale;
for (j = 0; j < (int) strlen(inlocale) && j < (int) strlen(candidate); j++)
{
if(inlocale[j] != candidate[j]) break;
}
if (j > outlocale_score)
{
outlocale = candidate;
outlocale_score = j;
}
if (inlocale[j] != candidate[j])
break;
}
if (j > outlocale_score)
{
outlocale = candidate;
outlocale_score = j;
}
}
/* locale must match at least two characters */
if (outlocale_score < 2)
{
outlocale = "";
}
{
outlocale = "";
}
return outlocale;
}
@ -925,68 +941,70 @@ static void set_langint_from_locale_string(const char *restrict loc)
*dot = '\0';
if (cntrycode)
{
ccodeaux = strdup(cntrycode);
*cntrycode = '\0';
}
{
ccodeaux = strdup(cntrycode);
*cntrycode = '\0';
}
if (at)
{
ataux = strdup(at);
*at = '\0';
if (cntrycode)
{
ataux = strdup(at);
*at = '\0';
if (cntrycode)
{
/* ll_CC@variant */
//if (found == 0) printf("ll_CC@variant check\n");
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
langint = i;
found = 1;
}
}
}
/* ll@variant */
//if (found == 0) printf("ll@variant check\n");
snprintf(straux, 255, "%s%s", baseloc, ataux);
/* ll_CC@variant */
//if (found == 0) printf("ll_CC@variant check\n");
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i])
&& !strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
langint = i;
found = 1;
}
langint = i;
found = 1;
}
}
}
/* ll@variant */
//if (found == 0) printf("ll@variant check\n");
snprintf(straux, 255, "%s%s", baseloc, ataux);
len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i])
&& !strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
langint = i;
found = 1;
}
}
}
if (cntrycode)
{
/* ll_CC */
//if (found == 0) printf("ll_CC check\n");
snprintf(straux, 255, "%s%s", baseloc, ccodeaux);
len_baseloc = strlen(straux);
/* Which, if any, of the locales is it? */
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
/* ll_CC */
//if (found == 0) printf("ll_CC check\n");
snprintf(straux, 255, "%s%s", baseloc, ccodeaux);
len_baseloc = strlen(straux);
/* Which, if any, of the locales is it? */
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) &&
!strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
}
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) &&
!strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
}
}
/* ll */
// if (found == 0) printf("ll check\n");
@ -994,14 +1012,15 @@ static void set_langint_from_locale_string(const char *restrict loc)
/* Which, if any, of the locales is it? */
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i])
&& !strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
langint = i;
found = 1;
}
}
/* Last resort, we should never arrive here, this check depends
on the right order in lang_prefixes[]
@ -1011,14 +1030,14 @@ static void set_langint_from_locale_string(const char *restrict loc)
// printf("Language still not found: loc= %s Trying reverse check as last resource...\n", loc);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
langint = i;
found = 1;
}
}
// printf("langint %i, lang_ext %s\n", langint, lang_prefixes[langint]);
free(baseloc);
@ -1048,7 +1067,8 @@ static void mysetenv(const char *name, const char *value)
char *str;
#endif
if (name != NULL && value != NULL) {
if (name != NULL && value != NULL)
{
#ifdef HAVE_SETENV
setenv(name, value, 1);
#else
@ -1058,11 +1078,12 @@ static void mysetenv(const char *name, const char *value)
sprintf(str, "%s=%s", name, value);
putenv(str);
#endif
} else {
fprintf(stderr, "WARNING: mysetenv() received a null pointer. name=%s, value=%s\n",
(name == NULL ? "NULL" : name),
(value == NULL ? "NULL" : value)
);
}
else
{
fprintf(stderr,
"WARNING: mysetenv() received a null pointer. name=%s, value=%s\n",
(name == NULL ? "NULL" : name), (value == NULL ? "NULL" : value));
}
}
@ -1074,7 +1095,8 @@ static void mysetenv(const char *name, const char *value)
* @return The Y-nudge value for font rendering in the language.
*/
static int set_current_language(const char *restrict loc, int * ptr_num_wished_langs)
static int set_current_language(const char *restrict loc,
int *ptr_num_wished_langs)
{
int i;
int j = 0;
@ -1087,66 +1109,67 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
*ptr_num_wished_langs = 0;
if (strlen(loc) > 0)
{
/* Got command line or config file language */
DEBUG_PRINTF("Language via config: %s\n", loc);
mysetenv("LANGUAGE", loc);
}
{
/* Got command line or config file language */
DEBUG_PRINTF("Language via config: %s\n", loc);
mysetenv("LANGUAGE", loc);
}
else
{
DEBUG_PRINTF("Language NOT set via config\n");
{
DEBUG_PRINTF("Language NOT set via config\n");
/* Find what language to use from env vars */
env = getenv("LANGUAGE");
if (env == NULL || env[0] == '\0')
{
env = getenv("LC_ALL");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language via LC_ALL: %s\n", getenv("LC_ALL"));
mysetenv("LANGUAGE", getenv("LC_ALL"));
}
else
{
env = getenv("LC_MESSAGES");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language via LC_MESSAGES: %s\n", getenv("LC_MESSAGES"));
mysetenv("LANGUAGE", getenv("LC_MESSAGES"));
}
else
{
env = getenv("LANG");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language via LANG: %s\n", getenv("LANG"));
mysetenv("LANGUAGE", getenv("LANG"));
}
else
{
DEBUG_PRINTF("No language set!\n");
}
}
}
}
/* Find what language to use from env vars */
env = getenv("LANGUAGE");
if (env == NULL || env[0] == '\0')
{
env = getenv("LC_ALL");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language via LC_ALL: %s\n", getenv("LC_ALL"));
mysetenv("LANGUAGE", getenv("LC_ALL"));
}
else
{
env = getenv("LC_MESSAGES");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language was set to '%s'\n", getenv("LANGUAGE"));
}
DEBUG_PRINTF("Language via LC_MESSAGES: %s\n",
getenv("LC_MESSAGES"));
mysetenv("LANGUAGE", getenv("LC_MESSAGES"));
}
else
{
env = getenv("LANG");
if (env != NULL && env[0] != '\0')
{
DEBUG_PRINTF("Language via LANG: %s\n", getenv("LANG"));
mysetenv("LANGUAGE", getenv("LANG"));
}
else
{
DEBUG_PRINTF("No language set!\n");
}
}
}
}
else
{
DEBUG_PRINTF("Language was set to '%s'\n", getenv("LANGUAGE"));
}
}
oldloc = strdup(loc);
/* First set the locale according to the environment, then try to overwrite with loc,
after that, ctype_utf8() call will test the compatibility with utf8 and try to load
a different locale if the resulting one is not compatible. */
DEBUG_PRINTF("Locale BEFORE is: %s\n", setlocale(LC_ALL, NULL)); //EP
DEBUG_PRINTF("Locale BEFORE is: %s\n", setlocale(LC_ALL, NULL)); //EP
setlocale(LC_ALL, "");
setlocale(LC_ALL, loc);
ctype_utf8();
DEBUG_PRINTF("Locale AFTER is: %s\n", setlocale(LC_ALL, NULL)); //EP
DEBUG_PRINTF("Locale AFTER is: %s\n", setlocale(LC_ALL, NULL)); //EP
#ifdef BDIST_WIN32
// FIXME: After the update of MinGW/MSYS2 in January 2022, gettext() no longer find
@ -1177,77 +1200,80 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
loc = setlocale(LC_MESSAGES, NULL);
if (oldloc && loc && strcmp(oldloc, "") != 0 && strcmp(loc, oldloc) != 0)
{
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */
{
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */
/* Albert's comments from December 2009:
gettext() won't even bother to look up messages unless it
is totally satisfied that you are using one of the locales that
it ships with! Make gettext() unhappy, and it'll switch to the
lobotomized 7-bit Linux "C" locale just to spite you.
/* Albert's comments from December 2009:
gettext() won't even bother to look up messages unless it
is totally satisfied that you are using one of the locales that
it ships with! Make gettext() unhappy, and it'll switch to the
lobotomized 7-bit Linux "C" locale just to spite you.
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
You can confuse gettext() into mostly behaving. For example, a
user could pick a random UTF-8 locale and change the messages.
In that case, Tux Paint thinks it's in the other locale but the
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
or set it to random nonsense. Yeah, Tux Paint will think it's in
a French locale, but the messages will be Zapotec nonetheless.
You can confuse gettext() into mostly behaving. For example, a
user could pick a random UTF-8 locale and change the messages.
In that case, Tux Paint thinks it's in the other locale but the
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
or set it to random nonsense. Yeah, Tux Paint will think it's in
a French locale, but the messages will be Zapotec nonetheless.
Maybe it's time to give up on gettext().
Maybe it's time to give up on gettext().
[see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ]
*/
[see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ]
*/
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */
mysetenv("LANGUAGE", oldloc);
set_langint_from_locale_string(oldloc);
}
mysetenv("LANGUAGE", oldloc);
set_langint_from_locale_string(oldloc);
}
else
{
{
#ifdef _WIN32
if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", loc);
if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", loc);
#endif
if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", "C");
}
if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", "C");
}
env_language = strdup(getenv("LANGUAGE"));
if (*env_language)
{
env_language_lang = strtok(env_language, ":");
while (env_language_lang != NULL)
{
env_language_lang = strtok(env_language, ":");
while (env_language_lang != NULL)
num_wished_langs++;
set_langint_from_locale_string(env_language_lang);
wished_langs[j].langint = langint;
wished_langs[j].lang_prefix = lang_prefixes[langint];
wished_langs[j].need_own_font =
search_int_array(langint, lang_use_own_font);
wished_langs[j].need_right_to_left =
search_int_array(langint, lang_use_right_to_left);
wished_langs[j].need_right_to_left_word =
search_int_array(langint, lang_use_right_to_left_word);
for (i = 0; lang_y_nudge[i][0] != -1; i++)
{
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
if (lang_y_nudge[i][0] == langint)
{
num_wished_langs++;
set_langint_from_locale_string(env_language_lang);
wished_langs[j].langint = langint;
wished_langs[j].lang_prefix = lang_prefixes[langint];
wished_langs[j].need_own_font = search_int_array(langint, lang_use_own_font);
wished_langs[j].need_right_to_left = search_int_array(langint, lang_use_right_to_left);
wished_langs[j].need_right_to_left_word = search_int_array(langint, lang_use_right_to_left_word);
for (i = 0; lang_y_nudge[i][0] != -1; i++)
{
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
if (lang_y_nudge[i][0] == langint)
{
wished_langs[j].lang_y_nudge = lang_y_nudge[i][1];
break;
}
}
j++;
env_language_lang = strtok(NULL, ":");
wished_langs[j].lang_y_nudge = lang_y_nudge[i][1];
break;
}
if (*env_language)
free(env_language);
}
j++;
env_language_lang = strtok(NULL, ":");
}
if (*env_language)
free(env_language);
}
// set_langint_from_locale_string(loc);
@ -1264,13 +1290,15 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
#ifdef DEBUG
fprintf(stderr, "DEBUG: Language is %s (%d) %s/%s\n",
lang_prefix, langint, need_right_to_left ? "(RTL)" : "", need_right_to_left_word ? "(RTL words)" : "");
lang_prefix, langint, need_right_to_left ? "(RTL)" : "",
need_right_to_left_word ? "(RTL words)" : "");
fflush(stderr);
#endif
free(oldloc);
DEBUG_PRINTF("lang_prefixes[%d] is \"%s\"\n", get_current_language(), lang_prefixes[get_current_language()]);
DEBUG_PRINTF("lang_prefixes[%d] is \"%s\"\n", get_current_language(),
lang_prefixes[get_current_language()]);
*ptr_num_wished_langs = num_wished_langs;
@ -1289,27 +1317,28 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
* @param int * a place to return the number of languages we want to use, when scanning stamp descriptions
* @return Y-nudge
*/
int setup_i18n(const char *restrict lang, const char *restrict locale, int * num_wished_langs)
int setup_i18n(const char *restrict lang, const char *restrict locale,
int *num_wished_langs)
{
DEBUG_PRINTF("lang %p, locale %p\n", lang, locale);
DEBUG_PRINTF("lang \"%s\", locale \"%s\"\n", lang, locale);
if (locale)
{
if (!strcmp(locale, "help"))
{
if (!strcmp(locale, "help"))
{
show_locale_usage(stdout, "tuxpaint");
exit(0);
}
show_locale_usage(stdout, "tuxpaint");
exit(0);
}
}
else
{
#if defined(__APPLE__)
locale = locale_to_closest_locale(apple_locale());
#else
locale = "";
#endif
}
{
#if defined(__APPLE__)
locale = locale_to_closest_locale(apple_locale());
#else
locale = "";
#endif
}
if (lang)
locale = language_to_locale(lang);

View file

@ -206,7 +206,8 @@ extern w_langs wished_langs[255];
/* Function prototypes: */
int get_current_language(void);
int setup_i18n(const char *restrict lang, const char *restrict locale, int * ptr_num_wished_languages) MUST_CHECK;
int setup_i18n(const char *restrict lang, const char *restrict locale,
int *ptr_num_wished_languages) MUST_CHECK;
#ifdef NO_SDLPANGO
int smash_i18n(void) MUST_CHECK;

1987
src/im.c

File diff suppressed because it is too large Load diff

View file

@ -25,8 +25,8 @@
#include "SDL.h"
int DisplayPageSetup(const SDL_Surface* surface);
const char* SurfacePrint(const SDL_Surface* surface, int showDialog);
int DisplayPageSetup(const SDL_Surface * surface);
const char *SurfacePrint(const SDL_Surface * surface, int showDialog);
#endif /* __IOS_PRINT_H__ */

File diff suppressed because it is too large Load diff

View file

@ -105,13 +105,13 @@ typedef struct osk_keyboard
char *name; /* The name of the keyboard */
char *keyboard_list; /* The names of the keyboards allowed from this one */
SDL_Surface *surface; /* The surface containing the current layout's keyboard */
/* The surfaces containing the current layout's button backgrounds*/
/* The surfaces containing the current layout's button backgrounds */
SDL_Surface *button_up;
SDL_Surface *button_down;
SDL_Surface *button_off;
SDL_Surface *button_nav;
SDL_Surface *button_hold;
/* The surfaces containing some symbols for the current layout's buttons */
/* The surfaces containing some symbols for the current layout's buttons */
SDL_Surface *oskdel; /* delete arrow */
SDL_Surface *osktab; /* Tab arrows */
SDL_Surface *oskenter; /* Return hook/arrow */
@ -133,7 +133,7 @@ typedef struct osk_keyboard
int composed_type; /* 1 if the value stored in composed is yet the unicode value */
osk_composenode *composing; /* The node in the middle of a compose sequence */
osk_key *last_key_pressed; /* The last key pressed */
SDL_Surface * canvas_ptr; /* Canvas drawing surface, for bpp and sizing needs when cycling through keyboard layouts */
SDL_Surface *canvas_ptr; /* Canvas drawing surface, for bpp and sizing needs when cycling through keyboard layouts */
/* Large and small buttons, to pass back to osk_create() when cycling through keyboard layouts */
SDL_Surface *BLANK_button_up;
SDL_Surface *BLANK_button_down;
@ -147,17 +147,23 @@ typedef struct osk_keyboard
SDL_Surface *BLANK_oskshift;
} on_screen_keyboard;
struct osk_keyboard *osk_create(char * layout_name, SDL_Surface * canvas,
SDL_Surface * BLANK_button_up, SDL_Surface * BLANK_button_down,
SDL_Surface * BLANK_button_off, SDL_Surface * BLANK_button_nav,
struct osk_keyboard *osk_create(char *layout_name, SDL_Surface * canvas,
SDL_Surface * BLANK_button_up,
SDL_Surface * BLANK_button_down,
SDL_Surface * BLANK_button_off,
SDL_Surface * BLANK_button_nav,
SDL_Surface * BLANK_button_hold,
SDL_Surface * BLANK_oskdel, SDL_Surface * BLANK_osktab, SDL_Surface * BLANK_oskenter,
SDL_Surface * BLANK_oskcapslock, SDL_Surface * BLANK_oskshift,
SDL_Surface * BLANK_oskdel,
SDL_Surface * BLANK_osktab,
SDL_Surface * BLANK_oskenter,
SDL_Surface * BLANK_oskcapslock,
SDL_Surface * BLANK_oskshift,
int disable_change);
struct osk_layout *osk_load_layout(char *layout_name);
void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h, char *layout_buttons, char *layout_labels,
void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h,
char *layout_buttons, char *layout_labels,
char *layout_keycodes);
void osk_reset(on_screen_keyboard * osk);
struct osk_keyboard *osk_clicked(on_screen_keyboard * keyboard, int x, int y);

View file

@ -95,5 +95,5 @@ struct cfginfo
#define CFGINFO_MAXOFFSET (sizeof(struct cfginfo))
extern void parse_one_option(struct cfginfo *restrict tmpcfg, const char *str, const char *opt,
const char *restrict src);
extern void parse_one_option(struct cfginfo *restrict tmpcfg, const char *str,
const char *opt, const char *restrict src);

View file

@ -37,19 +37,21 @@ static void putpixel8(SDL_Surface * surface, int x, int y, Uint32 pixel)
Uint8 *p;
/* Assuming the X/Y values are within the bounds of this surface... */
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
x); /* Go in X pixels */
if (likely
(likely((unsigned) x < (unsigned) surface->w)
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
x); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
*p = pixel;
}
*p = pixel;
}
}
/* Draw a single pixel into the surface: */
@ -58,19 +60,21 @@ static void putpixel16(SDL_Surface * surface, int x, int y, Uint32 pixel)
Uint8 *p;
/* Assuming the X/Y values are within the bounds of this surface... */
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 2)); /* Go in X pixels */
if (likely
(likely((unsigned) x < (unsigned) surface->w)
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 2)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
*(Uint16 *) p = pixel;
}
*(Uint16 *) p = pixel;
}
}
/* Draw a single pixel into the surface: */
@ -79,31 +83,33 @@ static void putpixel24(SDL_Surface * surface, int x, int y, Uint32 pixel)
Uint8 *p;
/* Assuming the X/Y values are within the bounds of this surface... */
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
if (likely
(likely((unsigned) x < (unsigned) surface->w)
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 3)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 3)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
}
}
/* Draw a single pixel into the surface: */
@ -112,19 +118,21 @@ static void putpixel32(SDL_Surface * surface, int x, int y, Uint32 pixel)
Uint8 *p;
/* Assuming the X/Y values are within the bounds of this surface... */
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 4)); /* Go in X pixels */
if (likely
(likely((unsigned) x < (unsigned) surface->w)
&& likely((unsigned) y < (unsigned) surface->h)))
{
// Set a pointer to the exact location in memory of the pixel
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
(y * surface->pitch) + /* Go down Y lines */
(x * 4)); /* Go in X pixels */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
/* Set the (correctly-sized) piece of data in the surface's RAM
* to the pixel value sent in: */
*(Uint32 *) p = pixel; // 32-bit display
}
*(Uint32 *) p = pixel; // 32-bit display
}
}
/* Get a pixel: */
@ -133,9 +141,9 @@ static Uint32 getpixel8(SDL_Surface * surface, int x, int y)
Uint8 *p;
/* get the X/Y values within the bounds of this surface */
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
x = (x < 0) ? 0 : surface->w - 1;
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
y = (y < 0) ? 0 : surface->h - 1;
/* Set a pointer to the exact location in memory of the pixel
@ -159,9 +167,9 @@ static Uint32 getpixel16(SDL_Surface * surface, int x, int y)
Uint8 *p;
/* get the X/Y values within the bounds of this surface */
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
x = (x < 0) ? 0 : surface->w - 1;
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
y = (y < 0) ? 0 : surface->h - 1;
/* Set a pointer to the exact location in memory of the pixel
@ -186,9 +194,9 @@ static Uint32 getpixel24(SDL_Surface * surface, int x, int y)
Uint32 pixel;
/* get the X/Y values within the bounds of this surface */
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
x = (x < 0) ? 0 : surface->w - 1;
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
y = (y < 0) ? 0 : surface->h - 1;
/* Set a pointer to the exact location in memory of the pixel
@ -219,9 +227,9 @@ static Uint32 getpixel32(SDL_Surface * surface, int x, int y)
Uint8 *p;
/* get the X/Y values within the bounds of this surface */
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
x = (x < 0) ? 0 : surface->w - 1;
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
y = (y < 0) ? 0 : surface->h - 1;
/* Set a pointer to the exact location in memory of the pixel
@ -239,11 +247,11 @@ static Uint32 getpixel32(SDL_Surface * surface, int x, int y)
return *(Uint32 *) p; // 32-bit display
}
void (*putpixels[]) (SDL_Surface *, int, int, Uint32) =
{
putpixel8, putpixel8, putpixel16, putpixel24, putpixel32};
void (*putpixels[])(SDL_Surface *, int, int, Uint32) = {
putpixel8, putpixel8, putpixel16, putpixel24, putpixel32
};
Uint32(*getpixels[])(SDL_Surface *, int, int) =
{
getpixel8, getpixel8, getpixel16, getpixel24, getpixel32};
Uint32(*getpixels[])(SDL_Surface *, int, int) = {
getpixel8, getpixel8, getpixel16, getpixel24, getpixel32
};

View file

@ -32,7 +32,7 @@
#include "SDL.h"
extern void (*putpixels[]) (SDL_Surface *, int, int, Uint32);
extern void (*putpixels[])(SDL_Surface *, int, int, Uint32);
extern Uint32(*getpixels[]) (SDL_Surface *, int, int);
#endif

View file

@ -24,21 +24,21 @@
#if defined(__APPLE__)
#include <TargetConditionals.h>
#include <TargetConditionals.h>
/*
* MAC test must be last because it tests true even on iOS / tvOS / watchOS.
*/
* MAC test must be last because it tests true even on iOS / tvOS / watchOS.
*/
#if TARGET_OS_IOS || TARGET_OS_IPHONE || TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR || TARGET_OS_EMBEDDED
#define __IOS__ 1
#elif TARGET_OS_OSX || TARGET_OS_MAC
#define __MACOS__ 1
#else
#define __OTHER_APPLE__ 1
#if TARGET_OS_IOS || TARGET_OS_IPHONE || TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR || TARGET_OS_EMBEDDED
#define __IOS__ 1
#elif TARGET_OS_OSX || TARGET_OS_MAC
#define __MACOS__ 1
#else
#define __OTHER_APPLE__ 1
#warning "Unsupported Apple platform, will build on a best-effort basis"
#endif
#warning "Unsupported Apple platform, will build on a best-effort basis"
#endif
#endif /* __APPLE__ */

View file

@ -48,70 +48,72 @@ static int old_sound[4] = { -1, -1, -1, -1 };
* (low values, near the top of the window, are quieter), or
* SNDDIST_NEAR for full volume
*/
void playsound(SDL_Surface * screen, int chan, int s, int override, int x, int y)
void playsound(SDL_Surface * screen, int chan, int s, int override, int x,
int y)
{
#ifndef NOSOUND
int left, dist;
if (!mute && use_sound && s != SND_NONE)
{
{
#ifdef DEBUG
printf("playsound #%d in channel %d, pos (%d,%d), %soverride, ptr=%p\n", s, chan, x, y, override ? "" : "no ",
sounds[s]);
printf("playsound #%d in channel %d, pos (%d,%d), %soverride, ptr=%p\n",
s, chan, x, y, override ? "" : "no ", sounds[s]);
fflush(stdout);
#endif
if (override || !Mix_Playing(chan))
{
Mix_PlayChannel(chan, sounds[s], 0);
old_sound[chan] = s;
}
if (old_sound[chan] == s)
{
if (y == SNDDIST_NEAR)
dist = 0;
else
{
if (y < 0)
y = 0;
else if (y >= screen->h - 1)
y = screen->h - 1;
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
}
if (use_stereo)
{
if (x == SNDPOS_LEFT)
left = 255 - dist;
else if (x == SNDPOS_CENTER)
left = (255 - dist) / 2;
else if (x == SNDPOS_RIGHT)
left = 0;
else
{
if (x < 0)
x = 0;
else if (x >= screen->w)
x = screen->w - 1;
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
}
}
else
{
/* Stereo disabled; treat everything like a SNDPOS_CENTER
(equal amount in each of the left/right channels) */
left = (255 - dist) / 2;
}
#ifdef DEBUG
printf("Panning of sound #%d in channel %d, left=%d, right=%d\n", s,
chan, left, (255 - dist) - left);
fflush(stdout);
#endif
if (override || !Mix_Playing(chan))
{
Mix_PlayChannel(chan, sounds[s], 0);
old_sound[chan] = s;
}
if (old_sound[chan] == s)
{
if (y == SNDDIST_NEAR)
dist = 0;
else
{
if (y < 0)
y = 0;
else if (y >= screen->h - 1)
y = screen->h - 1;
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
}
if (use_stereo)
{
if (x == SNDPOS_LEFT)
left = 255 - dist;
else if (x == SNDPOS_CENTER)
left = (255 - dist) / 2;
else if (x == SNDPOS_RIGHT)
left = 0;
else
{
if (x < 0)
x = 0;
else if (x >= screen->w)
x = screen->w - 1;
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
}
}
else
{
/* Stereo disabled; treat everything like a SNDPOS_CENTER
(equal amount in each of the left/right channels) */
left = (255 - dist) / 2;
}
#ifdef DEBUG
printf("Panning of sound #%d in channel %d, left=%d, right=%d\n", s, chan, left, (255 - dist) - left);
fflush(stdout);
#endif
Mix_SetPanning(chan, left, (255 - dist) - left);
}
Mix_SetPanning(chan, left, (255 - dist) - left);
}
}
#endif
}

View file

@ -37,6 +37,7 @@
extern Mix_Chunk *sounds[NUM_SOUNDS];
extern int mute, use_sound, use_stereo;
void playsound(SDL_Surface * screen, int chan, int s, int override, int x, int y);
void playsound(SDL_Surface * screen, int chan, int s, int override, int x,
int y);
#endif

View file

@ -69,17 +69,18 @@
static int f2int(float f)
{
return ((int)f);
return ((int) f);
}
static int f2dec(float f)
{
return (int)((f - f2int(f)) * 100);
return (int) ((f - f2int(f)) * 100);
}
/* Actually save the PostScript data to the file stream: */
int do_ps_save(FILE * fi,
const char *restrict const fname, SDL_Surface * surf, const char *restrict pprsize, int is_pipe)
const char *restrict const fname, SDL_Surface * surf,
const char *restrict pprsize, int is_pipe)
{
const struct paper *ppr;
int img_w = surf->w;
@ -93,7 +94,8 @@ int do_ps_save(FILE * fi,
Uint8 r, g, b;
char buf[256];
Uint32(*getpixel) (SDL_Surface *, int, int) = getpixels[surf->format->BytesPerPixel];
Uint32(*getpixel) (SDL_Surface *, int, int) =
getpixels[surf->format->BytesPerPixel];
int printed_img_w, printed_img_h;
time_t t = time(NULL);
int rotate;
@ -103,35 +105,35 @@ int do_ps_save(FILE * fi,
/* Determine paper size: */
if (pprsize == NULL)
{
/* User did not request a specific paper size (on command-line or
in config file), ask the system. It will return either their
$PAPER env. var., the value from /etc/papersize, or NULL: */
pprsize = systempapername();
if (pprsize == NULL)
{
/* User did not request a specific paper size (on command-line or
in config file), ask the system. It will return either their
$PAPER env. var., the value from /etc/papersize, or NULL: */
/* No setting, env. var. or /etc/ file; use the default! */
pprsize = systempapername();
if (pprsize == NULL)
{
/* No setting, env. var. or /etc/ file; use the default! */
pprsize = defaultpapername();
pprsize = defaultpapername();
#ifdef DEBUG
printf("Using default paper\n");
#endif
}
#ifdef DEBUG
else
{
printf("Using system paper\n");
}
printf("Using default paper\n");
#endif
}
#ifdef DEBUG
else
{
printf("Using system paper\n");
}
#endif
}
#ifdef DEBUG
else
{
printf("Using user paper\n");
}
{
printf("Using user paper\n");
}
#endif
#ifdef DEBUG
@ -147,7 +149,8 @@ int do_ps_save(FILE * fi,
ppr_h = paperpsheight(ppr);
#ifdef DEBUG
printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, (float)ppr_w / 72.0, (float)ppr_h / 72.0);
printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h,
(float) ppr_w / 72.0, (float) ppr_h / 72.0);
#endif
paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25
@ -155,18 +158,19 @@ int do_ps_save(FILE * fi,
/* Determine whether it's best to rotate the image: */
if ((ppr_w >= ppr_h && img_w >= img_h) || (ppr_w <= ppr_h && img_w <= img_h))
{
rotate = 0;
r_img_w = img_w;
r_img_h = img_h;
}
if ((ppr_w >= ppr_h && img_w >= img_h)
|| (ppr_w <= ppr_h && img_w <= img_h))
{
rotate = 0;
r_img_w = img_w;
r_img_h = img_h;
}
else
{
rotate = 1;
r_img_w = img_h;
r_img_h = img_w;
}
{
rotate = 1;
r_img_w = img_h;
r_img_h = img_w;
}
#ifdef DEBUG
printf("Image is %d x %d\n", img_w, img_h);
@ -177,13 +181,16 @@ int do_ps_save(FILE * fi,
/* Determine scale: */
scale = my_min(((float)(ppr_w - (MARGIN * 2)) / (float)r_img_w), ((float)(ppr_h - (MARGIN * 2)) / (float)r_img_h));
scale =
my_min(((float) (ppr_w - (MARGIN * 2)) / (float) r_img_w),
((float) (ppr_h - (MARGIN * 2)) / (float) r_img_h));
printed_img_w = r_img_w * scale;
printed_img_h = r_img_h * scale;
#ifdef DEBUG
printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w, printed_img_h);
printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w,
printed_img_h);
#endif
@ -209,7 +216,8 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%Pages: 1\n");
fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int)(ppr_w + 0.5), (int)(ppr_h + 0.5));
fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int) (ppr_w + 0.5),
(int) (ppr_h + 0.5));
fprintf(fi, "%%%%EndComments\n");
@ -228,20 +236,23 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%Page: 1 1\n");
fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", ppr_w, ppr_h);
fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n",
ppr_w, ppr_h);
fprintf(fi, "gsave\n");
/* 'translate' moves the user space origin to a new position with
respect to the current page, leaving the orientation of the axes and
the unit lengths unchanged. */
fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x), f2int(tlate_y), f2dec(tlate_y));
fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x),
f2int(tlate_y), f2dec(tlate_y));
/* 'scale' modifies the unit lengths independently along the current
x and y axes, leaving the origin location and the orientation of the
axes unchanged. */
fprintf(fi, "%d.%02d %d.%02d scale\n",
f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h), f2dec(printed_img_h));
f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h),
f2dec(printed_img_h));
/* Rotate the image */
if (rotate)
@ -261,23 +272,23 @@ int do_ps_save(FILE * fi,
cur_line_len = 0;
for (y = 0; y < img_h; y++)
{
for (plane = 0; plane < 3; plane++)
{
for (plane = 0; plane < 3; plane++)
{
for (x = 0; x < img_w; x++)
{
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
for (x = 0; x < img_w; x++)
{
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
cur_line_len++;
if (cur_line_len >= 30)
{
fprintf(fi, "\n");
cur_line_len = 0;
}
}
cur_line_len++;
if (cur_line_len >= 30)
{
fprintf(fi, "\n");
cur_line_len = 0;
}
}
}
}
fprintf(fi, "\n");
fprintf(fi, "grestore\n");
@ -286,74 +297,74 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%EOF\n");
if (!is_pipe)
{
fclose(fi);
return 1;
}
{
fclose(fi);
return 1;
}
else
{
pid_t child_pid, w;
int status;
{
pid_t child_pid, w;
int status;
#ifdef __APPLE__
/* macOS does not always reset errno so Tux Paint thinks print never
* succeeds - let's reset before calling pclose() on macOS */
errno = 0;
/* macOS does not always reset errno so Tux Paint thinks print never
* succeeds - let's reset before calling pclose() on macOS */
errno = 0;
#endif
child_pid = pclose(fi);
child_pid = pclose(fi);
#ifdef DEBUG
printf("pclose returned %d\n", child_pid);
fflush(stdout);
printf("errno = %d\n", errno);
fflush(stdout);
printf("pclose returned %d\n", child_pid);
fflush(stdout);
printf("errno = %d\n", errno);
fflush(stdout);
#endif
if (child_pid < 0 || (errno != 0 && errno != EAGAIN))
{ /* FIXME: This right? */
return 0;
}
else if (child_pid == 0)
{
return 1;
}
do
{
w = waitpid(child_pid, &status, 0);
#ifdef DEBUG
if (w == -1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status))
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("killed by signal %d\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status))
{
printf("stopped by signal %d\n", WSTOPSIG(status));
}
else if (WIFCONTINUED(status))
{
printf("continued\n");
}
#endif
}
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
return 0;
if (child_pid < 0 || (errno != 0 && errno != EAGAIN))
{ /* FIXME: This right? */
return 0;
}
else if (child_pid == 0)
{
return 1;
}
do
{
w = waitpid(child_pid, &status, 0);
#ifdef DEBUG
if (w == -1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status))
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("killed by signal %d\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status))
{
printf("stopped by signal %d\n", WSTOPSIG(status));
}
else if (WIFCONTINUED(status))
{
printf("continued\n");
}
#endif
}
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
return 0;
return 1;
}
}
#endif

View file

@ -79,7 +79,8 @@
#ifdef PRINTMETHOD_PS
int do_ps_save(FILE * fi,
const char *restrict const fname, SDL_Surface * surf, const char *restrict pprsize, int is_pipe);
const char *restrict const fname, SDL_Surface * surf,
const char *restrict pprsize, int is_pipe);
#endif

View file

@ -39,7 +39,8 @@ int progress_bar_disabled, prog_bar_ctr;
*
* @param screen Screen surface
*/
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer)
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer)
{
SDL_Rect dest, src, r;
int x;
@ -51,34 +52,36 @@ void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture, SDL_Rendere
newtime = SDL_GetTicks();
if (newtime > oldtime + 15) /* trying not to eat some serious CPU time! */
{
for (x = 0; x < screen->w; x = x + 65)
{
for (x = 0; x < screen->w; x = x + 65)
{
src.x = 65 - (prog_bar_ctr % 65);
src.y = 0;
src.w = 65;
src.h = 24;
src.x = 65 - (prog_bar_ctr % 65);
src.y = 0;
src.w = 65;
src.h = 24;
dest.x = x;
dest.y = screen->h - 24;
dest.x = x;
dest.y = screen->h - 24;
SDL_BlitSurface(img_progress, &src, screen, &dest);
}
prog_bar_ctr++;
r.x = 0;
r.y = screen->h - 24;
r.w = screen->w;
r.h = 24;
SDL_UpdateTexture(texture, &r, screen->pixels + ((screen->h - 24) * screen->pitch), screen->pitch);
/* Docs says one should clear the renderer, even if this means a refresh of the whole thing. */
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_BlitSurface(img_progress, &src, screen, &dest);
}
prog_bar_ctr++;
r.x = 0;
r.y = screen->h - 24;
r.w = screen->w;
r.h = 24;
SDL_UpdateTexture(texture, &r,
screen->pixels + ((screen->h - 24) * screen->pitch),
screen->pitch);
/* Docs says one should clear the renderer, even if this means a refresh of the whole thing. */
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
oldtime = newtime;

View file

@ -36,6 +36,7 @@
extern SDL_Surface *img_progress;
extern int progress_bar_disabled, prog_bar_ctr;
void show_progress_bar_(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer);
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture,
SDL_Renderer * renderer);
#endif

View file

@ -43,11 +43,11 @@ unsigned char linear_to_sRGB(float linear)
slot = linear * 4096.0 + 0.5;
if (slot > 4095)
{
if (linear > 0.5)
slot = 4095;
else
slot = 0;
}
{
if (linear > 0.5)
slot = 4095;
else
slot = 0;
}
return linear_to_sRGB_table[slot];
}

View file

@ -305,7 +305,8 @@ static const unsigned char linear_to_sRGB_table[4096] =
"\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd"
"\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
unsigned char linear_to_sRGB(float linear) FUNCTION;

View file

@ -118,8 +118,8 @@ const int shape_locked[NUM_SHAPES] = {
0, /* Hexagon */
0, /* Heptagon */
0, /* Heptagon */
1, /* Octagon */ /* FIXME: Consider unlocking? -bjk 2022.01.21 */
1, /* Octagon */ /* FIXME: Consider unlocking? -bjk 2022.01.21 */
1, /* Octagon *//* FIXME: Consider unlocking? -bjk 2022.01.21 */
1, /* Octagon *//* FIXME: Consider unlocking? -bjk 2022.01.21 */
0, /* Rhombus */
0, /* Rhombus */
0, /* 3 points star */
@ -334,8 +334,10 @@ const char *const shape_tips[NUM_SHAPES] = {
gettext_noop("A rectangle has four sides and four right angles."),
// Description of a circle
gettext_noop("A circle is a curve where all points have the same distance from the center."),
gettext_noop("A circle is a curve where all points have the same distance from the center."),
gettext_noop
("A circle is a curve where all points have the same distance from the center."),
gettext_noop
("A circle is a curve where all points have the same distance from the center."),
// Description of an ellipse
gettext_noop("An ellipse is a stretched circle."),
@ -362,8 +364,10 @@ const char *const shape_tips[NUM_SHAPES] = {
gettext_noop("An octagon has eight equal sides."),
// Description of a rhombus
gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
gettext_noop
("A rhombus has four equal sides, and opposite sides are parallel."),
gettext_noop
("A rhombus has four equal sides, and opposite sides are parallel."),
gettext_noop("A star with 3 points."),
gettext_noop("A star with 3 points."),
@ -423,15 +427,18 @@ const char *const shapemode_img_fnames[NUM_SHAPEMODES] = {
/* String shown when Shapes tool is selected;
one version for normal ("complex shapes"),
the other for simplified mode ("simple shapes") */
enum {
enum
{
SHAPE_COMPLEXITY_NORMAL,
SHAPE_COMPLEXITY_SIMPLE,
NUM_SHAPE_COMPLEXITIES
};
const char *const shape_tool_tips[NUM_SHAPE_COMPLEXITIES] = {
gettext_noop("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want. Move around to rotate it, and click again to draw it."),
gettext_noop("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want.")
gettext_noop
("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want. Move around to rotate it, and click again to draw it."),
gettext_noop
("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want.")
};
/* Strings shown when switching between "from center"

View file

@ -29,17 +29,19 @@
#include <unistd.h>
#include <png.h>
int main(int argc, char * argv[]) {
int main(int argc, char *argv[])
{
int i, w, h, y;
FILE * fi;
FILE *fi;
png_structp png;
png_infop info;
png_byte ctype, depth;
png_bytep * rows;
png_bytep *rows;
/* Usage output */
if (argc == 1 || strcmp(argv[1], "--help") == 0) {
if (argc == 1 || strcmp(argv[1], "--help") == 0)
{
fprintf(stderr, "Usage: %s file.png [file.png ...]\n", argv[0]);
exit(1);
}
@ -53,30 +55,39 @@ int main(int argc, char * argv[]) {
/* Open each PNG image!... */
for (i = 1; i < argc; i++) {
printf("%5d ------------------------------------------------------------------\n", i);
for (i = 1; i < argc; i++)
{
printf
("%5d ------------------------------------------------------------------\n",
i);
printf("%s\n", argv[i]);
fflush(stdout);
/* Open the file */
fi = fopen(argv[i], "rb");
if (fi == NULL) {
if (fi == NULL)
{
printf("Cannot open\n");
} else {
}
else
{
/* Prepare PNG library stuff... */
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) {
if (!png)
{
fprintf(stderr, "Cannot png_create_read_struct()!\n");
exit(1);
}
info = png_create_info_struct(png);
if (!info) {
if (!info)
{
fprintf(stderr, "Cannot png_create_info_struct()!\n");
exit(1);
}
if (setjmp(png_jmpbuf(png))) {
if (setjmp(png_jmpbuf(png)))
{
fprintf(stderr, "Cannot setjmp(png_jmpbuf(png)))!\n");
exit(1);
}
@ -95,39 +106,43 @@ int main(int argc, char * argv[]) {
depth = png_get_bit_depth(png, info);
/* If 16-bit, strip to 8-bit */
if (depth == 16) {
if (depth == 16)
{
printf("test-png warning: 16-bit\n");
png_set_strip_16(png);
}
/* Switch palette to RGB */
if (ctype == PNG_COLOR_TYPE_PALETTE) {
if (ctype == PNG_COLOR_TYPE_PALETTE)
{
printf("test-png warning: paletted\n");
png_set_palette_to_rgb(png);
}
/* Expand low-depth greyscale up to 8-bit */
if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8) {
if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8)
{
printf("test-png warning: greyscale with only %d-bit depth\n", depth);
png_set_expand_gray_1_2_4_to_8(png);
}
/* Expand tRNS chunks into alpha */
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
if (png_get_valid(png, info, PNG_INFO_tRNS))
{
printf("test-png warning: contains tRNS chunk\n");
png_set_tRNS_to_alpha(png);
}
/* Fill alpha channel if there is none */
if (ctype == PNG_COLOR_TYPE_RGB ||
ctype == PNG_COLOR_TYPE_GRAY ||
ctype == PNG_COLOR_TYPE_PALETTE) {
ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_PALETTE)
{
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
}
/* Expand grey to color */
if (ctype == PNG_COLOR_TYPE_GRAY ||
ctype == PNG_COLOR_TYPE_GRAY_ALPHA) {
if (ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_GRAY_ALPHA)
{
printf("test-png warning: greyscale\n");
png_set_gray_to_rgb(png);
}
@ -137,15 +152,19 @@ int main(int argc, char * argv[]) {
/* Allocate space */
rows = (png_bytep *) malloc(sizeof(png_bytep) * h);
if (!rows) {
if (!rows)
{
fprintf(stderr, "Failed to malloc() space for image data rows!\n");
exit(1);
}
for (y = 0; y < h; y++) {
for (y = 0; y < h; y++)
{
rows[y] = (png_byte *) malloc(png_get_rowbytes(png, info));
if (!rows[y]) {
fprintf(stderr, "Failed to malloc() space for image data row #%d!\n", y);
if (!rows[y])
{
fprintf(stderr,
"Failed to malloc() space for image data row #%d!\n", y);
exit(1);
}
}
@ -170,5 +189,5 @@ int main(int argc, char * argv[]) {
fflush(stdout);
}
return(0);
return (0);
}

File diff suppressed because it is too large Load diff

View file

@ -54,10 +54,10 @@ DIR *opendir(const char *pSpec)
strcat(pathname, "/*");
pDir->hFind = FindFirstFile(pathname, &pDir->wfd);
if (pDir->hFind == INVALID_HANDLE_VALUE)
{
free(pDir);
pDir = NULL;
}
{
free(pDir);
pDir = NULL;
}
return pDir;
}
@ -83,16 +83,16 @@ struct dirent *readdir(struct DIR *pDir)
assert(pDir != NULL);
if (pDir->hFind)
{
strcpy(pDir->de.d_name, (const char *)pDir->wfd.cFileName);
if (!FindNextFile(pDir->hFind, &pDir->wfd))
{
strcpy(pDir->de.d_name, (const char *) pDir->wfd.cFileName);
if (!FindNextFile(pDir->hFind, &pDir->wfd))
{
FindClose(pDir->hFind);
pDir->hFind = NULL;
}
return &pDir->de;
{
FindClose(pDir->hFind);
pDir->hFind = NULL;
}
return &pDir->de;
}
return NULL;
}
@ -107,7 +107,9 @@ struct dirent *readdir(struct DIR *pDir)
*/
int alphasort(const void *a, const void *b)
{
return (strcmp((*(const struct dirent **)a)->d_name, (*(const struct dirent **)b)->d_name));
return (strcmp
((*(const struct dirent **) a)->d_name,
(*(const struct dirent **) b)->d_name));
}
/**
@ -124,11 +126,15 @@ static int addToList(int i, struct dirent ***namelist, struct dirent *entry)
int size;
struct dirent *block;
*namelist = (struct dirent **)realloc((void *)(*namelist), (size_t) ((i + 1) * sizeof(struct dirent *)));
*namelist =
(struct dirent **) realloc((void *) (*namelist),
(size_t) ((i + 1) * sizeof(struct dirent *)));
if (*namelist == NULL)
return -1;
size = (((char *)&entry->d_name) - ((char *)entry)) + strlen(entry->d_name) + 1;
block = (struct dirent *)malloc(size);
size =
(((char *) &entry->d_name) - ((char *) entry)) + strlen(entry->d_name) +
1;
block = (struct dirent *) malloc(size);
if (block == NULL)
return -1;
(*namelist)[i] = block;
@ -145,7 +151,8 @@ static int addToList(int i, struct dirent ***namelist, struct dirent *entry)
* @param compar Callback for sorting items in the list (via qsort()).
* @return Count of items, or -1 on error.
*/
int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar)
int scandir(const char *dir, struct dirent ***namelist, selectCB select,
comparCB compar)
{
DIR *pDir;
int count;
@ -157,15 +164,16 @@ int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparC
return -1;
count = 0;
while ((entry = readdir(pDir)) != NULL)
{
if (select == NULL || (select != NULL && select(entry)))
if ((count = addToList(count, namelist, entry)) < 0)
break;
}
{
if (select == NULL || (select != NULL && select(entry)))
if ((count = addToList(count, namelist, entry)) < 0)
break;
}
closedir(pDir);
if (count <= 0)
return -1;
if (compar != NULL)
qsort((void *)(*namelist), (size_t) count, sizeof(struct dirent *), compar);
qsort((void *) (*namelist), (size_t) count, sizeof(struct dirent *),
compar);
return count;
}

View file

@ -68,7 +68,8 @@ typedef struct
extern DIR *opendir(const char *pSpec);
extern void closedir(DIR * pDir);
extern struct dirent *readdir(struct DIR *pDir);
typedef int (*selectCB) (const struct dirent *);
typedef int (*comparCB) (const void *, const void *);
typedef int (*selectCB)(const struct dirent *);
typedef int (*comparCB)(const void *, const void *);
extern int alphasort(const void *a, const void *b);
extern int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar);
extern int scandir(const char *dir, struct dirent ***namelist,
selectCB select, comparCB compar);

View file

@ -68,17 +68,18 @@ static SDL_Surface *make24bitDIB(SDL_Surface * surf)
surf24 = SDL_ConvertSurface(surf, &pixfmt, SDL_SWSURFACE);
surfDIB = SDL_CreateRGBSurface(SDL_SWSURFACE, surf24->w, surf24->h, 24,
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask);
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask,
pixfmt.Amask);
linesize = surf24->w * 3; // Flip top2bottom
dst = surfDIB->pixels;
src = ((Uint8 *) surf24->pixels) + ((surf24->h - 1) * surf24->pitch);
for (i = 0; i < surf24->h; ++i)
{
memcpy(dst, src, linesize);
src -= surf24->pitch;
dst += surfDIB->pitch;
}
{
memcpy(dst, src, linesize);
src -= surf24->pitch;
dst += surfDIB->pitch;
}
SDL_FreeSurface(surf24); // Free temp surface
@ -104,16 +105,17 @@ static int GetDefaultPrinterStrings(char *device, char *driver, char *output)
return 0;
if (((dev = strtok(buff, ",")) != NULL) &&
((drv = strtok(NULL, ", ")) != NULL) && ((out = strtok(NULL, ", ")) != NULL))
{
if (device)
strcpy(device, dev);
if (driver)
strcpy(driver, drv);
if (output)
strcpy(output, out);
return 1;
}
((drv = strtok(NULL, ", ")) != NULL)
&& ((out = strtok(NULL, ", ")) != NULL))
{
if (device)
strcpy(device, dev);
if (driver)
strcpy(driver, drv);
if (output)
strcpy(output, out);
return 1;
}
return 0;
}
@ -143,7 +145,8 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
if (!OpenPrinter(device, &hPrinter, NULL))
goto err_exit;
sizeof_devmode = (int)DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0);
sizeof_devmode =
(int) DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0);
if (!sizeof_devmode)
goto err_exit;
@ -156,7 +159,8 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
if (!devmode)
goto err_exit;
res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER);
res =
DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER);
if (res != IDOK)
goto err_exit;
@ -166,7 +170,9 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
goto err_exit;
fclose(fp);
res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);
res =
DocumentProperties(hWnd, hPrinter, device, devmode, devmode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (res != IDOK)
goto err_exit;
@ -189,25 +195,26 @@ err_exit:
/**
* FIXME
*/
static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath, HANDLE hDevMode)
static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath,
HANDLE hDevMode)
{
FILE *fp = NULL;
NOREF(hWnd);
if ((fp = fopen(filepath, "wb")) != NULL)
{
DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode);
int block_size = devmode->dmSize + devmode->dmDriverExtra;
int block_written;
char devname[dmDeviceNameSize];
{
DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode);
int block_size = devmode->dmSize + devmode->dmDriverExtra;
int block_written;
char devname[dmDeviceNameSize];
strcpy(devname, (const char *)devmode->dmDeviceName);
fwrite(devname, 1, sizeof(devname), fp);
block_written = fwrite(devmode, 1, block_size, fp);
GlobalUnlock(hDevMode);
fclose(fp);
return block_size == block_written;
}
strcpy(devname, (const char *) devmode->dmDeviceName);
fwrite(devname, 1, sizeof(devname), fp);
block_written = fwrite(devmode, 1, block_size, fp);
GlobalUnlock(hDevMode);
fclose(fp);
return block_size == block_written;
}
return 0;
}
@ -222,10 +229,10 @@ static int FileExists(const char *filepath)
FILE *fp;
if ((fp = fopen(filepath, "rb")) != NULL)
{
fclose(fp);
return 1;
}
{
fclose(fp);
return 1;
}
return 0;
}
@ -250,22 +257,23 @@ static int GetCustomPrinterDC(HWND hWnd, const char *printcfg, int show)
pd.hDevMode = LoadCustomPrinterHDEVMODE(hWnd, printcfg);
if (show || !FileExists(printcfg))
{
if (PrintDlg(&pd))
{
if (PrintDlg(&pd))
{
hDCprinter = pd.hDC;
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode);
GlobalFree(pd.hDevMode);
return 1;
}
hDCprinter = pd.hDC;
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode);
GlobalFree(pd.hDevMode);
return 0;
return 1;
}
GlobalFree(pd.hDevMode);
return 0;
}
{
DEVMODE *devmode = (DEVMODE *) GlobalLock(pd.hDevMode);
hDCprinter = CreateDC(NULL, (const char *)devmode->dmDeviceName, NULL, devmode);
hDCprinter =
CreateDC(NULL, (const char *) devmode->dmDeviceName, NULL, devmode);
GlobalUnlock(pd.hDevMode);
GlobalFree(pd.hDevMode);
}
@ -295,9 +303,9 @@ static int GetPrinterDC(HWND hWnd, const char *printcfg, int show)
hDCprinter = NULL;
if (printcfg)
{
return GetCustomPrinterDC(hWnd, printcfg, show);
}
{
return GetCustomPrinterDC(hWnd, printcfg, show);
}
hDCprinter = GetDefaultPrinterDC();
return 1;
}
@ -318,7 +326,8 @@ int IsPrinterAvailable(void)
/**
* FIXME
*/
const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *printcfg, int showdialog)
const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf,
const char *printcfg, int showdialog)
{
const char *res = NULL;
HWND hWnd;
@ -342,10 +351,10 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
hWnd = wminfo.info.win.window;
if (!GetPrinterDC(hWnd, printcfg, showdialog))
{
ShowWindow(hWnd, SW_SHOWNORMAL);
return NULL;
}
{
ShowWindow(hWnd, SW_SHOWNORMAL);
return NULL;
}
if (!hDCprinter)
return "win32_print: GetPrinterDC() failed.";
@ -360,26 +369,26 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
nError = StartDoc(hDCprinter, &di);
if (nError == SP_ERROR)
{
res = "win32_print: StartDoc() failed.";
goto error;
}
{
res = "win32_print: StartDoc() failed.";
goto error;
}
nError = StartPage(hDCprinter);
if (nError <= 0)
{
res = "win32_print: StartPage() failed.";
goto error;
}
{
res = "win32_print: StartPage() failed.";
goto error;
}
//////////////////////////////////////////////////////////////////////////////////////
surf24 = make24bitDIB(surf);
if (!surf24)
{
res = "win32_print: make24bitDIB() failed.";
goto error;
}
{
res = "win32_print: make24bitDIB() failed.";
goto error;
}
memset(&bmih, 0, sizeof(bmih));
bmih.biSize = sizeof(bmih);
@ -395,100 +404,100 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
sY = GetDeviceCaps(hDCprinter, LOGPIXELSY);
switch (scaling)
{
case STRETCH_TO_FIT:
{
case STRETCH_TO_FIT:
{
/* stretches x and y dimensions independently to fit the page */
/* doesn't preserve image aspect-ratio */
rcDst.top = 0;
rcDst.left = 0;
rcDst.bottom = pageHeight;
rcDst.right = pageWidth;
break;
}
case SCALE_TO_FIT:
{
/* maximises image size on the page */
/* preserves aspect-ratio, alignment is top and center */
int width = bmih.biWidth;
int height = bmih.biHeight;
if (width < pageWidth && height < pageHeight)
{
float dW = (float)pageWidth / width;
float dH = (float)pageHeight / height;
if (dW < dH)
{
width = pageWidth;
height = (int)((height * dW * (sY / sX)) + 0.5f);
}
else
{
width = (int)((width * dH * (sX / sY)) + 0.5f);
height = pageHeight;
}
}
if (width > pageWidth)
{
height = height * width / pageWidth;
width = pageWidth;
}
if (height > pageHeight)
{
width = width * height / pageHeight;
height = pageHeight;
}
rcDst.top = 0;
rcDst.left = (pageWidth - width) / 2;
rcDst.bottom = rcDst.top + height;
rcDst.right = rcDst.left + width;
break;
}
default:
res = "win32_print: invalid scaling option.";
goto error;
/* stretches x and y dimensions independently to fit the page */
/* doesn't preserve image aspect-ratio */
rcDst.top = 0;
rcDst.left = 0;
rcDst.bottom = pageHeight;
rcDst.right = pageWidth;
break;
}
case SCALE_TO_FIT:
{
/* maximises image size on the page */
/* preserves aspect-ratio, alignment is top and center */
int width = bmih.biWidth;
int height = bmih.biHeight;
if (width < pageWidth && height < pageHeight)
{
float dW = (float) pageWidth / width;
float dH = (float) pageHeight / height;
if (dW < dH)
{
width = pageWidth;
height = (int) ((height * dW * (sY / sX)) + 0.5f);
}
else
{
width = (int) ((width * dH * (sX / sY)) + 0.5f);
height = pageHeight;
}
}
if (width > pageWidth)
{
height = height * width / pageWidth;
width = pageWidth;
}
if (height > pageHeight)
{
width = width * height / pageHeight;
height = pageHeight;
}
rcDst.top = 0;
rcDst.left = (pageWidth - width) / 2;
rcDst.bottom = rcDst.top + height;
rcDst.right = rcDst.left + width;
break;
}
default:
res = "win32_print: invalid scaling option.";
goto error;
}
hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS);
if (hDCCaps & RC_PALETTE)
{
res = "win32_print: printer context requires palette.";
goto error;
}
{
res = "win32_print: printer context requires palette.";
goto error;
}
if (hDCCaps & RC_STRETCHDIB)
{
SetStretchBltMode(hDCprinter, COLORONCOLOR);
{
SetStretchBltMode(hDCprinter, COLORONCOLOR);
bmi.bmiHeader = bmih;
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
rcDst.right - rcDst.left,
rcDst.bottom - rcDst.top,
0, 0, bmih.biWidth, bmih.biHeight,
surf24->pixels, &bmi, DIB_RGB_COLORS, SRCCOPY);
if (nError == (int) GDI_ERROR)
{
res = "win32_print: StretchDIBits() failed.";
goto error;
}
}
else
bmi.bmiHeader = bmih;
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
rcDst.right - rcDst.left,
rcDst.bottom - rcDst.top,
0, 0, bmih.biWidth, bmih.biHeight,
surf24->pixels, &bmi, DIB_RGB_COLORS, SRCCOPY);
if (nError == (int) GDI_ERROR)
{
res = "win32_print: StretchDIBits() not available.";
res = "win32_print: StretchDIBits() failed.";
goto error;
}
}
else
{
res = "win32_print: StretchDIBits() not available.";
goto error;
}
//////////////////////////////////////////////////////////////////////////////////////
nError = EndPage(hDCprinter);
if (nError <= 0)
{
res = "win32_print: EndPage() failed.";
goto error;
}
{
res = "win32_print: EndPage() failed.";
goto error;
}
EndDoc(hDCprinter);
@ -514,7 +523,8 @@ error:
/*
Read access to Windows Registry
*/
static HRESULT ReadRegistry(const char *key, const char *option, char *value, int size)
static HRESULT ReadRegistry(const char *key, const char *option, char *value,
int size)
{
LONG res;
HKEY hKey = NULL;
@ -563,17 +573,18 @@ char *GetDefaultSaveDir(const char *suffix)
{
char prefix[MAX_PATH];
char path[2 * MAX_PATH];
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *key =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *option = "AppData";
HRESULT hr = S_OK;
if (SUCCEEDED(hr = ReadRegistry(key, option, prefix, sizeof(prefix))))
{
remove_slash(prefix);
snprintf(path, sizeof(path), "%s/%s", prefix, suffix);
_mkdir(path);
return strdup(path);
}
{
remove_slash(prefix);
snprintf(path, sizeof(path), "%s/%s", prefix, suffix);
_mkdir(path);
return strdup(path);
}
return strdup("userdata");
}
@ -587,15 +598,16 @@ char *GetDefaultSaveDir(const char *suffix)
char *GetSystemFontDir(void)
{
char path[MAX_PATH];
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *key =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *option = "Fonts";
HRESULT hr = S_OK;
if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path))))
{
remove_slash(path);
return strdup(path);
}
{
remove_slash(path);
return strdup(path);
}
return strdup("C:\\WINDOWS\\FONTS");
}
@ -609,15 +621,16 @@ char *GetUserImageDir(void);
char *GetUserImageDir(void)
{
char path[MAX_PATH];
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *key =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *option = "My Pictures";
HRESULT hr = S_OK;
if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path))))
{
remove_slash(path);
return strdup(path);
}
{
remove_slash(path);
return strdup(path);
}
return strdup("C:\\Pictures");
}
@ -630,9 +643,9 @@ static char *GetUserTempDir(void)
const char *temp = getenv("TEMP");
if (!temp)
{
temp = "userdata";
}
{
temp = "userdata";
}
return strdup(temp);
}
@ -662,7 +675,8 @@ static int g_bWindowActive = 0;
/**
* FIXME
*/
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
int bEatKeystroke = 0;
@ -672,14 +686,15 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
{
case WM_KEYDOWN:
case WM_KEYUP:
{
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN));
break;
}
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN)
|| (p->vkCode == VK_RWIN));
break;
}
}
if (bEatKeystroke)
return 1;
@ -693,7 +708,9 @@ int InstallKeyboardHook(void)
{
if (g_hKeyboardHook)
return -1;
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
g_hKeyboardHook =
SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
GetModuleHandle(NULL), 0);
return g_hKeyboardHook ? 0 : -2;
}

View file

@ -15,7 +15,8 @@
#endif
/* if printcfg is NULL, uses the default printer */
extern const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *printcfg, int showdialog);
extern const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf,
const char *printcfg, int showdialog);
extern int IsPrinterAvailable(void);
/* additional windows functions requiring <windows.h> */

View file

@ -1,23 +1,26 @@
#include <windows.h>
#include <tchar.h>
int MoveFileToRecycleBin(const TCHAR *fullPathName);
int MoveFileToRecycleBin(const TCHAR * fullPathName);
int win32_trash(const char *path);
int MoveFileToRecycleBin(const TCHAR *fullPathName)
int MoveFileToRecycleBin(const TCHAR * fullPathName)
{
SHFILEOPSTRUCT fileOp;
const TCHAR *src = fullPathName;
TCHAR *dest;
fileOp.pFrom = dest = alloca(sizeof(*dest) * (_tcslen(fullPathName) + 2));
while((*dest++ = *src++) != _T('\0')) {}
while ((*dest++ = *src++) != _T('\0'))
{
}
*dest = _T('\0');
fileOp.hwnd = NULL;
fileOp.wFunc = FO_DELETE;
fileOp.pTo = NULL;
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
fileOp.fFlags =
FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
return SHFileOperation(&fileOp);
}
@ -26,8 +29,10 @@ int win32_trash(const char *path)
char *p, *src;
src = p = strdup(path);
while(*p != '\0'){
if (*p == '/') *p = '\\';
while (*p != '\0')
{
if (*p == '/')
*p = '\\';
p++;
}
return MoveFileToRecycleBin(src);