September 8th
Merge branch 'master' into sdl2.0 Many changes and improvements by Bill
This commit is contained in:
commit
10baa371dd
272 changed files with 54699 additions and 34028 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* halftone.c
|
||||
|
||||
Last modified: 2021.02.20
|
||||
Last modified: 2021.09.04
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -16,6 +16,12 @@
|
|||
#include "SDL_image.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
||||
#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[]`) */
|
||||
|
||||
enum
|
||||
{
|
||||
TOOL_HALFTONE,
|
||||
|
|
@ -84,14 +90,6 @@ int halftone_init(magic_api * api)
|
|||
snprintf(fname, sizeof(fname), "%ssounds/magic/%s", api->data_directory, snd_filenames[i]);
|
||||
|
||||
snd_effect[i] = Mix_LoadWAV(fname);
|
||||
/*
|
||||
if (snd_effect[i] == NULL)
|
||||
{
|
||||
SDL_FreeSurface(canvas_backup);
|
||||
SDL_FreeSurface(square);
|
||||
return (0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -141,7 +139,7 @@ int halftone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBU
|
|||
|
||||
int halftone_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return MODE_PAINT;
|
||||
return (MODE_PAINT | MODE_FULLSCREEN);
|
||||
}
|
||||
|
||||
void halftone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
|
||||
|
|
@ -158,10 +156,30 @@ void halftone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
|
|||
SDL_FreeSurface(square);
|
||||
}
|
||||
|
||||
void halftone_click(magic_api * api, int which, int mode 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)
|
||||
{
|
||||
halftone_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
int full_x, full_y;
|
||||
|
||||
if (mode == MODE_PAINT)
|
||||
{
|
||||
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_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,
|
||||
|
|
@ -184,10 +202,15 @@ void halftone_drag(magic_api * api, int which, SDL_Surface * canvas,
|
|||
y = tmp;
|
||||
}
|
||||
|
||||
update_rect->x = ox - 16;
|
||||
update_rect->y = oy - 16;
|
||||
update_rect->w = (x + 16) - update_rect->x;
|
||||
update_rect->h = (y + 16) - update_rect->h;
|
||||
ox = (ox / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
oy = (oy / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
x = (x / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
y = (y / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
|
||||
update_rect->x = ox - GRID_SIZE / 2;
|
||||
update_rect->y = oy - GRID_SIZE / 2;
|
||||
update_rect->w = (x + GRID_SIZE / 2) - update_rect->x;
|
||||
update_rect->h = (y + GRID_SIZE / 2) - update_rect->y;
|
||||
|
||||
api->playsound(snd_effect[which], (x * 255) / canvas->w, // pan
|
||||
255); // distance
|
||||
|
|
@ -203,17 +226,17 @@ enum
|
|||
};
|
||||
|
||||
Uint8 chan_colors[NUM_CHANS][3] = {
|
||||
{0, 255, 255},
|
||||
{255, 0, 255},
|
||||
{255, 255, 0},
|
||||
{0, 0, 0}
|
||||
{0, 255, 255}, /* Cyan */
|
||||
{255, 0, 255}, /* Magenta */
|
||||
{255, 255, 0}, /* Yellow */
|
||||
{0, 0, 0} /* Black */
|
||||
};
|
||||
|
||||
int chan_angles[NUM_CHANS] = {
|
||||
100,
|
||||
15,
|
||||
0,
|
||||
45
|
||||
75, /* Cyan */
|
||||
15, /* Magenta */
|
||||
90, /* Yellow */
|
||||
45 /* Black */
|
||||
};
|
||||
|
||||
void halftone_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
|
||||
|
|
@ -227,98 +250,95 @@ void halftone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUS
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
|
||||
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;
|
||||
int px_cnt;
|
||||
Uint32 pixel;
|
||||
int xx, yy, xxx, yyy, channel, ox, oy, sqx, sqy;
|
||||
int xxx, yyy, channel, ox, oy, sqx, sqy;
|
||||
SDL_Rect dest;
|
||||
magic_api *api = (magic_api *) ptr;
|
||||
float cmyk[4];
|
||||
|
||||
/* Start the pixel with white */
|
||||
pixel = SDL_MapRGB(square->format, 255, 255, 255);
|
||||
SDL_FillRect(square, NULL, pixel);
|
||||
|
||||
/* Lock to grid, centered around mouse */
|
||||
x = ((x / 8) - 1) * 8;
|
||||
y = ((y / 8) - 1) * 8;
|
||||
/* Lock to a grid, centered around mouse */
|
||||
x = (x / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
y = (y / GRID_SIZE) * GRID_SIZE + (GRID_SIZE / 2);
|
||||
|
||||
if (api->touched(x, y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (xx = 0; xx < 16; xx = xx + 4)
|
||||
/* 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 (yy = 0; yy < 16; yy = yy + 4)
|
||||
for (yyy = -(GRID_SIZE / 2); yyy < (GRID_SIZE / 2); yyy++)
|
||||
{
|
||||
/* Get avg color around the mouse */
|
||||
total_r = total_g = total_b = 0;
|
||||
for (xxx = 0; xxx < 4; xxx++)
|
||||
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 /= (GRID_SIZE * GRID_SIZE);
|
||||
total_g /= (GRID_SIZE * GRID_SIZE);
|
||||
total_b /= (GRID_SIZE * GRID_SIZE);
|
||||
|
||||
|
||||
/* Convert the average color from RGB to CMYK values, for 'painting' later */
|
||||
halftone_rgb2cmyk(total_r, total_g, total_b, cmyk);
|
||||
|
||||
/* 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 (yyy = -(GRID_SIZE / 2) - 1; yyy < (GRID_SIZE / 2) + 1; yyy++)
|
||||
{
|
||||
for (yyy = 0; yyy < 4; 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))
|
||||
{
|
||||
SDL_GetRGB(api->getpixel(canvas_backup, x + xx + xxx, y + yy + yyy), canvas_backup->format, &r, &g,
|
||||
&b);
|
||||
total_r += r;
|
||||
total_g += g;
|
||||
total_b += b;
|
||||
}
|
||||
}
|
||||
total_r /= 16;
|
||||
total_g /= 16;
|
||||
total_b /= 16;
|
||||
/* 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];
|
||||
|
||||
/* Convert to CMYK values */
|
||||
halftone_rgb2cmyk(total_r, total_g, total_b, cmyk);
|
||||
|
||||
/* Draw C, M, Y and K blobs into our 'square' surface */
|
||||
for (channel = 0; channel < NUM_CHANS; channel++)
|
||||
{
|
||||
r = chan_colors[channel][0];
|
||||
g = chan_colors[channel][1];
|
||||
b = chan_colors[channel][2];
|
||||
|
||||
for (xxx = 0; xxx < 8; xxx++)
|
||||
{
|
||||
for (yyy = 0; yyy < 8; yyy++)
|
||||
{
|
||||
/* A circle blob, radius based upon channel (C, M, Y or K) strength for this color */
|
||||
|
||||
/* FIXME: Base it upon this channel's angle! -bjk 2011.07.17 */
|
||||
ox = xxx;
|
||||
oy = yyy;
|
||||
|
||||
sqx = (xx + ox) % 16;
|
||||
sqy = (yy + oy) % 16;
|
||||
|
||||
if (api->in_circle(xxx - 4, yyy - 4, cmyk[channel] * 6.0))
|
||||
{
|
||||
SDL_GetRGB(api->getpixel(square, sqx, sqy), square->format, &or, &og, &ob);
|
||||
|
||||
if (or == 255 && og == 255 && ob == 255)
|
||||
{
|
||||
/* If it's just white, put full color down */
|
||||
pixel = SDL_MapRGB(square->format, r, g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, blend a little */
|
||||
pixel = SDL_MapRGB(square->format, (r + or) / 2, (g + og) / 2, (b + ob) / 2);
|
||||
}
|
||||
|
||||
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(r * 1.2, or), min(g * 1.2, og), min(b * 1.2, ob));
|
||||
api->putpixel(square, sqx, sqy, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
/* Copy the results to the canvas */
|
||||
dest.x = x - GRID_SIZE / 2;
|
||||
dest.y = y - GRID_SIZE / 2;
|
||||
dest.w = GRID_SIZE;
|
||||
dest.h = GRID_SIZE;
|
||||
|
||||
SDL_BlitSurface(square, NULL, canvas, &dest);
|
||||
}
|
||||
|
|
@ -326,16 +346,18 @@ void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
|
|||
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, 16, 16, canvas->format->BitsPerPixel, canvas->format->Rmask,
|
||||
canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
|
||||
|
||||
/* FIXME: What to do if they come back 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);
|
||||
}
|
||||
|
||||
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
Negative Magic Tool Plugin
|
||||
Tux Paint - A simple drawing program for children.
|
||||
|
||||
Copyright (c) 2002-2008 by Bill Kendrick and others; see AUTHORS.txt
|
||||
Copyright (c) 2002-2021 by Bill Kendrick and others; see AUTHORS.txt
|
||||
bill@newbreedsoftware.com
|
||||
http://www.tuxpaint.org/
|
||||
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
(See COPYING.txt)
|
||||
|
||||
Last updated: July 8, 2008
|
||||
Last updated: September 6, 2021
|
||||
$Id$
|
||||
*/
|
||||
|
||||
|
|
@ -56,7 +56,35 @@ void negative_switchin(magic_api * api, int which, int mode, SDL_Surface * canva
|
|||
void negative_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
|
||||
int negative_modes(magic_api * api, int which);
|
||||
|
||||
// No setup required:
|
||||
enum
|
||||
{
|
||||
TOOL_NEGATIVE,
|
||||
TOOL_COMPLEMENTARY,
|
||||
negative_NUM_TOOLS
|
||||
};
|
||||
|
||||
const char *negative_icon_filenames[negative_NUM_TOOLS] = {
|
||||
"negative.png",
|
||||
"opposite.png"
|
||||
};
|
||||
|
||||
const char *negative_names[negative_NUM_TOOLS] = {
|
||||
gettext_noop("Negative"),
|
||||
gettext_noop("Opposite")
|
||||
};
|
||||
|
||||
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 change colors to their opposites -- their complementary colors."),
|
||||
gettext_noop("Click to turn all colors in your painting into their opposites -- their complementary colors.")
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
int negative_init(magic_api * api)
|
||||
{
|
||||
char fname[1024];
|
||||
|
|
@ -73,43 +101,69 @@ Uint32 negative_api_version(void)
|
|||
return (TP_MAGIC_API_VERSION);
|
||||
}
|
||||
|
||||
// Only one tool:
|
||||
int negative_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (1);
|
||||
return (negative_NUM_TOOLS);
|
||||
}
|
||||
|
||||
// Load our icon:
|
||||
SDL_Surface *negative_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
|
||||
SDL_Surface *negative_get_icon(magic_api * api, int which)
|
||||
{
|
||||
char fname[1024];
|
||||
|
||||
snprintf(fname, sizeof(fname), "%simages/magic/negative.png", api->data_directory);
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/%s", api->data_directory, negative_icon_filenames[which]);
|
||||
return (IMG_Load(fname));
|
||||
}
|
||||
|
||||
// Return our name, localized:
|
||||
char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
|
||||
{
|
||||
return (strdup(gettext_noop("Negative")));
|
||||
return (strdup(gettext_noop(negative_names[which])));
|
||||
}
|
||||
|
||||
// Return our description, localized:
|
||||
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
|
||||
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
|
||||
{
|
||||
if (mode == MODE_PAINT)
|
||||
return (strdup(gettext_noop("Click and drag the mouse around to make your painting negative."))); /* Does this make more sense? */
|
||||
else if (mode == MODE_FULLSCREEN)
|
||||
return (strdup(gettext_noop("Click to turn your painting into its negative.")));
|
||||
int mode_idx;
|
||||
|
||||
if (mode == MODE_PAINT) {
|
||||
mode_idx = 0;
|
||||
} else if (mode == MODE_FULLSCREEN) {
|
||||
mode_idx = 1;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
else
|
||||
return (NULL);
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback that does the negative color effect on a circle centered around x,y
|
||||
static void do_negative(void *ptr, int which ATTRIBUTE_UNUSED, 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;
|
||||
Uint8 r, g, b, new_r, new_g, new_b;
|
||||
magic_api *api = (magic_api *) ptr;
|
||||
|
||||
for (yy = y - 16; yy < y + 16; yy++)
|
||||
|
|
@ -119,12 +173,8 @@ static void do_negative(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * can
|
|||
if (api->in_circle(xx - x, yy - y, 16))
|
||||
{
|
||||
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
|
||||
|
||||
r = 0xFF - r;
|
||||
g = 0xFF - g;
|
||||
b = 0xFF - b;
|
||||
|
||||
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -175,19 +225,15 @@ void negative_click(magic_api * api, int which, int mode,
|
|||
else
|
||||
{
|
||||
int xx, yy;
|
||||
Uint8 r, g, b;
|
||||
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);
|
||||
|
||||
r = 0xFF - r;
|
||||
g = 0xFF - g;
|
||||
b = 0xFF - b;
|
||||
|
||||
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +241,8 @@ void negative_click(magic_api * api, int which, int mode,
|
|||
update_rect->y = 0;
|
||||
update_rect->w = canvas->w;
|
||||
update_rect->h = canvas->h;
|
||||
|
||||
api->playsound(negative_snd, (x * 255) / canvas->w, 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,3 +286,4 @@ int negative_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
|||
{
|
||||
return (MODE_PAINT | MODE_FULLSCREEN);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
Credits: Andrew Corcoran <akanewbie@gmail.com>
|
||||
|
||||
Copyright (c) 2002-2019 by Bill Kendrick and others; see AUTHORS.txt
|
||||
Copyright (c) 2002-2021 by Bill Kendrick and others; see AUTHORS.txt
|
||||
bill@newbreedsoftware.com
|
||||
http://www.tuxpaint.org/
|
||||
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
(See COPYING.txt)
|
||||
|
||||
Last updated: August 29, 2019
|
||||
Last updated: September 4, 2021
|
||||
$Id$
|
||||
*/
|
||||
|
||||
|
|
@ -114,6 +114,7 @@ float top_advc_y, right_advc_y, bottom_advc_y, left_advc_y;
|
|||
enum
|
||||
{
|
||||
TOOL_PERSPECTIVE,
|
||||
TOOL_PANELS,
|
||||
TOOL_ZOOM,
|
||||
perspective_NUM_TOOLS
|
||||
};
|
||||
|
|
@ -134,28 +135,29 @@ static Mix_Chunk *perspective_snd_effect[perspective_NUM_TOOLS + 1];
|
|||
|
||||
const char *perspective_snd_filenames[perspective_NUM_TOOLS + 1] = {
|
||||
"perspective.ogg",
|
||||
"zoom_down.ogg", /* TODO: Could use a different sound */
|
||||
"zoom_up.ogg",
|
||||
"zoom_down.ogg",
|
||||
};
|
||||
|
||||
const char *perspective_icon_filenames[perspective_NUM_TOOLS] = {
|
||||
"perspective.png",
|
||||
"panels.png",
|
||||
"zoom.png",
|
||||
};
|
||||
|
||||
const char *perspective_names[perspective_NUM_TOOLS] = {
|
||||
gettext_noop("Perspective"),
|
||||
gettext_noop("Panels"),
|
||||
gettext_noop("Zoom"),
|
||||
|
||||
};
|
||||
|
||||
const char *perspective_descs[perspective_NUM_TOOLS] = {
|
||||
gettext_noop("Click on the corners and drag where you want to stretch the picture."),
|
||||
|
||||
gettext_noop("Click to turn your picture into 2-by-2 panels."),
|
||||
|
||||
gettext_noop("Click and drag up to zoom in or drag down to zoom out the picture."),
|
||||
|
||||
|
||||
};
|
||||
|
||||
Uint32 perspective_api_version(void)
|
||||
|
|
@ -358,8 +360,56 @@ void perspective_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
|
|||
old_h = new_h;
|
||||
}
|
||||
break;
|
||||
case TOOL_PANELS:
|
||||
{
|
||||
SDL_Surface *scaled_surf;
|
||||
|
||||
scaled_surf = api->scale(canvas, canvas->w / 2, canvas->h / 2, 0);
|
||||
|
||||
/* Top left */
|
||||
update_rect->x = 0;
|
||||
update_rect->y = 0;
|
||||
update_rect->w = scaled_surf->w;
|
||||
update_rect->h = scaled_surf->h;
|
||||
SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect);
|
||||
|
||||
/* Top right */
|
||||
update_rect->x = scaled_surf->w;
|
||||
update_rect->y = 0;
|
||||
update_rect->w = scaled_surf->w;
|
||||
update_rect->h = scaled_surf->h;
|
||||
SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect);
|
||||
|
||||
/* Bottom left */
|
||||
update_rect->x = 0;
|
||||
update_rect->y = scaled_surf->h;
|
||||
update_rect->w = scaled_surf->w;
|
||||
update_rect->h = scaled_surf->h;
|
||||
SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect);
|
||||
|
||||
/* Bottom right */
|
||||
update_rect->x = scaled_surf->w;
|
||||
update_rect->y = scaled_surf->h;
|
||||
update_rect->w = scaled_surf->w;
|
||||
update_rect->h = scaled_surf->h;
|
||||
SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect);
|
||||
|
||||
update_rect->x = 0;
|
||||
update_rect->y = 0;
|
||||
update_rect->w = canvas->w;
|
||||
update_rect->h = canvas->h;
|
||||
|
||||
SDL_FreeSurface(scaled_surf);
|
||||
|
||||
api->playsound(perspective_snd_effect[which], 127, 255);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (which != TOOL_PANELS)
|
||||
{
|
||||
perspective_drag(api, which, canvas, last, x, y, x, y, update_rect);
|
||||
}
|
||||
perspective_drag(api, which, canvas, last, x, y, x, y, update_rect);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -482,7 +532,6 @@ void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED,
|
|||
}
|
||||
}
|
||||
|
||||
// No setup happened:
|
||||
void perspective_shutdown(magic_api * api ATTRIBUTE_UNUSED)
|
||||
{
|
||||
//Clean up sounds
|
||||
|
|
@ -546,9 +595,13 @@ void perspective_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
|
|||
SDL_FreeSurface(canvas_back);
|
||||
}
|
||||
|
||||
int perspective_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
int perspective_modes(magic_api * api ATTRIBUTE_UNUSED, int which)
|
||||
{
|
||||
return (MODE_PAINT_WITH_PREVIEW);
|
||||
if (which == TOOL_PANELS) {
|
||||
return (MODE_FULLSCREEN);
|
||||
} else {
|
||||
return (MODE_PAINT_WITH_PREVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
void perspective_line(void *ptr_to_api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue