Added support for animated brushes.
This commit is contained in:
parent
44f0d728ed
commit
609a8d5104
5 changed files with 139 additions and 32 deletions
|
|
@ -1 +1 @@
|
||||||
frames=7
|
frames=6
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ http://www.newbreedsoftware.com/tuxpaint/
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
|
|
||||||
2006.September.2 (0.9.16)
|
2006.September.3 (0.9.16)
|
||||||
* Interface improvements:
|
* Interface improvements:
|
||||||
-----------------------
|
-----------------------
|
||||||
* New slideshow tool! ("Slides", available in "Open" dialog.)
|
* New slideshow tool! ("Slides", available in "Open" dialog.)
|
||||||
|
|
@ -68,6 +68,14 @@ $Id$
|
||||||
|
|
||||||
* Round erasers added.
|
* Round erasers added.
|
||||||
|
|
||||||
|
* Brushes may be animated.
|
||||||
|
(Create an image (W*N) x H in size (where N is number of frames),
|
||||||
|
then create a ".dat" file for the brush containing "frames=N".
|
||||||
|
|
||||||
|
* New Brushes:
|
||||||
|
------------
|
||||||
|
* Vines (animated)
|
||||||
|
|
||||||
* New Starter Images:
|
* New Starter Images:
|
||||||
-------------------
|
-------------------
|
||||||
* Shipwreck
|
* Shipwreck
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
bill@newbreedsoftware.com
|
bill@newbreedsoftware.com
|
||||||
http://www.newbreedsoftware.com/tuxpaint/
|
http://www.newbreedsoftware.com/tuxpaint/
|
||||||
|
|
||||||
June 14, 2002 - March 12, 2006
|
June 14, 2002 - September 3, 2006
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -119,16 +119,43 @@ Where Files Go
|
||||||
Brushes
|
Brushes
|
||||||
|
|
||||||
The brushes used for drawing with the 'Brush' and 'Lines' tools in
|
The brushes used for drawing with the 'Brush' and 'Lines' tools in
|
||||||
Tux Paint are simply greyscale PNG images.
|
Tux Paint are simply PNG image files.
|
||||||
|
|
||||||
The alpha (transparency) of the PNG image is used to determine the shape
|
The alpha (transparency) of the PNG image is used to determine the shape
|
||||||
of the brush, which means that the shape can be 'anti-aliased' and even
|
of the brush, which means that the shape can be 'anti-aliased' and even
|
||||||
partially-transparent!
|
partially-transparent!
|
||||||
|
|
||||||
|
Greyscale pixels in the brush PNG will be drawn using the
|
||||||
|
currently-selected color in Tux Paint. Color pixels will be tinted.
|
||||||
|
|
||||||
Brush images should be no wider than 40 pixels across and no taller than
|
Brush images should be no wider than 40 pixels across and no taller than
|
||||||
40 pixels high. (i.e., the maximum size can be 40 x 40.)
|
40 pixels high. (i.e., the maximum size can be 40 x 40.)
|
||||||
|
|
||||||
Just place them in the "brushes" directory.
|
Brush Options
|
||||||
|
|
||||||
|
Aside from a graphical shape, brushes can also be given other
|
||||||
|
attributes. To do this, you need to create a 'data file' for the
|
||||||
|
brush.
|
||||||
|
|
||||||
|
A brush data file is simply a text file containing the options.
|
||||||
|
|
||||||
|
The file has the same name as the PNG image, but a ".dat" extension.
|
||||||
|
(e.g., "brush.png"'s data file is the text file "brush.dat" in the
|
||||||
|
same directory.)
|
||||||
|
|
||||||
|
Animated Brushes
|
||||||
|
|
||||||
|
As of Tux Paint version 0.9.16, you may now create animated brushes.
|
||||||
|
As the brush is drawn, each frame of the animation is displayed.
|
||||||
|
|
||||||
|
Lay each frame out across a wide PNG image. For example, if your
|
||||||
|
brush is 30x30 and you have 5 frames, the image should be 150x30.
|
||||||
|
|
||||||
|
Add a line containing the line "frames=N" to the brush's data file,
|
||||||
|
where N is the number of frames in the brush.
|
||||||
|
|
||||||
|
Place the brush image PNGs (and any data text files) in the "brushes"
|
||||||
|
directory.
|
||||||
|
|
||||||
Note: If your new brushes all come out as solid squares or rectangles,
|
Note: If your new brushes all come out as solid squares or rectangles,
|
||||||
it's because you forgot to use alpha transparency! See the documentation
|
it's because you forgot to use alpha transparency! See the documentation
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ New Breed Software</p>
|
||||||
<p><a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a><br>
|
<p><a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a><br>
|
||||||
<a href="http://www.newbreedsoftware.com/tuxpaint/">http://www.newbreedsoftware.com/tuxpaint/</a></p>
|
<a href="http://www.newbreedsoftware.com/tuxpaint/">http://www.newbreedsoftware.com/tuxpaint/</a></p>
|
||||||
|
|
||||||
<p>June 14, 2002 - March 12, 2006</p>
|
<p>June 14, 2002 - September 3, 2006</p>
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
<hr size=2 noshade>
|
<hr size=2 noshade>
|
||||||
|
|
@ -187,7 +187,7 @@ effect.</p>
|
||||||
<h2>Brushes</h2>
|
<h2>Brushes</h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>The brushes used for drawing with the 'Brush' and 'Lines' tools in
|
<p>The brushes used for drawing with the 'Brush' and 'Lines' tools in
|
||||||
Tux Paint are simply greyscale PNG images.</p>
|
Tux Paint are simply PNG image files.</p>
|
||||||
|
|
||||||
<img src="images/brush_edit.png" width=123 height=147 alt="" align=right>
|
<img src="images/brush_edit.png" width=123 height=147 alt="" align=right>
|
||||||
|
|
||||||
|
|
@ -195,11 +195,45 @@ effect.</p>
|
||||||
of the brush, which means that the shape can be 'anti-aliased' and even
|
of the brush, which means that the shape can be 'anti-aliased' and even
|
||||||
partially-transparent!</p>
|
partially-transparent!</p>
|
||||||
|
|
||||||
|
<p>Greyscale pixels in the brush PNG will be drawn using the
|
||||||
|
currently-selected color in Tux Paint. Color pixels will be
|
||||||
|
tinted.</p>
|
||||||
|
|
||||||
<p>Brush images should be no wider than 40 pixels across and
|
<p>Brush images should be no wider than 40 pixels across and
|
||||||
no taller than 40 pixels high. (i.e., the maximum size
|
no taller than 40 pixels high. (i.e., the maximum size
|
||||||
can be 40 x 40.)</p>
|
can be 40 x 40.)</p>
|
||||||
|
|
||||||
<p>Just place them in the "<code><b>brushes</b></code>" directory.</p>
|
|
||||||
|
<h3>Brush Options</h3>
|
||||||
|
<blockquote>
|
||||||
|
<p>Aside from a graphical shape, brushes can also be given other
|
||||||
|
attributes. To do this, you need to create a 'data file'
|
||||||
|
for the brush.</p>
|
||||||
|
|
||||||
|
<p>A brush data file is simply a text file containing the options.</p>
|
||||||
|
|
||||||
|
<p>The file has the same name as the PNG image, but a "<code>.dat</code>"
|
||||||
|
extension. (e.g., "<code>brush.png</code>"'s data file is the text
|
||||||
|
file "<code>brush.dat</code>" in the same directory.)</p>
|
||||||
|
|
||||||
|
<h4>Animated Brushes</h4>
|
||||||
|
<blockquote>
|
||||||
|
<p>As of Tux Paint version 0.9.16, you may now create animated
|
||||||
|
brushes. As the brush is drawn, each frame of the animation is
|
||||||
|
displayed.</p>
|
||||||
|
|
||||||
|
<p>Lay each frame out across a wide PNG image. For example,
|
||||||
|
if your brush is 30x30 and you have 5 frames, the image should
|
||||||
|
be 150x30.</p>
|
||||||
|
|
||||||
|
<p>Add a line containing the line "<code><b>frames=<i>N</i></b></code>"
|
||||||
|
to the brush's data file, where <i>N</i> is the number of frames
|
||||||
|
in the brush.</p>
|
||||||
|
</blockquote>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>Place the brush image PNGs (and any data text files) in the
|
||||||
|
"<code><b>brushes</b></code>" directory.</p>
|
||||||
|
|
||||||
<p>Note: If your new brushes all come out as solid squares or rectangles,
|
<p>Note: If your new brushes all come out as solid squares or rectangles,
|
||||||
it's because you forgot to use alpha transparency! See the documentation
|
it's because you forgot to use alpha transparency! See the documentation
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
(See COPYING.txt)
|
(See COPYING.txt)
|
||||||
|
|
||||||
June 14, 2002 - August 28, 2006
|
June 14, 2002 - September 3, 2006
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -972,7 +972,8 @@ static SDL_Surface *img_color_btn_off;
|
||||||
static int colors_are_selectable;
|
static int colors_are_selectable;
|
||||||
|
|
||||||
static SDL_Surface *img_cur_brush;
|
static SDL_Surface *img_cur_brush;
|
||||||
static int brush_counter, rainbow_color;
|
int img_cur_brush_w, img_cur_brush_h, img_cur_brush_frames;
|
||||||
|
static int brush_counter, rainbow_color, brush_frame;
|
||||||
|
|
||||||
#define NUM_ERASERS 12 /* How many sizes of erasers
|
#define NUM_ERASERS 12 /* How many sizes of erasers
|
||||||
(from ERASER_MIN to _MAX as squares, then again
|
(from ERASER_MIN to _MAX as squares, then again
|
||||||
|
|
@ -1070,6 +1071,9 @@ static void rect_xor(int x1, int y1, int x2, int y2);
|
||||||
static void draw_blinking_cursor(void);
|
static void draw_blinking_cursor(void);
|
||||||
static void hide_blinking_cursor(void);
|
static void hide_blinking_cursor(void);
|
||||||
|
|
||||||
|
void reset_brush_counter_and_frame(void);
|
||||||
|
void reset_brush_counter(void);
|
||||||
|
|
||||||
#ifdef LOW_QUALITY_STAMP_OUTLINE
|
#ifdef LOW_QUALITY_STAMP_OUTLINE
|
||||||
#define stamp_xor(x,y) rect_xor( \
|
#define stamp_xor(x,y) rect_xor( \
|
||||||
(x) - (CUR_STAMP_W+1)/2, \
|
(x) - (CUR_STAMP_W+1)/2, \
|
||||||
|
|
@ -2635,10 +2639,10 @@ static void mainloop(void)
|
||||||
rec_undo_buffer();
|
rec_undo_buffer();
|
||||||
|
|
||||||
/* (Arbitrarily large, so we draw once now) */
|
/* (Arbitrarily large, so we draw once now) */
|
||||||
brush_counter = 999;
|
reset_brush_counter();
|
||||||
|
|
||||||
brush_draw(old_x, old_y, old_x, old_y, 1);
|
brush_draw(old_x, old_y, old_x, old_y, 1);
|
||||||
playsound(screen, 0, SND_PAINT1 + (img_cur_brush->w) / 12, 1,
|
playsound(screen, 0, SND_PAINT1 + (img_cur_brush_w) / 12, 1,
|
||||||
event.button.x, SNDDIST_NEAR);
|
event.button.x, SNDDIST_NEAR);
|
||||||
}
|
}
|
||||||
else if (cur_tool == TOOL_STAMP)
|
else if (cur_tool == TOOL_STAMP)
|
||||||
|
|
@ -2667,7 +2671,7 @@ static void mainloop(void)
|
||||||
line_start_y = old_y;
|
line_start_y = old_y;
|
||||||
|
|
||||||
/* (Arbitrarily large, so we draw once now) */
|
/* (Arbitrarily large, so we draw once now) */
|
||||||
brush_counter = 999;
|
reset_brush_counter();
|
||||||
|
|
||||||
brush_draw(old_x, old_y, old_x, old_y, 1);
|
brush_draw(old_x, old_y, old_x, old_y, 1);
|
||||||
|
|
||||||
|
|
@ -2697,7 +2701,7 @@ static void mainloop(void)
|
||||||
/* Draw the shape with the brush! */
|
/* Draw the shape with the brush! */
|
||||||
|
|
||||||
/* (Arbitrarily large...) */
|
/* (Arbitrarily large...) */
|
||||||
brush_counter = 999;
|
reset_brush_counter();
|
||||||
|
|
||||||
playsound(screen, 1, SND_LINE_END, 1, event.button.x,
|
playsound(screen, 1, SND_LINE_END, 1, event.button.x,
|
||||||
SNDDIST_NEAR);
|
SNDDIST_NEAR);
|
||||||
|
|
@ -2728,7 +2732,7 @@ static void mainloop(void)
|
||||||
|
|
||||||
|
|
||||||
/* (Arbitrarily large, so we draw once now) */
|
/* (Arbitrarily large, so we draw once now) */
|
||||||
brush_counter = 999;
|
reset_brush_counter();
|
||||||
|
|
||||||
if (cur_magic != MAGIC_FILL)
|
if (cur_magic != MAGIC_FILL)
|
||||||
{
|
{
|
||||||
|
|
@ -2975,7 +2979,7 @@ static void mainloop(void)
|
||||||
if (cur_tool == TOOL_LINES)
|
if (cur_tool == TOOL_LINES)
|
||||||
{
|
{
|
||||||
/* (Arbitrarily large, so we draw once now) */
|
/* (Arbitrarily large, so we draw once now) */
|
||||||
brush_counter = 999;
|
reset_brush_counter();
|
||||||
|
|
||||||
brush_draw(line_start_x, line_start_y,
|
brush_draw(line_start_x, line_start_y,
|
||||||
event.button.x - r_canvas.x,
|
event.button.x - r_canvas.x,
|
||||||
|
|
@ -3028,7 +3032,7 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
brush_counter = 999; /* arbitrarily large... */
|
reset_brush_counter();
|
||||||
|
|
||||||
|
|
||||||
playsound(screen, 1, SND_LINE_END, 1, event.button.x,
|
playsound(screen, 1, SND_LINE_END, 1, event.button.x,
|
||||||
|
|
@ -3191,7 +3195,7 @@ static void mainloop(void)
|
||||||
|
|
||||||
brush_draw(old_x, old_y, new_x, new_y, 1);
|
brush_draw(old_x, old_y, new_x, new_y, 1);
|
||||||
|
|
||||||
playsound(screen, 0, SND_PAINT1 + (img_cur_brush->w) / 12, 0,
|
playsound(screen, 0, SND_PAINT1 + (img_cur_brush_w) / 12, 0,
|
||||||
event.button.x, SNDDIST_NEAR);
|
event.button.x, SNDDIST_NEAR);
|
||||||
}
|
}
|
||||||
else if (cur_tool == TOOL_LINES)
|
else if (cur_tool == TOOL_LINES)
|
||||||
|
|
@ -3483,23 +3487,43 @@ static void brush_draw(int x1, int y1, int x2, int y2, int update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_brush_counter_and_frame(void)
|
||||||
|
{
|
||||||
|
brush_counter = 999;
|
||||||
|
brush_frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_brush_counter(void)
|
||||||
|
{
|
||||||
|
brush_counter = 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Draw the current brush in the current color: */
|
/* Draw the current brush in the current color: */
|
||||||
|
|
||||||
static void blit_brush(int x, int y)
|
static void blit_brush(int x, int y)
|
||||||
{
|
{
|
||||||
SDL_Rect dest;
|
SDL_Rect src, dest;
|
||||||
|
|
||||||
brush_counter++;
|
brush_counter++;
|
||||||
|
|
||||||
if (brush_counter >= (img_cur_brush->h / 4))
|
if (brush_counter >= (img_cur_brush_h / 4))
|
||||||
{
|
{
|
||||||
brush_counter = 0;
|
brush_counter = 0;
|
||||||
|
|
||||||
|
brush_frame++;
|
||||||
|
if (brush_frame > img_cur_brush_frames)
|
||||||
|
brush_frame = 0;
|
||||||
|
|
||||||
dest.x = x;
|
dest.x = x;
|
||||||
dest.y = y;
|
dest.y = y;
|
||||||
|
|
||||||
SDL_BlitSurface(img_cur_brush, NULL, canvas, &dest);
|
src.x = brush_frame * img_cur_brush_w;
|
||||||
|
src.y = 0;
|
||||||
|
src.w = img_cur_brush_w;
|
||||||
|
src.h = img_cur_brush_h;
|
||||||
|
|
||||||
|
SDL_BlitSurface(img_cur_brush, &src, canvas, &dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5165,14 +5189,13 @@ static void loadbrush_callback(SDL_Surface * screen,
|
||||||
|
|
||||||
/* Load brush metadata, if any: */
|
/* Load brush metadata, if any: */
|
||||||
|
|
||||||
|
brushes_frames[num_brushes] = 1;
|
||||||
|
brushes_directional[num_brushes] = 0;
|
||||||
|
|
||||||
strcpy(strcasestr(fname, ".png"), ".dat");
|
strcpy(strcasestr(fname, ".png"), ".dat");
|
||||||
fi = fopen(fname, "r");
|
fi = fopen(fname, "r");
|
||||||
if (fi == NULL)
|
|
||||||
{
|
if (fi != NULL)
|
||||||
brushes_frames[num_brushes] = 1;
|
|
||||||
brushes_directional[num_brushes] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
@ -8533,17 +8556,32 @@ static void render_brush(void)
|
||||||
SDL_GetRGBA(getpixel_brush(img_brushes[cur_brush], x, y),
|
SDL_GetRGBA(getpixel_brush(img_brushes[cur_brush], x, y),
|
||||||
img_brushes[cur_brush]->format, &r, &g, &b, &a);
|
img_brushes[cur_brush]->format, &r, &g, &b, &a);
|
||||||
|
|
||||||
putpixel_brush(img_cur_brush, x, y,
|
if (r == g && g == b)
|
||||||
SDL_MapRGBA(img_cur_brush->format,
|
{
|
||||||
color_hexes[cur_color][0],
|
putpixel_brush(img_cur_brush, x, y,
|
||||||
color_hexes[cur_color][1],
|
SDL_MapRGBA(img_cur_brush->format,
|
||||||
color_hexes[cur_color][2], a));
|
color_hexes[cur_color][0],
|
||||||
|
color_hexes[cur_color][1],
|
||||||
|
color_hexes[cur_color][2], a));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putpixel_brush(img_cur_brush, x, y,
|
||||||
|
SDL_MapRGBA(img_cur_brush->format,
|
||||||
|
(r + color_hexes[cur_color][0]) >> 1,
|
||||||
|
(g + color_hexes[cur_color][1]) >> 1,
|
||||||
|
(b + color_hexes[cur_color][2]) >> 1, a));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_UnlockSurface(img_cur_brush);
|
SDL_UnlockSurface(img_cur_brush);
|
||||||
SDL_UnlockSurface(img_brushes[cur_brush]);
|
SDL_UnlockSurface(img_brushes[cur_brush]);
|
||||||
|
|
||||||
|
img_cur_brush_w = img_cur_brush->w / brushes_frames[cur_brush];
|
||||||
|
img_cur_brush_h = img_cur_brush->h / (brushes_directional[cur_brush] ? 3 : 1);
|
||||||
|
img_cur_brush_frames = brushes_frames[cur_brush];
|
||||||
|
|
||||||
brush_counter = 0;
|
brush_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue