Slight change to its default behavior re: pointer variables (before: "type * var"; now seems to prefer: "type *var").
223 lines
5.1 KiB
C
223 lines
5.1 KiB
C
/* specular.c
|
|
|
|
A specular reflection Magic tool for Tux Paint
|
|
by Bill Kendrick <bill@newbreedsoftware.com>
|
|
|
|
Last updated: March 2, 2024
|
|
*/
|
|
|
|
|
|
/* Inclusion of header files */
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <libintl.h>
|
|
|
|
#include "tp_magic_api.h"
|
|
#include "SDL_image.h"
|
|
#include "SDL_mixer.h"
|
|
|
|
/* Our global variables: */
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
/* Sound effects: */
|
|
Mix_Chunk *snd_effect;
|
|
|
|
/* The size the user has selected in Tux Paint: */
|
|
Uint8 specular_size = 32;
|
|
|
|
|
|
void specular_drag(magic_api * api, int which, SDL_Surface * canvas,
|
|
SDL_Surface * snapshot, int old_x, int old_y, int x, int y, SDL_Rect * update_rect);
|
|
|
|
void specular_line_callback(void *pointer, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
|
|
|
|
|
|
Uint32 specular_api_version(void)
|
|
{
|
|
return (TP_MAGIC_API_VERSION);
|
|
}
|
|
|
|
int specular_init(magic_api *api, Uint8 disabled_features, Uint8 complexity_level)
|
|
{
|
|
int i;
|
|
char filename[1024];
|
|
|
|
snprintf(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory, "reflection.ogg"); // FIXME
|
|
snd_effect = Mix_LoadWAV(filename);
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
int specular_get_tool_count(magic_api *api)
|
|
{
|
|
return (1);
|
|
}
|
|
|
|
SDL_Surface *specular_get_icon(magic_api *api, int which)
|
|
{
|
|
char filename[1024];
|
|
|
|
snprintf(filename, sizeof(filename), "%simages/magic/%s", api->data_directory, "reflection.png"); // FIXME
|
|
|
|
return (IMG_Load(filename));
|
|
}
|
|
|
|
|
|
char *specular_get_name(magic_api *api, int which)
|
|
{
|
|
return strdup(gettext("Specular Reflection"));
|
|
}
|
|
|
|
|
|
int specular_get_group(magic_api *api, int which)
|
|
{
|
|
return MAGIC_TYPE_PAINTING;
|
|
}
|
|
|
|
|
|
int specular_get_order(int which)
|
|
{
|
|
return 1710;
|
|
}
|
|
|
|
|
|
char *specular_get_description(magic_api *api, int which, int mode)
|
|
{
|
|
return
|
|
strdup(gettext
|
|
("Click and drag on the bottom half of your picture to draw a specular reflection — like a puddle, pond, or lake — that mirrors the top half of your picture."));
|
|
}
|
|
|
|
|
|
int specular_requires_colors(magic_api *api, int which)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
int specular_modes(magic_api *api, int which)
|
|
{
|
|
return MODE_PAINT;
|
|
}
|
|
|
|
|
|
Uint8 specular_accepted_sizes(magic_api *api, int which, int mode)
|
|
{
|
|
return 4;
|
|
}
|
|
|
|
|
|
Uint8 specular_default_size(magic_api *api, int which, int mode)
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
|
|
void specular_shutdown(magic_api *api)
|
|
{
|
|
if (snd_effect != NULL)
|
|
{
|
|
Mix_FreeChunk(snd_effect);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
specular_click(magic_api *api, int which, int mode,
|
|
SDL_Surface *canvas, SDL_Surface *snapshot, int x, int y, SDL_Rect *update_rect)
|
|
{
|
|
specular_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
|
}
|
|
|
|
|
|
void
|
|
specular_drag(magic_api *api, int which,
|
|
SDL_Surface *canvas, SDL_Surface *snapshot, int old_x, int old_y, int x, int y, SDL_Rect *update_rect)
|
|
{
|
|
SDL_LockSurface(snapshot);
|
|
SDL_LockSurface(canvas);
|
|
|
|
api->line((void *)api, which, canvas, snapshot, old_x, old_y, x, y, 1, specular_line_callback);
|
|
|
|
SDL_UnlockSurface(canvas);
|
|
SDL_UnlockSurface(snapshot);
|
|
|
|
if (old_x > x)
|
|
{
|
|
int temp = old_x;
|
|
|
|
old_x = x;
|
|
x = temp;
|
|
}
|
|
if (old_y > y)
|
|
{
|
|
int temp = old_y;
|
|
|
|
old_y = y;
|
|
y = temp;
|
|
}
|
|
|
|
update_rect->x = old_x - specular_size;
|
|
update_rect->y = old_y - specular_size;
|
|
update_rect->w = (x + specular_size) - update_rect->x + 1;
|
|
update_rect->h = (y + specular_size) - update_rect->y + 1;
|
|
|
|
api->playsound(snd_effect, (x * 255) / canvas->w, 255);
|
|
}
|
|
|
|
void
|
|
specular_release(magic_api *api, int which,
|
|
SDL_Surface *canvas, SDL_Surface *snapshot, int x, int y, SDL_Rect *update_rect)
|
|
{
|
|
}
|
|
|
|
void specular_set_color(magic_api *api, int which, SDL_Surface *canvas, SDL_Surface *snapshot, Uint8 r, Uint8 g,
|
|
Uint8 b, SDL_Rect *update_rect)
|
|
{
|
|
}
|
|
|
|
void specular_set_size(magic_api *api, int which, int mode, SDL_Surface *canvas, SDL_Surface *snapshot, Uint8 size,
|
|
SDL_Rect *update_rect)
|
|
{
|
|
specular_size = size * 16;
|
|
}
|
|
|
|
|
|
void specular_line_callback(void *pointer, int which, SDL_Surface *canvas, SDL_Surface *snapshot, int x, int y)
|
|
{
|
|
magic_api *api = (magic_api *) pointer;
|
|
int xx, yy, ysrc;
|
|
Uint8 r, g, b, r1, g1, b1, r2, g2, b2, fade;
|
|
|
|
for (yy = -specular_size / 16; yy < specular_size / 16; yy++)
|
|
{
|
|
ysrc = (snapshot->h - y - yy) + sin(y - yy) * 4;
|
|
|
|
for (xx = -specular_size; xx < specular_size; xx++)
|
|
{
|
|
if (api->in_circle(xx, yy * 16, specular_size))
|
|
{
|
|
SDL_GetRGB(api->getpixel(snapshot, x + xx + sin((y + yy) / 4) * 4, ysrc), snapshot->format, &r1, &g1, &b1);
|
|
SDL_GetRGB(api->getpixel(snapshot, x + xx + sin((y + yy) / 4) * 4 + 1, ysrc), snapshot->format, &r2, &g2, &b2);
|
|
|
|
fade = (((y + yy) * 255) / canvas->h);
|
|
r = (((r1 + r2) * 2) + fade) / 5;
|
|
g = (((g1 + g2) * 2) + fade) / 5;
|
|
b = (((b1 + b2) * 2) + fade) / 5;
|
|
|
|
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void specular_switchin(magic_api *api, int which, int mode, SDL_Surface *canvas)
|
|
{
|
|
}
|
|
|
|
void specular_switchout(magic_api *api, int which, int mode, SDL_Surface *canvas)
|
|
{
|
|
}
|