Syncing tp_magic_example.c (indent & transliteration)
This commit is contained in:
parent
bd10e955a1
commit
51d47d554e
14 changed files with 2058 additions and 1988 deletions
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // Fyrir "strdup()"
|
||||
#include <libintl.h> // Fyrir "gettext()"
|
||||
#include <string.h> // Fyrir "strdup()"
|
||||
#include <libintl.h> // Fyrir "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_drag(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
SDL_Surface * skjamynd, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int x, int y);
|
||||
SDL_Surface * skjamynd, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int hamur)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int hamur,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, skjamynd, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int hamur,
|
|||
void
|
||||
example_drag(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * skjamynd,
|
||||
int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(skjamynd);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, skjamynd,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(skjamynd);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_staerd;
|
||||
update_rect->y = old_y - example_staerd;
|
||||
update_rect->w = (x + example_staerd) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* vinstri/hægri hliðrun */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* vinstri/hægri hliðrun */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * skjamynd, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * skjamynd, Uint8 staerd, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * skjamynd,
|
||||
Uint8 staerd, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_staerd = staerd * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int x, int y)
|
||||
SDL_Surface * skjamynd, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_staerd; yy < example_staerd; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
skjamynd->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // Fyrir "strdup()"
|
||||
#include <libintl.h> // Fyrir "gettext()"
|
||||
#include <string.h> // Fyrir "strdup()"
|
||||
#include <libintl.h> // Fyrir "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_drag(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
SDL_Surface * skjamynd, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int x, int y);
|
||||
SDL_Surface * skjamynd, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int hamur)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int hamur,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, skjamynd, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int hamur,
|
|||
void
|
||||
example_drag(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * skjamynd,
|
||||
int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(skjamynd);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, skjamynd,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(skjamynd);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_staerd;
|
||||
update_rect->y = old_y - example_staerd;
|
||||
update_rect->w = (x + example_staerd) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* vinstri/hægri hliðrun */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* vinstri/hægri hliðrun */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * skjamynd, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * skjamynd, Uint8 staerd, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * skjamynd,
|
||||
Uint8 staerd, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_staerd = staerd * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * skjamynd, int x, int y)
|
||||
SDL_Surface * skjamynd, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_staerd; yy < example_staerd; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
skjamynd->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
#include <string.h> // For "strdup()"
|
||||
#include <libintl.h> // For "gettext()"
|
||||
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header
|
||||
#include "SDL_image.h" // For IMG_Load(), to load our PNG icon
|
||||
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
|
||||
|
||||
|
||||
/* Tool Enumerations: */
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
enum
|
||||
{
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
TOOL_ONE, // Becomes '0'
|
||||
TOOL_TWO, // Becomes '1'
|
||||
NUM_TOOLS // Becomes '2'
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ _before_ them.
|
|||
*/
|
||||
|
||||
void example_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_Surface * snapshot, int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
|
||||
|
||||
/* Setup Functions: */
|
||||
|
|
@ -144,7 +144,8 @@ released, aka deallocated) when the user quits Tux Paint, when our
|
|||
example_shutdown() function is called.
|
||||
*/
|
||||
|
||||
int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level)
|
||||
int example_init(magic_api * api, Uint8 disabled_features,
|
||||
Uint8 complexity_level)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
|
@ -152,15 +153,15 @@ int example_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_leve
|
|||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
{
|
||||
/*
|
||||
Assemble the filename from the "sound_filenames[]" array into a full path
|
||||
to a real file.
|
||||
Assemble the filename from the "sound_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(filename, sizeof(filename), "%ssounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
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(filename, sizeof(filename), "%ssounds/magic/%s",
|
||||
api->data_directory, sound_filenames[i]);
|
||||
|
||||
printf("Trying to load %s sound file\n", filename);
|
||||
|
||||
|
|
@ -200,16 +201,16 @@ SDL_Surface *example_get_icon(magic_api * api, int which)
|
|||
char filename[1024];
|
||||
|
||||
/*
|
||||
Assemble the filename from the "icon_filenames[]" array into a full path to
|
||||
a real file.
|
||||
Assemble the filename from the "icon_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.)
|
||||
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.)
|
||||
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use "which" (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
snprintf(filename, sizeof(filename), "%simages/magic/%s",
|
||||
api->data_directory, icon_filenames[which]);
|
||||
|
||||
|
|
@ -229,31 +230,31 @@ names (labels) for the 'Magic' tool buttons.
|
|||
*/
|
||||
char *example_get_name(magic_api * api, int which)
|
||||
{
|
||||
const char *our_name_english;
|
||||
const char *our_name_english;
|
||||
const char *our_name_localized;
|
||||
|
||||
/*
|
||||
Get our name from the "tool_names[]" array.
|
||||
Get our name from the "tool_names[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_name_english = tool_names[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
Return a localized (aka translated) version of our name, if possible.
|
||||
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
We send "gettext()" the English version of the name from our array.
|
||||
*/
|
||||
our_name_localized = gettext(our_name_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
return (strdup(our_name_localized));
|
||||
}
|
||||
|
||||
|
|
@ -267,11 +268,11 @@ where the tool should be grouped.
|
|||
int example_get_group(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
Return our group, found in the "tool_groups[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
return (tool_groups[which]);
|
||||
}
|
||||
|
||||
|
|
@ -302,28 +303,28 @@ char *example_get_description(magic_api * api, int which, int mode)
|
|||
const char *our_desc_localized;
|
||||
|
||||
/*
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
Get our description from the "tool_descriptions[]" array.
|
||||
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
We use 'which' (which of our tools Tux Paint is asking about) as an index
|
||||
into the array.
|
||||
*/
|
||||
our_desc_english = tool_descriptions[which];
|
||||
|
||||
|
||||
/*
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
Return a localized (aka translated) version of our description, if
|
||||
possible.
|
||||
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
We send "gettext" the English version of the description from our array.
|
||||
*/
|
||||
our_desc_localized = gettext(our_desc_english);
|
||||
|
||||
|
||||
/*
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
Finally, duplicate the string into a new section of memory, and send it to
|
||||
Tux Paint. (Tux Paint keeps track of the string and will free it for us,
|
||||
so we have one less thing to keep track of.)
|
||||
*/
|
||||
|
||||
return (strdup(our_desc_localized));
|
||||
}
|
||||
|
|
@ -345,9 +346,9 @@ int example_requires_colors(magic_api * api, int which)
|
|||
int example_modes(magic_api * api, int which)
|
||||
{
|
||||
/*
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
Both of our tools are painted (neither affect the full-screen), so we're
|
||||
always returning 'MODE_PAINT'
|
||||
*/
|
||||
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
|
@ -385,9 +386,9 @@ void example_shutdown(magic_api * api)
|
|||
int i;
|
||||
|
||||
/*
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
Free (aka release, aka deallocate) the memory used to store the sound
|
||||
effects that we loaded during example_init():
|
||||
*/
|
||||
for (i = 0; i < NUM_TOOLS; i++)
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
|
|
@ -404,13 +405,13 @@ example_click(magic_api * api, int which, int mode,
|
|||
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 than across
|
||||
a line.
|
||||
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 than across
|
||||
a line.
|
||||
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
So we 'cheat' here, by calling our "example_draw()" function with (x,y) for
|
||||
both the beginning and end points of a line.
|
||||
*/
|
||||
|
||||
example_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
|
||||
}
|
||||
|
|
@ -420,34 +421,32 @@ example_click(magic_api * api, int which, int mode,
|
|||
void
|
||||
example_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)
|
||||
int old_x, int old_y, int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
Call Tux Paint's "line()" (line-traversing) function.
|
||||
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
It will calculate a straight line between (old_x,old_y) and (x,y). Every
|
||||
N steps along that line (in this case, N is '1'), it will call _our_
|
||||
function, "example_line_callback()", and send the current X,Y
|
||||
coordinates along the line, as well as other useful things (which of our
|
||||
'Magic' tools is being used and the current and snapshot canvases).
|
||||
*/
|
||||
SDL_LockSurface(snapshot);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line((void *) api, which, canvas, snapshot,
|
||||
old_x, old_y, x, y, 1,
|
||||
example_line_callback);
|
||||
old_x, old_y, x, y, 1, example_line_callback);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(snapshot);
|
||||
|
||||
/*
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
If we need to, swap the X and/or Y values, so that the coordinates
|
||||
(old_x,old_y) is always the top left, and the coordinates (x,y) is
|
||||
always the bottom right, so the values we put inside "update_rect" make
|
||||
sense:
|
||||
*/
|
||||
|
||||
if (old_x > x)
|
||||
{
|
||||
|
|
@ -466,17 +465,20 @@ example_drag(magic_api * api, int which,
|
|||
|
||||
|
||||
/*
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
Fill in the elements of the "update_rect" SDL_Rect structure that Tux
|
||||
Paint is sharing with us, therefore telling Tux Paint which part of the
|
||||
canvas has been modified and should be updated.
|
||||
*/
|
||||
|
||||
if (which == TOOL_ONE) {
|
||||
if (which == TOOL_ONE)
|
||||
{
|
||||
update_rect->x = old_x;
|
||||
update_rect->y = old_y;
|
||||
update_rect->w = (x - old_x) + 1;
|
||||
update_rect->h = (y - old_y) + 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rect->x = old_x - example_size;
|
||||
update_rect->y = old_y - example_size;
|
||||
update_rect->w = (x + example_size) - update_rect->x + 1;
|
||||
|
|
@ -484,19 +486,18 @@ example_drag(magic_api * api, int which,
|
|||
}
|
||||
|
||||
/*
|
||||
Play the appropriate sound effect
|
||||
Play the appropriate sound effect
|
||||
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
We're calculating a value between 0-255 for where the mouse is
|
||||
horizontally across the canvas (0 is the left, ~128 is the center, 255
|
||||
is the right).
|
||||
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which],
|
||||
(x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */);
|
||||
These are the exact values Tux Paint's "playsound()" wants, to determine
|
||||
what speaker to play the sound in. (So the sound will pan from speaker
|
||||
to speaker as you drag the mouse around the canvas!)
|
||||
*/
|
||||
api->playsound(sound_effects[which], (x * 255) / canvas->w, /* Left/right pan */
|
||||
255 /* Near/far distance (loudness) */ );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,9 +509,9 @@ example_release(magic_api * api, int which,
|
|||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -526,12 +527,14 @@ changes their chosen, we'll be informed of that as well.
|
|||
The color comes in as RGB (red, green, and blue) values from 0 (darkest) to
|
||||
255 (brightest).
|
||||
*/
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b, SDL_Rect * update_rect)
|
||||
void example_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
We simply store the RGB values in the global variables we declared at
|
||||
the top of this file.
|
||||
*/
|
||||
|
||||
example_r = r;
|
||||
example_g = g;
|
||||
|
|
@ -551,12 +554,14 @@ that as well.
|
|||
The size comes in as an unsigned integer (Uint8) between 1 and the value
|
||||
returned by our example_accepted_sizes() function during setup.
|
||||
*/
|
||||
void example_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, Uint8 size, SDL_Rect * update_rect)
|
||||
void example_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
Uint8 size, SDL_Rect * update_rect)
|
||||
{
|
||||
/*
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
Store the new size into the global variable we declared at the top of
|
||||
this file.
|
||||
*/
|
||||
|
||||
example_size = size * 4;
|
||||
}
|
||||
|
|
@ -580,51 +585,51 @@ Our callback pays attention to 'which' to determine which of our plugin's
|
|||
tools is currently selected.
|
||||
*/
|
||||
void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
SDL_Surface * snapshot, int x, int y)
|
||||
{
|
||||
/*
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
For technical reasons, we can't accept a pointer to the Tux Paint API's
|
||||
"magic_api" struct, like the other functions do.
|
||||
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
Instead, we receive a 'generic' pointer (a "void *"). The line below
|
||||
declares a local "magic_api" pointer variable called "api", and then
|
||||
assigns it to the value of the 'generic' pointer we received.
|
||||
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
The "(magic_api *)" seen below casts the generic "void *" pointer into
|
||||
the 'type' of pointer we want, a pointer to a "magic_api" struct.)
|
||||
*/
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
int xx, yy;
|
||||
|
||||
/*
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that Tux Paint
|
||||
sends to us with the values we enumerated above.
|
||||
*/
|
||||
This function handles both of our tools, so we need to check which is
|
||||
being used right now. We compare the 'which' argument that 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 acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
Tool number 1 simply draws a single pixel at the (x,y) location. It acts
|
||||
as a 1x1 pixel brush.
|
||||
*/
|
||||
|
||||
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 a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
Tool number 2 copies a square of pixels (of the size chosen by the user)
|
||||
from the opposite side of the canvas and puts it under the cursor.
|
||||
*/
|
||||
|
||||
for (yy = -example_size; yy < example_size; yy++)
|
||||
{
|
||||
|
|
@ -636,14 +641,14 @@ void example_line_callback(void *pointer, int which, SDL_Surface * canvas,
|
|||
snapshot->h - y - yy));
|
||||
|
||||
/*
|
||||
Here we have simply use Tux Paint's "getpixel()" routine to pull pixel
|
||||
values from the 'snapshot', and then "putpixel()" to draw them right
|
||||
into the 'canvas'.
|
||||
Here we have 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 and/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 and/or height).
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue