Indentation.

This commit is contained in:
Pere Pujal i Carabantes 2017-12-19 02:17:27 +01:00
commit 1e0ea6d4b3
94 changed files with 26586 additions and 26244 deletions

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
*.o
*.so
tuxpaint
obj/parse.c
obj/parse_step1.c
src/tp_magic_api.h
tp-magic-config
trans/
*~

View file

@ -10,6 +10,7 @@ $Id$
2017.xxx.x (0.9.23) 2017.xxx.x (0.9.23)
* New tools * New tools
---------
* Color selector * Color selector
Pere Pujal i Carabantes Pere Pujal i Carabantes
@ -102,6 +103,11 @@ $Id$
the program will crash the program will crash
(SF.net Bug #210) (SF.net Bug #210)
* Other Improvements:
-------------------
* Reformatted source code via GNU Indent tool; should
greatly increase code readability and formatting consistency.
2014.August.5 (0.9.22) 2014.August.5 (0.9.22)
* New Tools: * New Tools:

View file

@ -11,9 +11,10 @@ static TYPE x UNUSED;
#endif #endif
#ifdef SYMBOL #ifdef SYMBOL
static int exists UNUSED = !!SYMBOL; static int exists UNUSED = ! !SYMBOL;
#endif #endif
int main(int argc UNUSED, char *argv[] UNUSED){ int main(int argc UNUSED, char *argv[]UNUSED)
return 0; {
return 0;
} }

1
macosx/.indent.pro vendored Symbolic link
View file

@ -0,0 +1 @@
../src/.indent.pro

View file

@ -12,34 +12,37 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "TransparentTextView.h" #import "TransparentTextView.h"
@interface SDLMain : NSObject @ interface SDLMain:NSObject
{ {
IBOutlet NSWindow *messagePanel; IBOutlet NSWindow *messagePanel;
IBOutlet NSTextField *messageText; IBOutlet NSTextField *messageText;
IBOutlet NSTextField *messageStatus; IBOutlet NSTextField *messageStatus;
IBOutlet NSProgressIndicator *messageProgress; IBOutlet NSProgressIndicator *messageProgress;
IBOutlet NSWindow *aboutWindow; IBOutlet NSWindow *aboutWindow;
IBOutlet NSTextField *appnameText; IBOutlet NSTextField *appnameText;
IBOutlet NSTextField *versionText; IBOutlet NSTextField *versionText;
IBOutlet TransparentTextView *acknowledgmentsText; IBOutlet TransparentTextView *acknowledgmentsText;
} }
- (IBAction)onAbout:(id)sender; -(IBAction) onAbout:(id) sender;
- (IBAction)onNew:(id)sender; -(IBAction) onNew:(id) sender;
- (IBAction)onOpen:(id)sender; -(IBAction) onOpen:(id) sender;
- (IBAction)onSave:(id)sender; -(IBAction) onSave:(id) sender;
- (IBAction)onPrint:(id)sender; -(IBAction) onPrint:(id) sender;
- (IBAction)onPageSetup:(id)sender; -(IBAction) onPageSetup:(id) sender;
- (IBAction)onUndo:(id)sender; -(IBAction) onUndo:(id) sender;
- (IBAction)onRedo:(id)sender; -(IBAction) onRedo:(id) sender;
- (IBAction)onHelp:(id)sender; -(IBAction) onHelp:(id) sender;
- (IBAction)onQuit:(id)sender; -(IBAction) onQuit:(id) sender;
- (void) sendSDLControlKeystroke:(int)key; -(void)sendSDLControlKeystroke:(int)key;
- (void) sendSDLControlShiftKeystroke:(int)key; -(void)sendSDLControlShiftKeystroke:(int)key;
- (void) setupBridge; -(void)setupBridge;
- (void) displayMessage:(NSString*)message andStatus:(NSString*)status withProgressIndicator:(BOOL)progress; -(void)displayMessage:(NSString *)
- (void) hideMessage; message andStatus:(NSString *)
status withProgressIndicator:(BOOL) progress;
-(void)hideMessage;
@end @end

View file

@ -23,5 +23,5 @@
#define MSG_FONT_CACHE 1 #define MSG_FONT_CACHE 1
void displayMessage( int msgId ); void displayMessage(int msgId);
void hideMessage(); void hideMessage();

View file

@ -17,42 +17,42 @@
// missing from wchar.h on Mac // missing from wchar.h on Mac
wchar_t* wcsdup(const wchar_t* ws) wchar_t *wcsdup(const wchar_t * ws)
{ {
wchar_t *ret; wchar_t *ret;
size_t len; size_t len;
len = wcslen (ws); len = wcslen(ws);
ret = malloc ((len + 1) * sizeof (wchar_t)); ret = malloc((len + 1) * sizeof(wchar_t));
if (ret == 0) if (ret == 0)
return ret; return ret;
return (wcscpy (ret, ws)); return (wcscpy(ret, ws));
} }
// missing, needed by __nl_find_msg in libintl.a(dcigettext.o) // missing, needed by __nl_find_msg in libintl.a(dcigettext.o)
// http://forums.macrumors.com/showthread.php?t=1284479 // http://forums.macrumors.com/showthread.php?t=1284479
#undef iconv_t #undef iconv_t
typedef void* iconv_t; typedef void *iconv_t;
extern size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); extern size_t libiconv(iconv_t cd, char * *inbuf, size_t * inbytesleft, char * *outbuf, size_t * outbytesleft);
extern iconv_t libiconv_open(const char* tocode, const char* fromcode); extern iconv_t libiconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) size_t iconv(iconv_t cd, char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft)
{ {
return libiconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); return libiconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);
} }
iconv_t iconv_open(const char *tocode, const char *fromcode) iconv_t iconv_open(const char *tocode, const char *fromcode)
{ {
return libiconv_open(tocode, fromcode); return libiconv_open(tocode, fromcode);
} }
// to fix ineffective setlocale() in i18n.c or force language to Inuktitut // to fix ineffective setlocale() in i18n.c or force language to Inuktitut
// must be called prior to setup_i18n() // must be called prior to setup_i18n()
patch_i18n(const char* locale) patch_i18n(const char *locale)
{ {
setenv("LANG", locale, 1); // takes language passed as an argument setenv("LANG", locale, 1); // takes language passed as an argument
// setenv("LANG", "iu_CA.UTF-8", 1); // forces language to Inuktitut // setenv("LANG", "iu_CA.UTF-8", 1); // forces language to Inuktitut
} }
@ -62,282 +62,283 @@ patch_i18n(const char* locale)
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/int_lib.h // http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/int_lib.h
#include <limits.h> #include <limits.h>
typedef unsigned su_int; typedef unsigned su_int;
typedef long long di_int; typedef long long di_int;
typedef unsigned long long du_int; typedef unsigned long long du_int;
#ifdef __i386__ #ifdef __i386__
typedef int ti_int __attribute__ ((mode (DI))); typedef int ti_int __attribute__ ((mode(DI)));
typedef unsigned tu_int __attribute__ ((mode (DI))); typedef unsigned tu_int __attribute__ ((mode(DI)));
#else #else
typedef int ti_int __attribute__ ((mode (TI))); typedef int ti_int __attribute__ ((mode(TI)));
typedef unsigned tu_int __attribute__ ((mode (TI))); typedef unsigned tu_int __attribute__ ((mode(TI)));
#endif #endif
typedef union typedef union
{ {
tu_int all; tu_int all;
struct struct
{ {
#if _YUGA_LITTLE_ENDIAN #if _YUGA_LITTLE_ENDIAN
du_int low; du_int low;
du_int high; du_int high;
#else #else
du_int high; du_int high;
du_int low; du_int low;
#endif /* _YUGA_LITTLE_ENDIAN */ #endif /* _YUGA_LITTLE_ENDIAN */
}s; } s;
} utwords; } utwords;
// missing, needed by __umodti3 and __udivti3 // missing, needed by __umodti3 and __udivti3
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivmodti4.c // http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivmodti4.c
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem) tu_int __udivmodti4(tu_int a, tu_int b, tu_int * rem)
{ {
const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT; const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
utwords n; utwords n;
n.all = a;
utwords d; n.all = a;
d.all = b; utwords d;
utwords q;
utwords r; d.all = b;
unsigned sr; utwords q;
/* special cases, X is unknown, K != 0 */ utwords r;
if (n.s.high == 0) unsigned sr;
/* special cases, X is unknown, K != 0 */
if (n.s.high == 0)
{ {
if (d.s.high == 0) if (d.s.high == 0)
{ {
/* 0 X /* 0 X
* --- * ---
* 0 X * 0 X
*/ */
if (rem) if (rem)
*rem = n.s.low % d.s.low; *rem = n.s.low % d.s.low;
return n.s.low / d.s.low; return n.s.low / d.s.low;
} }
/* 0 X /* 0 X
* --- * ---
* K X * K X
*/ */
if (rem) if (rem)
*rem = n.s.low; *rem = n.s.low;
return 0; return 0;
} }
/* n.s.high != 0 */ /* n.s.high != 0 */
if (d.s.low == 0) if (d.s.low == 0)
{ {
if (d.s.high == 0) if (d.s.high == 0)
{ {
/* K X /* K X
* --- * ---
* 0 0 * 0 0
*/ */
if (rem) if (rem)
*rem = n.s.high % d.s.low; *rem = n.s.high % d.s.low;
return n.s.high / d.s.low; return n.s.high / d.s.low;
} }
/* d.s.high != 0 */ /* d.s.high != 0 */
if (n.s.low == 0) if (n.s.low == 0)
{ {
/* K 0 /* K 0
* --- * ---
* K 0 * K 0
*/ */
if (rem) if (rem)
{ {
r.s.high = n.s.high % d.s.high; r.s.high = n.s.high % d.s.high;
r.s.low = 0; r.s.low = 0;
*rem = r.all; *rem = r.all;
} }
return n.s.high / d.s.high; return n.s.high / d.s.high;
} }
/* K K /* K K
* --- * ---
* K 0 * K 0
*/ */
if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
{ {
if (rem) if (rem)
{ {
r.s.low = n.s.low; r.s.low = n.s.low;
r.s.high = n.s.high & (d.s.high - 1); r.s.high = n.s.high & (d.s.high - 1);
*rem = r.all; *rem = r.all;
} }
return n.s.high >> __builtin_ctzll(d.s.high); return n.s.high >> __builtin_ctzll(d.s.high);
} }
/* K K /* K K
* --- * ---
* K 0 * K 0
*/ */
sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high); sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
/* 0 <= sr <= n_udword_bits - 2 or sr large */ /* 0 <= sr <= n_udword_bits - 2 or sr large */
if (sr > n_udword_bits - 2) if (sr > n_udword_bits - 2)
{ {
if (rem) if (rem)
*rem = n.all;
return 0;
}
++sr;
/* 1 <= sr <= n_udword_bits - 1 */
/* q.all = n.all << (n_utword_bits - sr); */
q.s.low = 0;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr; */
r.s.high = n.s.high >> sr;
r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
}
else /* d.s.low != 0 */
{
if (d.s.high == 0)
{
/* K X
* ---
* 0 K
*/
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
{
if (rem)
*rem = n.s.low & (d.s.low - 1);
if (d.s.low == 1)
return n.all;
unsigned sr = __builtin_ctzll(d.s.low);
q.s.high = n.s.high >> sr;
q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
return q.all;
}
/* K X
* ---
* 0 K
*/
sr = 1 + n_udword_bits + __builtin_clzll(d.s.low) - __builtin_clzll(n.s.high);
/* 2 <= sr <= n_utword_bits - 1
* q.all = n.all << (n_utword_bits - sr);
* r.all = n.all >> sr;
* if (sr == n_udword_bits)
* {
* q.s.low = 0;
* q.s.high = n.s.low;
* r.s.high = 0;
* r.s.low = n.s.high;
* }
* else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
* {
* q.s.low = 0;
* q.s.high = n.s.low << (n_udword_bits - sr);
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
* {
* q.s.low = n.s.low << (n_utword_bits - sr);
* q.s.high = (n.s.high << (n_utword_bits - sr)) |
* (n.s.low >> (sr - n_udword_bits));
* r.s.high = 0;
* r.s.low = n.s.high >> (sr - n_udword_bits);
* }
*/
q.s.low = (n.s.low << (n_utword_bits - sr)) & ((di_int) (int)(n_udword_bits - sr) >> (n_udword_bits - 1));
q.s.high = ((n.s.low << (n_udword_bits - sr)) &
((di_int) (int)(sr - n_udword_bits - 1) >> (n_udword_bits - 1))) |
(((n.s.high << (n_utword_bits - sr)) |
(n.s.low >> (sr - n_udword_bits))) & ((di_int) (int)(n_udword_bits - sr) >> (n_udword_bits - 1)));
r.s.high = (n.s.high >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1));
r.s.low = ((n.s.high >> (sr - n_udword_bits)) &
((di_int) (int)(n_udword_bits - sr - 1) >> (n_udword_bits - 1))) |
(((n.s.high << (n_udword_bits - sr)) |
(n.s.low >> sr)) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1)));
}
else
{
/* K X
* ---
* K K
*/
sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
/*0 <= sr <= n_udword_bits - 1 or sr large */
if (sr > n_udword_bits - 1)
{
if (rem)
*rem = n.all; *rem = n.all;
return 0; return 0;
}
++sr;
/* 1 <= sr <= n_udword_bits - 1 */
/* q.all = n.all << (n_utword_bits - sr); */
q.s.low = 0;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr; */
r.s.high = n.s.high >> sr;
r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
}
else /* d.s.low != 0 */
{
if (d.s.high == 0)
{
/* K X
* ---
* 0 K
*/
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
{
if (rem)
*rem = n.s.low & (d.s.low - 1);
if (d.s.low == 1)
return n.all;
unsigned sr = __builtin_ctzll(d.s.low);
q.s.high = n.s.high >> sr;
q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
return q.all;
} }
/* K X ++sr;
* --- /* 1 <= sr <= n_udword_bits */
* 0 K /* q.all = n.all << (n_utword_bits - sr); */
*/ q.s.low = 0;
sr = 1 + n_udword_bits + __builtin_clzll(d.s.low) q.s.high = n.s.low << (n_udword_bits - sr);
- __builtin_clzll(n.s.high); /* r.all = n.all >> sr;
/* 2 <= sr <= n_utword_bits - 1 * if (sr < n_udword_bits)
* q.all = n.all << (n_utword_bits - sr); * {
* r.all = n.all >> sr; * r.s.high = n.s.high >> sr;
* if (sr == n_udword_bits) * r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* { * }
* q.s.low = 0; * else
* q.s.high = n.s.low; * {
* r.s.high = 0; * r.s.high = 0;
* r.s.low = n.s.high; * r.s.low = n.s.high;
* } * }
* else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1 */
* { r.s.high = (n.s.high >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1));
* q.s.low = 0; r.s.low = (n.s.high << (n_udword_bits - sr)) |
* q.s.high = n.s.low << (n_udword_bits - sr); ((n.s.low >> sr) & ((di_int) (int)(sr - n_udword_bits) >> (n_udword_bits - 1)));
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
* {
* q.s.low = n.s.low << (n_utword_bits - sr);
* q.s.high = (n.s.high << (n_utword_bits - sr)) |
* (n.s.low >> (sr - n_udword_bits));
* r.s.high = 0;
* r.s.low = n.s.high >> (sr - n_udword_bits);
* }
*/
q.s.low = (n.s.low << (n_utword_bits - sr)) &
((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1));
q.s.high = ((n.s.low << ( n_udword_bits - sr)) &
((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) |
(((n.s.high << (n_utword_bits - sr)) |
(n.s.low >> (sr - n_udword_bits))) &
((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)));
r.s.high = (n.s.high >> sr) &
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
r.s.low = ((n.s.high >> (sr - n_udword_bits)) &
((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) |
(((n.s.high << (n_udword_bits - sr)) |
(n.s.low >> sr)) &
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
}
else
{
/* K X
* ---
* K K
*/
sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
/*0 <= sr <= n_udword_bits - 1 or sr large */
if (sr > n_udword_bits - 1)
{
if (rem)
*rem = n.all;
return 0;
}
++sr;
/* 1 <= sr <= n_udword_bits */
/* q.all = n.all << (n_utword_bits - sr); */
q.s.low = 0;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr;
* if (sr < n_udword_bits)
* {
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else
* {
* r.s.high = 0;
* r.s.low = n.s.high;
* }
*/
r.s.high = (n.s.high >> sr) &
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
r.s.low = (n.s.high << (n_udword_bits - sr)) |
((n.s.low >> sr) &
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
} }
} }
/* Not a special case /* Not a special case
* q and r are initialized with: * q and r are initialized with:
* q.all = n.all << (n_utword_bits - sr); * q.all = n.all << (n_utword_bits - sr);
* r.all = n.all >> sr; * r.all = n.all >> sr;
* 1 <= sr <= n_utword_bits - 1 * 1 <= sr <= n_utword_bits - 1
*/ */
su_int carry = 0; su_int carry = 0;
for (; sr > 0; --sr)
for (; sr > 0; --sr)
{ {
/* r:q = ((r:q) << 1) | carry */ /* r:q = ((r:q) << 1) | carry */
r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1)); r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1));
r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1)); r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1));
q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1)); q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1));
q.s.low = (q.s.low << 1) | carry; q.s.low = (q.s.low << 1) | carry;
/* carry = 0; /* carry = 0;
* if (r.all >= d.all) * if (r.all >= d.all)
* { * {
* r.all -= d.all; * r.all -= d.all;
* carry = 1; * carry = 1;
* } * }
*/ */
const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1); const ti_int s = (ti_int) (d.all - r.all - 1) >> (n_utword_bits - 1);
carry = s & 1;
r.all -= d.all & s; carry = s & 1;
r.all -= d.all & s;
} }
q.all = (q.all << 1) | carry; q.all = (q.all << 1) | carry;
if (rem) if (rem)
*rem = r.all; *rem = r.all;
return q.all; return q.all;
} }
// missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o) // missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o)
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/umodti3.c // http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/umodti3.c
tu_int __umodti3(tu_int a, tu_int b) tu_int __umodti3(tu_int a, tu_int b)
{ {
tu_int r; tu_int r;
__udivmodti4(a, b, &r);
return r; __udivmodti4(a, b, &r);
return r;
} }
// missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o) // missing, needed by __cairo_uint128_divrem in libcairo.a(cairo-wideint.o)
// http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivti3.c // http://www.publicsource.apple.com/source/clang/clang-137/src/projects/compiler-rt/lib/udivti3.c
tu_int __udivti3(tu_int a, tu_int b) tu_int __udivti3(tu_int a, tu_int b)
{ {
return __udivmodti4(a, b, 0); return __udivmodti4(a, b, 0);
} }
// missing, needed by __nl_log_untranslated in libintl.a(log.o) for 10.5 // missing, needed by __nl_log_untranslated in libintl.a(log.o) for 10.5
FILE* fopen$DARWIN_EXTSN(const char *filename, const char *mode) FILE *fopen$DARWIN_EXTSN(const char *filename, const char *mode)
{ {
return fopen(filename, mode); return fopen(filename, mode);
} }
// missing, needed by _slab_allocator_alloc_chunk in libglib-2.0.a(libglib_2_0_la-gslice.o) for 10.5 // missing, needed by _slab_allocator_alloc_chunk in libglib-2.0.a(libglib_2_0_la-gslice.o) for 10.5
@ -345,21 +346,20 @@ FILE* fopen$DARWIN_EXTSN(const char *filename, const char *mode)
// http://www.publicsource.apple.com/source/clang/clang-137/src/tools/clang/lib/Headers/mm_malloc.h // http://www.publicsource.apple.com/source/clang/clang-137/src/tools/clang/lib/Headers/mm_malloc.h
int posix_memalign(void **ptr, size_t align, size_t size) int posix_memalign(void **ptr, size_t align, size_t size)
{ {
if (ptr) if (ptr)
{ {
*ptr = _mm_malloc (size, align); *ptr = _mm_malloc(size, align);
return 0; return 0;
} }
return ENOMEM; return ENOMEM;
} }
#endif // PATCH_10_5 #endif // PATCH_10_5
#ifdef PATCH_LIBPNG_EARLIER_THAN_1_5 #ifdef PATCH_LIBPNG_EARLIER_THAN_1_5
// missing in libpng<1.5, needed by _Load_SBit_Png in libfreetype.a(sfnt.o), _error_callback in libfreetype.a(sfnt.o) // missing in libpng<1.5, needed by _Load_SBit_Png in libfreetype.a(sfnt.o), _error_callback in libfreetype.a(sfnt.o)
// http://stackoverflow.com/questions/5190554/unresolved-external-png-set-longjmp-fn-in-libpng // http://stackoverflow.com/questions/5190554/unresolved-external-png-set-longjmp-fn-in-libpng
// http://cpansearch.perl.org/src/JTPALMER/Alien-SDL-1.439_1/patches/SDL_image-1.2.10-libpng15.patch // http://cpansearch.perl.org/src/JTPALMER/Alien-SDL-1.439_1/patches/SDL_image-1.2.10-libpng15.patch
typedef jmp_buf* (*png_set_longjmp_fnPtr)(png_structp, void*, size_t); typedef jmp_buf *(*png_set_longjmp_fnPtr) (png_structp, void *, size_t);
png_set_longjmp_fnPtr png_set_longjmp_fn = 0; png_set_longjmp_fnPtr png_set_longjmp_fn = 0;
#endif #endif

View file

@ -11,4 +11,4 @@
#include <wchar.h> #include <wchar.h>
wchar_t* wcsdup(const wchar_t*); wchar_t *wcsdup(const wchar_t *);

View file

@ -21,5 +21,4 @@
// (See COPYING.txt) // (See COPYING.txt)
// //
void speak_string(const wchar_t *str); void speak_string(const wchar_t * str);

View file

@ -14,15 +14,15 @@
struct WrapperDataStruct struct WrapperDataStruct
{ {
char dataPath[2048]; // path to data folder inside Tux Paint application bundle char dataPath[2048]; // path to data folder inside Tux Paint application bundle
char preferencesPath[2048]; // path to the user's Tux Paint preferences folder char preferencesPath[2048]; // path to the user's Tux Paint preferences folder
char globalPreferencesPath[2048]; // path to all users' Tux Paint preferences folder char globalPreferencesPath[2048]; // path to all users' Tux Paint preferences folder
char fontsPath[2048]; // path to the user's fonts folder char fontsPath[2048]; // path to the user's fonts folder
int foundSDL; // was SDL.framework found? int foundSDL; // was SDL.framework found?
int foundSDL_image; // was SDL_image.framework found? int foundSDL_image; // was SDL_image.framework found?
int foundSDL_mixer; // was SDL_mixer.framework found? int foundSDL_mixer; // was SDL_mixer.framework found?
int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper? int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper?
int menuAction; // was the action initiated by a Mac OS X menu selection? int menuAction; // was the action initiated by a Mac OS X menu selection?
}; };
typedef struct WrapperDataStruct WrapperData; typedef struct WrapperDataStruct WrapperData;

View file

@ -9,12 +9,12 @@
/* -------------------------- */ /* -------------------------- */
#include <stdio.h> #include <stdio.h>
#include <string.h> // For "strdup()" #include <string.h> // For "strdup()"
#include <libintl.h> // For "gettext()" #include <libintl.h> // For "gettext()"
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header #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_image.h" // For IMG_Load(), to load our PNG icon
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects #include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
/* Tool Enumerations: */ /* Tool Enumerations: */
@ -22,21 +22,22 @@
/* What tools we contain: */ /* What tools we contain: */
enum { enum
TOOL_ONE, // Becomes '0' {
TOOL_TWO, // Becomes '1' TOOL_ONE, // Becomes '0'
NUM_TOOLS // Becomes '2' TOOL_TWO, // Becomes '1'
NUM_TOOLS // Becomes '2'
}; };
/* A list of filenames for sounds and icons to load at startup: */ /* A list of filenames for sounds and icons to load at startup: */
const char * snd_filenames[NUM_TOOLS] = { const char *snd_filenames[NUM_TOOLS] = {
"one.wav", "one.wav",
"two.wav" "two.wav"
}; };
const char * icon_filenames[NUM_TOOLS] = { const char *icon_filenames[NUM_TOOLS] = {
"one.png", "one.png",
"two.png" "two.png"
}; };
@ -49,7 +50,7 @@ const char * icon_filenames[NUM_TOOLS] = {
/* A list of names for the tools */ /* A list of names for the tools */
const char * names[NUM_TOOLS] = { const char *names[NUM_TOOLS] = {
gettext_noop("A tool"), gettext_noop("A tool"),
gettext_noop("Another tool") gettext_noop("Another tool")
}; };
@ -57,7 +58,7 @@ const char * names[NUM_TOOLS] = {
/* A list of descriptions of the tools */ /* A list of descriptions of the tools */
const char * descs[NUM_TOOLS] = { const char *descs[NUM_TOOLS] = {
gettext_noop("This is example tool number 1."), gettext_noop("This is example tool number 1."),
gettext_noop("This is example tool number 2.") gettext_noop("This is example tool number 2.")
}; };
@ -68,7 +69,7 @@ const char * descs[NUM_TOOLS] = {
/* --------------------- */ /* --------------------- */
/* Sound effects: */ /* Sound effects: */
Mix_Chunk * snd_effect[NUM_TOOLS]; Mix_Chunk *snd_effect[NUM_TOOLS];
/* The current color (an "RGB" value) the user has selected in Tux Paint: */ /* The current color (an "RGB" value) the user has selected in Tux Paint: */
Uint8 example_r, example_g, example_b; Uint8 example_r, example_g, example_b;
@ -83,12 +84,9 @@ Uint8 example_r, example_g, example_b;
// that are declared _before_ them. // that are declared _before_ them.
void example_drag(magic_api * api, int which, SDL_Surface * canvas, void example_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void example_line_callback(void * ptr, int which, void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y);
/* Setup Functions: */ /* Setup Functions: */
@ -105,7 +103,7 @@ void example_line_callback(void * ptr, int which,
Uint32 example_api_version(void) Uint32 example_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
@ -129,26 +127,24 @@ int example_init(magic_api * api)
char fname[1024]; char fname[1024];
for (i = 0; i < NUM_TOOLS; i++) for (i = 0; i < NUM_TOOLS; i++)
{ {
// Assemble the filename from the "snd_filenames[]" array into // Assemble the filename from the "snd_filenames[]" array into
// a full path to a real file. // a full path to a real file.
// //
// Use "api->data_directory" to figure out where our sounds should be. // Use "api->data_directory" to figure out where our sounds should be.
// (The "tp-magic-config --dataprefix" command would have told us when // (The "tp-magic-config --dataprefix" command would have told us when
// we installed our plugin and its data.) // we installed our plugin and its data.)
snprintf(fname, sizeof(fname), snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, snd_filenames[i]);
"%s/sounds/magic/%s",
api->data_directory, snd_filenames[i]);
printf("Trying to load %s sound file\n", fname); printf("Trying to load %s sound file\n", fname);
// Try to load the file! // Try to load the file!
snd_effect[i] = Mix_LoadWAV(fname); snd_effect[i] = Mix_LoadWAV(fname);
} }
return(1); return (1);
} }
@ -163,7 +159,7 @@ int example_init(magic_api * api)
int example_get_tool_count(magic_api * api) int example_get_tool_count(magic_api * api)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
@ -172,7 +168,7 @@ int example_get_tool_count(magic_api * api)
// When Tux Paint is starting up and loading plugins, it asks us to // When Tux Paint is starting up and loading plugins, it asks us to
// provide icons for the "Magic" tool buttons. // provide icons for the "Magic" tool buttons.
SDL_Surface * example_get_icon(magic_api * api, int which) SDL_Surface *example_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
@ -186,13 +182,12 @@ SDL_Surface * example_get_icon(magic_api * api, int which)
// We use 'which' (which of our tools Tux Paint is asking about) // We use 'which' (which of our tools Tux Paint is asking about)
// as an index into the array. // as an index into the array.
snprintf(fname, sizeof(fname), "%s/images/magic/%s.png", snprintf(fname, sizeof(fname), "%s/images/magic/%s.png", api->data_directory, icon_filenames[which]);
api->data_directory, icon_filenames[which]);
// Try to load the image, and return the results to Tux Paint: // Try to load the image, and return the results to Tux Paint:
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
@ -201,10 +196,10 @@ SDL_Surface * example_get_icon(magic_api * api, int which)
// When Tux Paint is starting up and loading plugins, it asks us to // When Tux Paint is starting up and loading plugins, it asks us to
// provide names (labels) for the "Magic" tool buttons. // provide names (labels) for the "Magic" tool buttons.
char * example_get_name(magic_api * api, int which) char *example_get_name(magic_api * api, int which)
{ {
const char * our_name_english; const char *our_name_english;
const char * our_name_localized; const char *our_name_localized;
// Get our name from the "names[]" array. // Get our name from the "names[]" array.
// //
@ -226,7 +221,7 @@ char * example_get_name(magic_api * api, int which)
// send it to Tux Paint. (Tux Paint keeps track of the string 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.) // will free it for us, so we have one less thing to keep track of.)
return(strdup(our_name_localized)); return (strdup(our_name_localized));
} }
@ -235,10 +230,10 @@ char * example_get_name(magic_api * api, int which)
// When Tux Paint is starting up and loading plugins, it asks us to // When Tux Paint is starting up and loading plugins, it asks us to
// provide names (labels) for the "Magic" tool buttons. // provide names (labels) for the "Magic" tool buttons.
char * example_get_description(magic_api * api, int which, int mode) char *example_get_description(magic_api * api, int which, int mode)
{ {
const char * our_desc_english; const char *our_desc_english;
const char * our_desc_localized; const char *our_desc_localized;
// Get our desc from the "descs[]" array. // Get our desc from the "descs[]" array.
// //
@ -260,7 +255,7 @@ char * example_get_description(magic_api * api, int which, int mode)
// send it to Tux Paint. (Tux Paint keeps track of the string 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.) // will free it for us, so we have one less thing to keep track of.)
return(strdup(our_desc_localized)); return (strdup(our_desc_localized));
} }
// Report whether we accept colors // Report whether we accept colors
@ -309,8 +304,7 @@ void example_shutdown(magic_api * api)
// Affect the canvas on click: // Affect the canvas on click:
void example_click(magic_api * api, int which, int mode, void example_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
// In our case, a single click (which is also the start of a drag!) // 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 // is identical to what dragging does, but just at one point, rather
@ -326,8 +320,7 @@ void example_click(magic_api * api, int which, int mode,
// Affect the canvas on drag: // Affect the canvas on drag:
void example_drag(magic_api * api, int which, SDL_Surface * canvas, void example_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
// Call Tux Paint's "line()" function. // Call Tux Paint's "line()" function.
// //
@ -338,16 +331,27 @@ void example_drag(magic_api * api, int which, SDL_Surface * canvas,
// useful things (which of our "Magic" tools is being used and // useful things (which of our "Magic" tools is being used and
// the current and snapshot canvases). // the current and snapshot canvases).
api->line((void *) api, which, canvas, snapshot, api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, example_line_callback);
ox, oy, x, y, 1, example_line_callback);
// If we need to, swap the X and/or Y values, so that // If we need to, swap the X and/or Y values, so that
// (ox,oy) is always the top left, and (x,y) is always the bottom right, // (ox,oy) is always the top left, and (x,y) is always the bottom right,
// so the values we put inside "update_rect" make sense: // so the values we put inside "update_rect" make sense:
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
// Fill in the elements of the "update_rect" SDL_Rect structure // Fill in the elements of the "update_rect" SDL_Rect structure
@ -369,17 +373,15 @@ void example_drag(magic_api * api, int which, SDL_Surface * canvas,
// (So the sound will pan from speaker to speaker as you drag the // (So the sound will pan from speaker to speaker as you drag the
// mouse around the canvas!) // mouse around the canvas!)
api->playsound(snd_effect[which], api->playsound(snd_effect[which], (x * 255) / canvas->w, // pan
(x * 255) / canvas->w, // pan 255); // distance
255); // distance
} }
// Affect the canvas on release: // Affect the canvas on release:
void example_release(magic_api * api, int which, void example_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
// Neither of our effects do anything special when the mouse is released // 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... // from a click or click-and-drag, so there's no code here...
@ -423,9 +425,7 @@ void example_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
// It pays attention to 'which' to determine which of our plugin's tools // It pays attention to 'which' to determine which of our plugin's tools
// is currently selected. // is currently selected.
void example_line_callback(void * ptr, int which, void example_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y)
{ {
// For technical reasons, we can't accept a pointer to the "magic_api" // For technical reasons, we can't accept a pointer to the "magic_api"
// struct, like the other functions do. // struct, like the other functions do.
@ -436,7 +436,7 @@ void example_line_callback(void * ptr, int which,
// //
// (The "(magic_api *)" casts the generic pointer into the 'type' of // (The "(magic_api *)" casts the generic pointer into the 'type' of
// pointer we want, a pointer to a "magic_api".) // pointer we want, a pointer to a "magic_api".)
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
@ -445,43 +445,37 @@ void example_line_callback(void * ptr, int which,
// Tux Paint sends to us with the values we enumerated above. // Tux Paint sends to us with the values we enumerated above.
if (which == TOOL_ONE) if (which == TOOL_ONE)
{
// Tool number 1 simply draws a single pixel at the (x,y) location.
// It's a 1x1 pixel brush
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format,
example_r,
example_g,
example_b));
// We use "SDL_MapRGB()" to convert the RGB value we receive from Tux Paint
// for the user's current color selection to a 'Uint32' pixel value
// we can send to Tux Paint's "putpixel()" function.
}
else if (which == TOOL_TWO)
{
// Tool number 2 copies an 8x8 square of pixels from the opposite side
// of the canvas and puts it under the cursor
for (yy = -4; yy < 4; yy++)
{ {
for (xx = -4; xx < 4; xx++) // Tool number 1 simply draws a single pixel at the (x,y) location.
{ // It's a 1x1 pixel brush
api->putpixel(canvas, x + xx, y + yy,
api->getpixel(snapshot,
canvas->w - x - xx,
canvas->h - y - yy));
// We simply use Tux Paint's "getpixel()" routine to pull pixel api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, example_r, example_g, example_b));
// values from the 'snapshot', and then "putpixel()" to draw them
// right into the 'canvas'. // 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
// Note: putpixel() and getpixel() are safe to use, even if your // we can send to Tux Paint's "putpixel()" function.
// X,Y values are outside of the SDL surface (e.g., negative, or }
// greater than the surface's width or height). else if (which == TOOL_TWO)
} {
// Tool number 2 copies an 8x8 square of pixels from the opposite side
// of the canvas and puts it under the cursor
for (yy = -4; yy < 4; yy++)
{
for (xx = -4; xx < 4; xx++)
{
api->putpixel(canvas, x + xx, y + yy, api->getpixel(snapshot, canvas->w - x - xx, canvas->h - y - yy));
// We simply use Tux Paint's "getpixel()" routine to pull pixel
// values from the 'snapshot', and then "putpixel()" to draw them
// right into the 'canvas'.
// Note: putpixel() and getpixel() are safe to use, even if your
// X,Y values are outside of the SDL surface (e.g., negative, or
// greater than the surface's width or height).
}
}
} }
}
} }
// Switch-In event // Switch-In event

1
magic/src/.indent.pro vendored Symbolic link
View file

@ -0,0 +1 @@
../../src/.indent.pro

View file

@ -43,48 +43,50 @@
#define gettext_noop(String) String #define gettext_noop(String) String
#endif #endif
static const double alien_ANGLE[] = {0,0,0}; static const double alien_ANGLE[] = { 0, 0, 0 };
static const double alien_FREQUENCY[] = {1,1,1}; static const double alien_FREQUENCY[] = { 1, 1, 1 };
static const int alien_RADIUS = 16; static const int alien_RADIUS = 16;
enum { enum
TOOL_alien, {
alien_NUM_TOOLS TOOL_alien,
alien_NUM_TOOLS
}; };
static Mix_Chunk * alien_snd_effect[alien_NUM_TOOLS]; static Mix_Chunk *alien_snd_effect[alien_NUM_TOOLS];
const char * alien_snd_filenames[alien_NUM_TOOLS] = { const char *alien_snd_filenames[alien_NUM_TOOLS] = {
"alien.ogg", "alien.ogg",
}; };
const char * alien_icon_filenames[alien_NUM_TOOLS] = {
const char *alien_icon_filenames[alien_NUM_TOOLS] = {
"alien.png", "alien.png",
}; };
const char * alien_names[alien_NUM_TOOLS] = {
const char *alien_names[alien_NUM_TOOLS] = {
gettext_noop("Color Shift"), gettext_noop("Color Shift"),
}; };
const char * alien_descs[alien_NUM_TOOLS][2] = {
const char *alien_descs[alien_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to change the colors in parts of your picture."), {gettext_noop("Click and drag the mouse to change the colors in parts of your picture."),
gettext_noop("Click to change the colors in your entire picture."),}, gettext_noop("Click to change the colors in your entire picture."),},
}; };
// Prototypes // Prototypes
Uint32 alien_api_version(void); Uint32 alien_api_version(void);
int alien_init(magic_api * api); int alien_init(magic_api * api);
int alien_get_tool_count(magic_api * api); int alien_get_tool_count(magic_api * api);
SDL_Surface * alien_get_icon(magic_api * api, int which); SDL_Surface *alien_get_icon(magic_api * api, int which);
char * alien_get_name(magic_api * api, int which); char *alien_get_name(magic_api * api, int which);
char * alien_get_description(magic_api * api, int which, int mode); char *alien_get_description(magic_api * api, int which, int mode);
void alien_drag(magic_api * api, int which, SDL_Surface * canvas, void alien_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect); Mix_Chunk *magic_loadsound(char *file);
Mix_Chunk * magic_loadsound(char* file);
void alien_click(magic_api * api, int which, int mode, void alien_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void alien_release(magic_api * api, int which, void alien_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void alien_shutdown(magic_api * api); void alien_shutdown(magic_api * api);
void alien_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void alien_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int alien_requires_colors(magic_api * api, int which); int alien_requires_colors(magic_api * api, int which);
@ -93,109 +95,134 @@ void alien_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas)
int alien_modes(magic_api * api, int which); int alien_modes(magic_api * api, int which);
Uint32 alien_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 alien_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int alien_init(magic_api * api){ int alien_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
srand(time(0)); srand(time(0));
for (i = 0; i < alien_NUM_TOOLS; i++){ for (i = 0; i < alien_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, alien_snd_filenames[i]); {
alien_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, alien_snd_filenames[i]);
} alien_snd_effect[i] = Mix_LoadWAV(fname);
return(1); }
return (1);
} }
int alien_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int alien_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(alien_NUM_TOOLS); {
return (alien_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * alien_get_icon(magic_api * api, int which){ SDL_Surface *alien_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, alien_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, alien_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * alien_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *alien_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(alien_names[which]))); {
return (strdup(gettext_noop(alien_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * alien_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *alien_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(alien_descs[which][mode-1]))); {
return (strdup(gettext_noop(alien_descs[which][mode - 1])));
} }
//Do the effect for one pixel //Do the effect for one pixel
static void do_alien_pixel(void * ptr, int which ATTRIBUTE_UNUSED, static void do_alien_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y){ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 temp[3]; Uint8 temp[3];
double temp2[3]; double temp2[3];
int k; int k;
SDL_GetRGB(api->getpixel(canvas,x, y), canvas->format, &temp[0], &temp[1], &temp[2]); SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
for (k =0;k<3;k++){ for (k = 0; k < 3; k++)
{
//EP temp2[k] = clamp(0,127.5 * (1.0 + sin (((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI)),255); //EP temp2[k] = clamp(0,127.5 * (1.0 + sin (((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI)),255);
temp2[k] = clamp(0.0, temp2[k] = clamp(0.0,
127.5 * ( 127.5 * (1.0 +
1.0 + sin (((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI) sin(((temp[k] / 127.5 - 1.0) * alien_FREQUENCY[k] + alien_ANGLE[k] / 180.0) * M_PI)),
), 255.0);
255.0); }
} api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
} }
// Do the effect for the full image // Do the effect for the full image
static void do_alien_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ static void do_alien_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
{
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int x,y; int x, y;
for (y = 0; y < last->h; y++){ for (y = 0; y < last->h; y++)
for (x=0; x < last->w; x++){ {
do_alien_pixel(ptr, which, canvas, last, x, y); for (x = 0; x < last->w; x++)
} {
} do_alien_pixel(ptr, which, canvas, last, x, y);
}
}
} }
//do the effect for the brush //do the effect for the brush
static void do_alien_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ static void do_alien_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
int xx, yy; int xx, yy;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - alien_RADIUS; yy < y + alien_RADIUS; yy++) for (yy = y - alien_RADIUS; yy < y + alien_RADIUS; yy++)
{
for (xx = x - alien_RADIUS; xx < x + alien_RADIUS; xx++)
{ {
if (api->in_circle(xx - x, yy - y, alien_RADIUS) && for (xx = x - alien_RADIUS; xx < x + alien_RADIUS; xx++)
!api->touched(xx, yy)) {
{ if (api->in_circle(xx - x, yy - y, alien_RADIUS) && !api->touched(xx, yy))
do_alien_pixel(api, which, canvas, last, xx, yy); {
} do_alien_pixel(api, which, canvas, last, xx, yy);
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void alien_drag(magic_api * api, int which, SDL_Surface * canvas, void alien_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_alien_brush); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_alien_brush);
api->playsound(alien_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(alien_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - alien_RADIUS; update_rect->x = ox - alien_RADIUS;
update_rect->y = oy - alien_RADIUS; update_rect->y = oy - alien_RADIUS;
@ -205,53 +232,60 @@ void alien_drag(magic_api * api, int which, SDL_Surface * canvas,
int use_sound = 1; int use_sound = 1;
Mix_Chunk * magic_loadsound(char* file){ Mix_Chunk *magic_loadsound(char *file)
Mix_Chunk * temp; {
Mix_Chunk *temp;
if (!use_sound){ if (!use_sound)
return (Mix_Chunk*)-1; {
} return (Mix_Chunk *) - 1;
}
temp = Mix_LoadWAV(file); temp = Mix_LoadWAV(file);
return temp; return temp;
} }
// Affect the canvas on click: // Affect the canvas on click:
void alien_click(magic_api * api, int which, int mode, void alien_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
alien_drag(api, which, canvas, last, x, y, x, y, update_rect); alien_drag(api, which, canvas, last, x, y, x, y, update_rect);
else{ else
update_rect->x = 0; {
update_rect->y = 0; update_rect->x = 0;
update_rect->w = canvas->w; update_rect->y = 0;
update_rect->h = canvas->h; update_rect->w = canvas->w;
do_alien_full(api, canvas, last, which); update_rect->h = canvas->h;
api->playsound(alien_snd_effect[which], 128, 255); do_alien_full(api, canvas, last, which);
} api->playsound(alien_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void alien_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void alien_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void alien_shutdown(magic_api * api ATTRIBUTE_UNUSED) void alien_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<alien_NUM_TOOLS; i++){
if(alien_snd_effect[i] != NULL){ for (i = 0; i < alien_NUM_TOOLS; i++)
Mix_FreeChunk(alien_snd_effect[i]); {
} if (alien_snd_effect[i] != NULL)
} {
Mix_FreeChunk(alien_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void alien_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void alien_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -261,16 +295,17 @@ int alien_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 0; return 0;
} }
void alien_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void alien_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void alien_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void alien_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int alien_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int alien_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -33,54 +33,54 @@
int BLIND_RADIUS = 16; int BLIND_RADIUS = 16;
int BLIND_OPAQUE = 20; int BLIND_OPAQUE = 20;
int BLIND_THICKNESS = 30; int BLIND_THICKNESS = 30;
int blind_side; /* 0 top, 1 left, 2 bottom, 3 right */ int blind_side; /* 0 top, 1 left, 2 bottom, 3 right */
static Uint8 blind_r, blind_g, blind_b, blind_light; static Uint8 blind_r, blind_g, blind_b, blind_light;
enum blind_sides{ enum blind_sides
{
BLIND_SIDE_TOP, BLIND_SIDE_TOP,
BLIND_SIDE_LEFT, BLIND_SIDE_LEFT,
BLIND_SIDE_BOTTOM, BLIND_SIDE_BOTTOM,
BLIND_SIDE_RIGHT}; BLIND_SIDE_RIGHT
};
enum blind_tools{ enum blind_tools
{
BLIND_TOOL_BLIND, BLIND_TOOL_BLIND,
BLIND_NUMTOOLS}; BLIND_NUMTOOLS
};
Mix_Chunk * blind_snd; Mix_Chunk *blind_snd;
// Prototypes // Prototypes
Uint32 blind_api_version(void); Uint32 blind_api_version(void);
void blind_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void blind_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int blind_init(magic_api * api); int blind_init(magic_api * api);
int blind_get_tool_count(magic_api * api); int blind_get_tool_count(magic_api * api);
SDL_Surface * blind_get_icon(magic_api * api, int which); SDL_Surface *blind_get_icon(magic_api * api, int which);
char * blind_get_name(magic_api * api, int which); char *blind_get_name(magic_api * api, int which);
char * blind_get_description(magic_api * api, int which, int mode); char *blind_get_description(magic_api * api, int which, int mode);
int blind_requires_colors(magic_api * api, int which); int blind_requires_colors(magic_api * api, int which);
void blind_release(magic_api * api, int which, void blind_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blind_shutdown(magic_api * api); void blind_shutdown(magic_api * api);
void blind_paint_blind(void * ptr_to_api, int which_tool, void blind_paint_blind(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void blind_drag(magic_api * api, int which, SDL_Surface * canvas, void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void blind_click(magic_api * api, int which, int mode, void blind_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blind_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void blind_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blind_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void blind_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int blind_modes(magic_api * api, int which); int blind_modes(magic_api * api, int which);
// Housekeeping functions // Housekeeping functions
Uint32 blind_api_version(void) Uint32 blind_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void blind_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure void blind_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
{ {
blind_r = r; blind_r = r;
blind_g = g; blind_g = g;
@ -91,10 +91,10 @@ int blind_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/blind.ogg", api->data_directory); snprintf(fname, sizeof(fname), "%s/sounds/magic/blind.ogg", api->data_directory);
blind_snd = Mix_LoadWAV(fname); blind_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int blind_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int blind_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -102,24 +102,25 @@ int blind_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return BLIND_NUMTOOLS; return BLIND_NUMTOOLS;
} }
SDL_Surface * blind_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *blind_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/blind.png", snprintf(fname, sizeof(fname), "%s/images/magic/blind.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * blind_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *blind_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return strdup(gettext_noop("Blind")); return strdup(gettext_noop("Blind"));
} }
char * blind_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *blind_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return strdup(gettext_noop("Click towards the edge of your picture to pull window blinds over it. Move perpendicularly to open or close the blinds.")); return
strdup(gettext_noop
("Click towards the edge of your picture to pull window blinds over it. Move perpendicularly to open or close the blinds."));
} }
int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
@ -128,24 +129,26 @@ int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
} }
void blind_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void blind_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void blind_shutdown(magic_api * api ATTRIBUTE_UNUSED) void blind_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
Mix_FreeChunk(blind_snd); Mix_FreeChunk(blind_snd);
} }
// Interactivity functions // Interactivity functions
void blind_paint_blind(void * ptr_to_api, int which_tool ATTRIBUTE_UNUSED, void blind_paint_blind(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr_to_api; magic_api *api = (magic_api *) ptr_to_api;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, (blind_r + blind_light) / 2, (blind_g + blind_light) / 2, (blind_b + blind_light) / 2)); api->putpixel(canvas, x, y,
SDL_MapRGB(canvas->format, (blind_r + blind_light) / 2, (blind_g + blind_light) / 2,
(blind_b + blind_light) / 2));
} }
/* void blind_do_blind(void * ptr_to_api, int which_tool, /* void blind_do_blind(void * ptr_to_api, int which_tool,
@ -159,31 +162,31 @@ void blind_paint_blind(void * ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
*/ */
void blind_drag(magic_api * api, int which, SDL_Surface * canvas, void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
int opaque; int opaque;
SDL_BlitSurface(snapshot, NULL, canvas, NULL); SDL_BlitSurface(snapshot, NULL, canvas, NULL);
switch (blind_side) switch (blind_side)
{ {
int i, j; int i, j;
case BLIND_SIDE_TOP: case BLIND_SIDE_TOP:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2); opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y;i >= 0; i -= BLIND_THICKNESS) for (i = y; i >= 0; i -= BLIND_THICKNESS)
{ {
blind_light = 255; blind_light = 255;
for (j=i; j > i - opaque/2; j--) for (j = i; j > i - opaque / 2; j--)
{ {
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light -=20; blind_light -= 20;
} }
for (j = i - opaque/2; j > i - opaque; j--) for (j = i - opaque / 2; j > i - opaque; j--)
{ {
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light +=20; blind_light += 20;
} }
} }
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -194,19 +197,19 @@ void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
case BLIND_SIDE_BOTTOM: case BLIND_SIDE_BOTTOM:
opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2); opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
for (i = y; i <= canvas->h; i += BLIND_THICKNESS) for (i = y; i <= canvas->h; i += BLIND_THICKNESS)
{ {
blind_light = 255; blind_light = 255;
for (j = i; j < i + opaque / 2; j++) for (j = i; j < i + opaque / 2; j++)
{ {
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light -= 20; blind_light -= 20;
} }
for (j = i + opaque / 2; j < i + opaque; j ++) for (j = i + opaque / 2; j < i + opaque; j++)
{ {
api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
blind_light += 20; blind_light += 20;
} }
} }
update_rect->x = 0; update_rect->x = 0;
update_rect->y = min(oy, y); update_rect->y = min(oy, y);
@ -218,19 +221,19 @@ void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
case BLIND_SIDE_RIGHT: case BLIND_SIDE_RIGHT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2); opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i <= canvas->w; i += BLIND_THICKNESS) for (i = x; i <= canvas->w; i += BLIND_THICKNESS)
{ {
blind_light = 255; blind_light = 255;
for (j = i; j < i + opaque / 2; j++) for (j = i; j < i + opaque / 2; j++)
{ {
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light -= 20; blind_light -= 20;
} }
for (j = i + opaque / 2; j < i + opaque; j ++) for (j = i + opaque / 2; j < i + opaque; j++)
{ {
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light += 20; blind_light += 20;
} }
} }
update_rect->x = min(ox, x); update_rect->x = min(ox, x);
update_rect->y = 0; update_rect->y = 0;
@ -242,19 +245,19 @@ void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
case BLIND_SIDE_LEFT: case BLIND_SIDE_LEFT:
opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2); opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
for (i = x; i >= 0; i -= BLIND_THICKNESS) for (i = x; i >= 0; i -= BLIND_THICKNESS)
{ {
blind_light = 255; blind_light = 255;
for (j=i; j > i - opaque/2; j--) for (j = i; j > i - opaque / 2; j--)
{ {
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light -=20; blind_light -= 20;
} }
for (j = i - opaque/2; j > i - opaque; j--) for (j = i - opaque / 2; j > i - opaque; j--)
{ {
api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind); api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
blind_light +=20; blind_light += 20;
} }
} }
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = max(ox, x); update_rect->w = max(ox, x);
@ -266,37 +269,44 @@ void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
} }
void blind_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void blind_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
if (y < canvas->h / 2) if (y < canvas->h / 2)
{ {
if (x < y) blind_side = 1; /* left */ if (x < y)
else if (canvas->w - x < y) blind_side = 3; /* right */ blind_side = 1; /* left */
else blind_side = 0; /* top */ else if (canvas->w - x < y)
} blind_side = 3; /* right */
else else
{ blind_side = 0; /* top */
if (x < canvas->h - y) blind_side = 1; /* left */ }
else if (canvas->w - x < canvas->h - y) blind_side = 3; /* right */ else
else blind_side = 2; /* bottom */ {
} if (x < canvas->h - y)
blind_side = 1; /* left */
else if (canvas->w - x < canvas->h - y)
blind_side = 3; /* right */
else
blind_side = 2; /* bottom */
}
blind_drag(api, which, canvas, last, x, y, x, y, update_rect); blind_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void blind_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void blind_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
{ SDL_Surface * canvas ATTRIBUTE_UNUSED)
}
void blind_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
}
void blind_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
} }
int blind_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int blind_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN | MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -35,7 +35,8 @@
/* What tools we contain: */ /* What tools we contain: */
enum { enum
{
TOOL_BLOCKS, TOOL_BLOCKS,
TOOL_CHALK, TOOL_CHALK,
TOOL_DRIP, TOOL_DRIP,
@ -45,7 +46,7 @@ enum {
/* Our globals: */ /* Our globals: */
static Mix_Chunk * snd_effect[NUM_TOOLS]; static Mix_Chunk *snd_effect[NUM_TOOLS];
/* Our function prototypes: */ /* Our function prototypes: */
@ -53,21 +54,16 @@ static Mix_Chunk * snd_effect[NUM_TOOLS];
int blocks_chalk_drip_init(magic_api * api); int blocks_chalk_drip_init(magic_api * api);
Uint32 blocks_chalk_drip_api_version(void); Uint32 blocks_chalk_drip_api_version(void);
int blocks_chalk_drip_get_tool_count(magic_api * api); int blocks_chalk_drip_get_tool_count(magic_api * api);
SDL_Surface * blocks_chalk_drip_get_icon(magic_api * api, int which); SDL_Surface *blocks_chalk_drip_get_icon(magic_api * api, int which);
char * blocks_chalk_drip_get_name(magic_api * api, int which); char *blocks_chalk_drip_get_name(magic_api * api, int which);
char * blocks_chalk_drip_get_description(magic_api * api, int which, int mode); char *blocks_chalk_drip_get_description(magic_api * api, int which, int mode);
static void blocks_chalk_drip_linecb(void * ptr, int which, static void blocks_chalk_drip_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas, void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void blocks_chalk_drip_click(magic_api * api, int which, int mode, void blocks_chalk_drip_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blocks_chalk_drip_release(magic_api * api, int which, void blocks_chalk_drip_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blocks_chalk_drip_shutdown(magic_api * api); void blocks_chalk_drip_shutdown(magic_api * api);
void blocks_chalk_drip_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void blocks_chalk_drip_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int blocks_chalk_drip_requires_colors(magic_api * api, int which); int blocks_chalk_drip_requires_colors(magic_api * api, int which);
@ -81,90 +77,82 @@ int blocks_chalk_drip_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/blocks.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/blocks.wav", api->data_directory);
api->data_directory);
snd_effect[0] = Mix_LoadWAV(fname); snd_effect[0] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/chalk.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/chalk.wav", api->data_directory);
api->data_directory);
snd_effect[1] = Mix_LoadWAV(fname); snd_effect[1] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/drip.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/drip.wav", api->data_directory);
api->data_directory);
snd_effect[2] = Mix_LoadWAV(fname); snd_effect[2] = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 blocks_chalk_drip_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 blocks_chalk_drip_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int blocks_chalk_drip_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int blocks_chalk_drip_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * blocks_chalk_drip_get_icon(magic_api * api, int which) SDL_Surface *blocks_chalk_drip_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == TOOL_BLOCKS) if (which == TOOL_BLOCKS)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/blocks.png", snprintf(fname, sizeof(fname), "%s/images/magic/blocks.png", api->data_directory);
api->data_directory); }
}
else if (which == TOOL_CHALK) else if (which == TOOL_CHALK)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/chalk.png", snprintf(fname, sizeof(fname), "%s/images/magic/chalk.png", api->data_directory);
api->data_directory); }
}
else if (which == TOOL_DRIP) else if (which == TOOL_DRIP)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/drip.png", snprintf(fname, sizeof(fname), "%s/images/magic/drip.png", api->data_directory);
api->data_directory); }
}
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * blocks_chalk_drip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *blocks_chalk_drip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == TOOL_BLOCKS) if (which == TOOL_BLOCKS)
return(strdup(gettext_noop("Blocks"))); return (strdup(gettext_noop("Blocks")));
else if (which == TOOL_CHALK) else if (which == TOOL_CHALK)
return(strdup(gettext_noop("Chalk"))); return (strdup(gettext_noop("Chalk")));
else if (which == TOOL_DRIP) else if (which == TOOL_DRIP)
return(strdup(gettext_noop("Drip"))); return (strdup(gettext_noop("Drip")));
return(NULL); return (NULL);
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * blocks_chalk_drip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *blocks_chalk_drip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (which == TOOL_BLOCKS) if (which == TOOL_BLOCKS)
return(strdup(gettext_noop( return (strdup(gettext_noop("Click and drag the mouse around to make the picture blocky.")));
"Click and drag the mouse around to make the picture blocky.")));
else if (which == TOOL_CHALK) else if (which == TOOL_CHALK)
return(strdup(gettext_noop( return (strdup(gettext_noop("Click and drag the mouse around to turn the picture into a chalk drawing.")));
"Click and drag the mouse around to turn the picture into a chalk drawing.")));
else if (which == TOOL_DRIP) else if (which == TOOL_DRIP)
return(strdup(gettext_noop( return (strdup(gettext_noop("Click and drag the mouse around to make the picture drip.")));
"Click and drag the mouse around to make the picture drip.")));
return(NULL); return (NULL);
} }
// Do the effect: // Do the effect:
static void blocks_chalk_drip_linecb(void * ptr, int which, static void blocks_chalk_drip_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
int h; int h;
SDL_Rect src, dest; SDL_Rect src, dest;
@ -172,113 +160,126 @@ static void blocks_chalk_drip_linecb(void * ptr, int which,
Uint32 colr; Uint32 colr;
if (which == TOOL_BLOCKS) if (which == TOOL_BLOCKS)
{
/* Put x/y on exact grid points: */
x = (x / 4) * 4;
y = (y / 4) * 4;
if (!api->touched(x, y))
{ {
for (yy = y - 8; yy < y + 8; yy = yy + 4) /* Put x/y on exact grid points: */
{
for (xx = x - 8; xx < x + 8; xx = xx + 4)
{
Uint32 pix[16];
Uint32 p_or = 0;
Uint32 p_and = ~0;
unsigned i = 16;
while (i--)
{
Uint32 p_tmp;
p_tmp = api->getpixel(last, xx + (i >> 2), yy + (i & 3));
p_or |= p_tmp;
p_and &= p_tmp;
pix[i] = p_tmp;
}
if (p_or == p_and) // if all pixels the same already
{
SDL_GetRGB(p_or, last->format, &r, &g, &b);
}
else // nope, must average them
{
double r_sum = 0.0;
double g_sum = 0.0;
double b_sum = 0.0;
i = 16;
while (i--)
{
SDL_GetRGB(pix[i], last->format, &r, &g, &b);
r_sum += api->sRGB_to_linear(r);
g_sum += api->sRGB_to_linear(g);
b_sum += api->sRGB_to_linear(b);
}
r = api->linear_to_sRGB(r_sum / 16.0);
g = api->linear_to_sRGB(g_sum / 16.0);
b = api->linear_to_sRGB(b_sum / 16.0);
}
/* Draw block: */ x = (x / 4) * 4;
y = (y / 4) * 4;
dest.x = xx; if (!api->touched(x, y))
dest.y = yy; {
dest.w = 4; for (yy = y - 8; yy < y + 8; yy = yy + 4)
dest.h = 4; {
for (xx = x - 8; xx < x + 8; xx = xx + 4)
{
Uint32 pix[16];
Uint32 p_or = 0;
Uint32 p_and = ~0;
unsigned i = 16;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, r, g, b)); while (i--)
} {
} Uint32 p_tmp;
p_tmp = api->getpixel(last, xx + (i >> 2), yy + (i & 3));
p_or |= p_tmp;
p_and &= p_tmp;
pix[i] = p_tmp;
}
if (p_or == p_and) // if all pixels the same already
{
SDL_GetRGB(p_or, last->format, &r, &g, &b);
}
else // nope, must average them
{
double r_sum = 0.0;
double g_sum = 0.0;
double b_sum = 0.0;
i = 16;
while (i--)
{
SDL_GetRGB(pix[i], last->format, &r, &g, &b);
r_sum += api->sRGB_to_linear(r);
g_sum += api->sRGB_to_linear(g);
b_sum += api->sRGB_to_linear(b);
}
r = api->linear_to_sRGB(r_sum / 16.0);
g = api->linear_to_sRGB(g_sum / 16.0);
b = api->linear_to_sRGB(b_sum / 16.0);
}
/* Draw block: */
dest.x = xx;
dest.y = yy;
dest.w = 4;
dest.h = 4;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
} }
}
else if (which == TOOL_CHALK) else if (which == TOOL_CHALK)
{
for (yy = y - 8; yy <= y + 8; yy = yy + 4)
{ {
for (xx = x - 8; xx <= x + 8; xx = xx + 4)
{
dest.x = xx + ((rand() % 5) - 2);
dest.y = yy + ((rand() % 5) - 2);
dest.w = (rand() % 4) + 2;
dest.h = (rand() % 4) + 2;
colr = api->getpixel(last, clamp(0, xx, canvas->w - 1), for (yy = y - 8; yy <= y + 8; yy = yy + 4)
clamp(0, yy, canvas->h - 1)); {
SDL_FillRect(canvas, &dest, colr); for (xx = x - 8; xx <= x + 8; xx = xx + 4)
} {
dest.x = xx + ((rand() % 5) - 2);
dest.y = yy + ((rand() % 5) - 2);
dest.w = (rand() % 4) + 2;
dest.h = (rand() % 4) + 2;
colr = api->getpixel(last, clamp(0, xx, canvas->w - 1), clamp(0, yy, canvas->h - 1));
SDL_FillRect(canvas, &dest, colr);
}
}
} }
}
else if (which == TOOL_DRIP) else if (which == TOOL_DRIP)
{
for (xx = x - 8; xx <= x + 8; xx++)
{ {
h = (rand() % 8) + 8; for (xx = x - 8; xx <= x + 8; xx++)
{
h = (rand() % 8) + 8;
for (yy = y; yy <= y + h; yy++) for (yy = y; yy <= y + h; yy++)
{ {
src.x = xx; src.x = xx;
src.y = y; src.y = y;
src.w = 1; src.w = 1;
src.h = 16; src.h = 16;
dest.x = xx; dest.x = xx;
dest.y = yy; dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest); SDL_BlitSurface(last, &src, canvas, &dest);
} }
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas, void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, blocks_chalk_drip_linecb); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, blocks_chalk_drip_linecb);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -290,16 +291,15 @@ void blocks_chalk_drip_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void blocks_chalk_drip_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void blocks_chalk_drip_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
blocks_chalk_drip_drag(api, which, canvas, last, x, y, x, y, update_rect); blocks_chalk_drip_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void blocks_chalk_drip_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void blocks_chalk_drip_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -315,7 +315,7 @@ void blocks_chalk_drip_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Record the color from Tux Paint: // Record the color from Tux Paint:
void blocks_chalk_drip_set_color(magic_api * api ATTRIBUTE_UNUSED, void blocks_chalk_drip_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -325,15 +325,17 @@ int blocks_chalk_drip_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int whic
return 0; return 0;
} }
void blocks_chalk_drip_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void blocks_chalk_drip_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void blocks_chalk_drip_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void blocks_chalk_drip_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int blocks_chalk_drip_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int blocks_chalk_drip_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); /* FIXME - Blocks and Chalk, at least, can also be turned into a full-image effect */ return (MODE_PAINT); /* FIXME - Blocks and Chalk, at least, can also be turned into a full-image effect */
} }

View file

@ -42,18 +42,15 @@
Uint32 blur_api_version(void); Uint32 blur_api_version(void);
int blur_init(magic_api * api); int blur_init(magic_api * api);
int blur_get_tool_count(magic_api * api); int blur_get_tool_count(magic_api * api);
SDL_Surface * blur_get_icon(magic_api * api, int which); SDL_Surface *blur_get_icon(magic_api * api, int which);
char * blur_get_name(magic_api * api, int which); char *blur_get_name(magic_api * api, int which);
char * blur_get_description(magic_api * api, int which, int mode); char *blur_get_description(magic_api * api, int which, int mode);
void blur_drag(magic_api * api, int which, SDL_Surface * canvas, void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void blur_click(magic_api * api, int which, int mode, void blur_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blur_release(magic_api * api, int which, void blur_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void blur_shutdown(magic_api * api); void blur_shutdown(magic_api * api);
void blur_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void blur_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int blur_requires_colors(magic_api * api, int which); int blur_requires_colors(magic_api * api, int which);
@ -61,142 +58,177 @@ void blur_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void blur_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void blur_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int blur_modes(magic_api * api, int which); int blur_modes(magic_api * api, int which);
enum { enum
TOOL_blur, {
blur_NUM_TOOLS TOOL_blur,
blur_NUM_TOOLS
}; };
static const int blur_RADIUS = 16; static const int blur_RADIUS = 16;
static Mix_Chunk * blur_snd_effect[blur_NUM_TOOLS]; static Mix_Chunk *blur_snd_effect[blur_NUM_TOOLS];
const char *blur_snd_filenames[blur_NUM_TOOLS] = { const char *blur_snd_filenames[blur_NUM_TOOLS] = {
"blur.wav", "blur.wav",
}; };
const char * blur_icon_filenames[blur_NUM_TOOLS] = {
const char *blur_icon_filenames[blur_NUM_TOOLS] = {
"blur.png", "blur.png",
}; };
const char * blur_names[blur_NUM_TOOLS] = {
const char *blur_names[blur_NUM_TOOLS] = {
gettext_noop("Blur"), gettext_noop("Blur"),
}; };
const char * blur_descs[blur_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse around to blur the image."), const char *blur_descs[blur_NUM_TOOLS][2] = {
gettext_noop("Click to blur the entire image.")}, {gettext_noop("Click and drag the mouse around to blur the image."),
gettext_noop("Click to blur the entire image.")},
}; };
Uint32 blur_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 blur_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int blur_init(magic_api * api){ int blur_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
for (i = 0; i < blur_NUM_TOOLS; i++){ for (i = 0; i < blur_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, blur_snd_filenames[i]); {
blur_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, blur_snd_filenames[i]);
} blur_snd_effect[i] = Mix_LoadWAV(fname);
return(1); }
return (1);
} }
int blur_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int blur_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(blur_NUM_TOOLS); {
return (blur_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * blur_get_icon(magic_api * api, int which){ SDL_Surface *blur_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, blur_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, blur_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * blur_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *blur_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(blur_names[which]))); {
return (strdup(gettext_noop(blur_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * blur_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *blur_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(blur_descs[which][mode-1]))); {
return (strdup(gettext_noop(blur_descs[which][mode - 1])));
} }
//Do the effect for one pixel //Do the effect for one pixel
static void do_blur_pixel(void * ptr, int which ATTRIBUTE_UNUSED, static void do_blur_pixel(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last, {
int x, int y){ magic_api *api = (magic_api *) ptr;
magic_api * api = (magic_api *) ptr; int i, j, k;
int i,j,k; Uint8 temp[3];
Uint8 temp[3];
double blurValue[3]; double blurValue[3];
//5x5 gaussiann weighting window //5x5 gaussiann weighting window
const int weight[5][5] = { {1,4,7,4,1}, const int weight[5][5] = { {1, 4, 7, 4, 1},
{4,16,26,16,4}, {4, 16, 26, 16, 4},
{7,26,41,26,7}, {7, 26, 41, 26, 7},
{4,16,26,16,4}, {4, 16, 26, 16, 4},
{1,4,7,4,1}}; {1, 4, 7, 4, 1}
};
for (k =0;k<3;k++){ for (k = 0; k < 3; k++)
blurValue[k] = 0; {
} blurValue[k] = 0;
for (i=-2;i<3;i++){
for (j=-2;j<3;j++){
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k =0;k<3;k++){
blurValue[k] += temp[k]* weight[i+2][j+2];
}
} }
}
for (k =0;k<3;k++){ for (i = -2; i < 3; i++)
blurValue[k] /= 273; {
} for (j = -2; j < 3; j++)
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2])); {
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
}
for (k = 0; k < 3; k++)
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2]));
} }
// Do the effect for the full image // Do the effect for the full image
static void do_blur_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ static void do_blur_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
{
//magic_api * api = (magic_api *) ptr; //magic_api * api = (magic_api *) ptr;
int x,y; int x, y;
for (y = 0; y < last->h; y++){ for (y = 0; y < last->h; y++)
for (x=0; x < last->w; x++){ {
do_blur_pixel(ptr, which, canvas, last, x, y); for (x = 0; x < last->w; x++)
} {
} do_blur_pixel(ptr, which, canvas, last, x, y);
}
}
} }
//do the effect for the brush //do the effect for the brush
static void do_blur_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ static void do_blur_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
int xx, yy; int xx, yy;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - blur_RADIUS; yy < y + blur_RADIUS; yy++) for (yy = y - blur_RADIUS; yy < y + blur_RADIUS; yy++)
{
for (xx = x - blur_RADIUS; xx < x + blur_RADIUS; xx++)
{ {
if (api->in_circle(xx - x, yy - y, blur_RADIUS) && for (xx = x - blur_RADIUS; xx < x + blur_RADIUS; xx++)
!api->touched(xx, yy)) {
{ if (api->in_circle(xx - x, yy - y, blur_RADIUS) && !api->touched(xx, yy))
do_blur_pixel(api, which, canvas, last, xx, yy); {
} do_blur_pixel(api, which, canvas, last, xx, yy);
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void blur_drag(magic_api * api, int which, SDL_Surface * canvas, void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_blur_brush); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_blur_brush);
api->playsound(blur_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(blur_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - blur_RADIUS; update_rect->x = ox - blur_RADIUS;
update_rect->y = oy - blur_RADIUS; update_rect->y = oy - blur_RADIUS;
@ -206,41 +238,46 @@ void blur_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void blur_click(magic_api * api, int which, int mode, void blur_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
blur_drag(api, which, canvas, last, x, y, x, y, update_rect); blur_drag(api, which, canvas, last, x, y, x, y, update_rect);
else{ else
update_rect->x = 0; {
update_rect->y = 0; update_rect->x = 0;
update_rect->w = canvas->w; update_rect->y = 0;
update_rect->h = canvas->h; update_rect->w = canvas->w;
do_blur_full(api, canvas, last, which); update_rect->h = canvas->h;
api->playsound(blur_snd_effect[which], 128, 255); do_blur_full(api, canvas, last, which);
} api->playsound(blur_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void blur_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void blur_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void blur_shutdown(magic_api * api ATTRIBUTE_UNUSED) void blur_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<blur_NUM_TOOLS; i++){
if(blur_snd_effect[i] != NULL){ for (i = 0; i < blur_NUM_TOOLS; i++)
Mix_FreeChunk(blur_snd_effect[i]); {
} if (blur_snd_effect[i] != NULL)
} {
Mix_FreeChunk(blur_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void blur_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void blur_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -250,15 +287,17 @@ int blur_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
return 0; return 0;
} }
void blur_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void blur_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void blur_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void blur_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int blur_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int blur_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -31,14 +31,15 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* For RAND_MAX */ #include <stdlib.h> /* For RAND_MAX */
#include "tp_magic_api.h" #include "tp_magic_api.h"
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
/* What tools we contain: */ /* What tools we contain: */
enum { enum
{
TOOL_LARGEBRICKS, TOOL_LARGEBRICKS,
TOOL_SMALLBRICKS, TOOL_SMALLBRICKS,
NUM_TOOLS NUM_TOOLS
@ -47,29 +48,24 @@ enum {
/* Our globals: */ /* Our globals: */
static Mix_Chunk * brick_snd; static Mix_Chunk *brick_snd;
static Uint8 bricks_r, bricks_g, bricks_b; static Uint8 bricks_r, bricks_g, bricks_b;
/* Local function prototype: */ /* Local function prototype: */
static void do_brick(magic_api * api, SDL_Surface * canvas, static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y, int w, int h);
int x, int y, int w, int h);
int bricks_init(magic_api * api); int bricks_init(magic_api * api);
Uint32 bricks_api_version(void); Uint32 bricks_api_version(void);
int bricks_get_tool_count(magic_api * api); int bricks_get_tool_count(magic_api * api);
SDL_Surface * bricks_get_icon(magic_api * api, int which); SDL_Surface *bricks_get_icon(magic_api * api, int which);
char * bricks_get_name(magic_api * api, int which); char *bricks_get_name(magic_api * api, int which);
char * bricks_get_description(magic_api * api, int which, int mode); char *bricks_get_description(magic_api * api, int which, int mode);
void bricks_drag(magic_api * api, int which, SDL_Surface * canvas, void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void bricks_click(magic_api * api, int which, int mode, void bricks_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect); void bricks_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect); //An empty function. Is there a purpose to this? Ask moderator.
void bricks_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect); //An empty function. Is there a purpose to this? Ask moderator.
void bricks_shutdown(magic_api * api); void bricks_shutdown(magic_api * api);
void bricks_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void bricks_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int bricks_requires_colors(magic_api * api, int which); int bricks_requires_colors(magic_api * api, int which);
@ -82,65 +78,64 @@ int bricks_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/brick.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/brick.wav", api->data_directory);
api->data_directory);
brick_snd = Mix_LoadWAV(fname); brick_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 bricks_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 bricks_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int bricks_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int bricks_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * bricks_get_icon(magic_api * api, int which) SDL_Surface *bricks_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == TOOL_LARGEBRICKS) if (which == TOOL_LARGEBRICKS)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/largebrick.png", snprintf(fname, sizeof(fname), "%s/images/magic/largebrick.png", api->data_directory);
api->data_directory); }
}
else if (which == TOOL_SMALLBRICKS) else if (which == TOOL_SMALLBRICKS)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/smallbrick.png", snprintf(fname, sizeof(fname), "%s/images/magic/smallbrick.png", api->data_directory);
api->data_directory); }
}
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * bricks_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *bricks_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
/* Both are named "Bricks", at the moment: */ /* Both are named "Bricks", at the moment: */
return(strdup(gettext_noop("Bricks"))); return (strdup(gettext_noop("Bricks")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * bricks_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *bricks_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (which == TOOL_LARGEBRICKS) if (which == TOOL_LARGEBRICKS)
return(strdup(gettext_noop("Click and drag to draw large bricks."))); return (strdup(gettext_noop("Click and drag to draw large bricks.")));
else if (which == TOOL_SMALLBRICKS) else if (which == TOOL_SMALLBRICKS)
return(strdup(gettext_noop("Click and drag to draw small bricks."))); return (strdup(gettext_noop("Click and drag to draw small bricks.")));
return(NULL); return (NULL);
} }
// Do the effect: // Do the effect:
static void do_bricks(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void do_bricks(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
// "specified" means the brick itself, w/o morter // "specified" means the brick itself, w/o morter
// "nominal" means brick-to-brick (includes morter) // "nominal" means brick-to-brick (includes morter)
@ -148,22 +143,22 @@ static void do_bricks(void * ptr, int which, SDL_Surface * canvas, SDL_Surface *
int nominal_length; int nominal_length;
int brick_x, brick_y; int brick_x, brick_y;
int vertical_joint = 2; // between a brick and the one above/below int vertical_joint = 2; // between a brick and the one above/below
int horizontal_joint = 2; // between a brick and the one to the side int horizontal_joint = 2; // between a brick and the one to the side
int nominal_width = 18; int nominal_width = 18;
int nominal_height = 12; // 11 to 14, for joints of 2 int nominal_height = 12; // 11 to 14, for joints of 2
static unsigned char *map; static unsigned char *map;
static int x_count; static int x_count;
static int y_count; static int y_count;
unsigned char *mybrick; unsigned char *mybrick;
if (which == TOOL_LARGEBRICKS) if (which == TOOL_LARGEBRICKS)
{ {
vertical_joint = 4; // between a brick and the one above/below vertical_joint = 4; // between a brick and the one above/below
horizontal_joint = 4; // between a brick and the one to the side horizontal_joint = 4; // between a brick and the one to the side
nominal_width = 36; nominal_width = 36;
nominal_height = 24; // 11 to 14, for joints of 2 nominal_height = 24; // 11 to 14, for joints of 2
} }
nominal_length = 2 * nominal_width; nominal_length = 2 * nominal_width;
specified_width = nominal_width - horizontal_joint; specified_width = nominal_width - horizontal_joint;
@ -171,69 +166,79 @@ static void do_bricks(void * ptr, int which, SDL_Surface * canvas, SDL_Surface *
specified_length = nominal_length - horizontal_joint; specified_length = nominal_length - horizontal_joint;
if (!api->button_down()) if (!api->button_down())
{ {
if (map) if (map)
free(map); free(map);
// the "+ 3" allows for both ends and misalignment // the "+ 3" allows for both ends and misalignment
x_count = (canvas->w + nominal_width - 1) / nominal_width + 3; x_count = (canvas->w + nominal_width - 1) / nominal_width + 3;
y_count = (canvas->h + nominal_height - 1) / nominal_height + 3; y_count = (canvas->h + nominal_height - 1) / nominal_height + 3;
map = calloc(x_count, y_count); map = calloc(x_count, y_count);
} }
brick_x = x / nominal_width; brick_x = x / nominal_width;
brick_y = y / nominal_height; brick_y = y / nominal_height;
mybrick = map + brick_x + 1 + (brick_y + 1) * x_count; mybrick = map + brick_x + 1 + (brick_y + 1) * x_count;
if ((unsigned) x < (unsigned) canvas->w if ((unsigned)x < (unsigned)canvas->w && (unsigned)y < (unsigned)canvas->h && !*mybrick)
&& (unsigned) y < (unsigned) canvas->h && !*mybrick)
{
int my_x = brick_x * nominal_width;
int my_w = specified_width;
*mybrick = 1;
// FIXME:
//SDL_LockSurface(canvas);
if ((brick_y ^ brick_x) & 1)
{ {
if (mybrick[1]) int my_x = brick_x * nominal_width;
my_w = specified_length; int my_w = specified_width;
*mybrick = 1;
// FIXME:
//SDL_LockSurface(canvas);
if ((brick_y ^ brick_x) & 1)
{
if (mybrick[1])
my_w = specified_length;
}
else if (mybrick[-1])
{
my_x -= nominal_width;
my_w = specified_length;
}
do_brick(api, canvas, my_x, brick_y * nominal_height, my_w, specified_height);
// FIXME:
// SDL_UnlockSurface(canvas);
// upper left corner and lower right corner
// FIXME
/*
update_canvas(brick_x * nominal_width - nominal_width,
brick_y * nominal_height - vertical_joint,
brick_x * nominal_width + specified_length,
(brick_y + 1) * nominal_height);
*/
} }
else if (mybrick[-1])
{
my_x -= nominal_width;
my_w = specified_length;
}
do_brick(api, canvas, my_x, brick_y * nominal_height,
my_w, specified_height);
// FIXME:
// SDL_UnlockSurface(canvas);
// upper left corner and lower right corner
// FIXME
/*
update_canvas(brick_x * nominal_width - nominal_width,
brick_y * nominal_height - vertical_joint,
brick_x * nominal_width + specified_length,
(brick_y + 1) * nominal_height);
*/
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void bricks_drag(magic_api * api, int which, SDL_Surface * canvas, void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_bricks); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_bricks);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = x - 64; update_rect->x = x - 64;
update_rect->y = y - 64; update_rect->y = y - 64;
@ -245,15 +250,14 @@ void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void bricks_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void bricks_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
bricks_drag(api, which, canvas, last, x, y, x, y, update_rect); bricks_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void bricks_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void bricks_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -278,23 +282,16 @@ int bricks_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
return 1; return 1;
} }
static void do_brick(magic_api * api, SDL_Surface * canvas, static void do_brick(magic_api * api, SDL_Surface * canvas, int x, int y, int w, int h)
int x, int y, int w, int h)
{ {
SDL_Rect dest; SDL_Rect dest;
// brick color: 127,76,73 // brick color: 127,76,73
double ran_r = rand() / (double) RAND_MAX; double ran_r = rand() / (double)RAND_MAX;
double ran_g = rand() / (double) RAND_MAX; double ran_g = rand() / (double)RAND_MAX;
double base_r = double base_r = api->sRGB_to_linear(bricks_r) * 1.5 + api->sRGB_to_linear(127) * 5.0 + ran_r;
api->sRGB_to_linear(bricks_r) * 1.5 + double base_g = api->sRGB_to_linear(bricks_g) * 1.5 + api->sRGB_to_linear(76) * 5.0 + ran_g;
api->sRGB_to_linear(127) * 5.0 + ran_r; double base_b = api->sRGB_to_linear(bricks_b) * 1.5 + api->sRGB_to_linear(73) * 5.0 + (ran_r + ran_g * 2.0) / 3.0;
double base_g =
api->sRGB_to_linear(bricks_g) * 1.5 +
api->sRGB_to_linear(76) * 5.0 + ran_g;
double base_b =
api->sRGB_to_linear(bricks_b) * 1.5 +
api->sRGB_to_linear(73) * 5.0 + (ran_r + ran_g * 2.0) / 3.0;
Uint8 r = api->linear_to_sRGB(base_r / 7.5); Uint8 r = api->linear_to_sRGB(base_r / 7.5);
Uint8 g = api->linear_to_sRGB(base_g / 7.5); Uint8 g = api->linear_to_sRGB(base_g / 7.5);
@ -315,16 +312,16 @@ static void do_brick(magic_api * api, SDL_Surface * canvas,
} }
void bricks_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void bricks_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void bricks_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void bricks_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int bricks_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int bricks_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -41,32 +41,29 @@ typedef struct
float x, y; float x, y;
} Point2D; } Point2D;
static Mix_Chunk * calligraphy_snd; static Mix_Chunk *calligraphy_snd;
static Point2D calligraphy_control_points[4]; static Point2D calligraphy_control_points[4];
static int calligraphy_r, calligraphy_g, calligraphy_b; static int calligraphy_r, calligraphy_g, calligraphy_b;
static int calligraphy_old_thick; static int calligraphy_old_thick;
static Uint32 calligraphy_last_time; static Uint32 calligraphy_last_time;
static SDL_Surface * calligraphy_brush, * calligraphy_colored_brush; static SDL_Surface *calligraphy_brush, *calligraphy_colored_brush;
/* Local Function Prototypes */ /* Local Function Prototypes */
static Point2D calligraphy_PointOnCubicBezier(Point2D* cp, float t); static Point2D calligraphy_PointOnCubicBezier(Point2D * cp, float t);
static void calligraphy_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve); static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static float calligraphy_dist(float x1, float y1, float x2, float y2); static float calligraphy_dist(float x1, float y1, float x2, float y2);
int calligraphy_init(magic_api * api); int calligraphy_init(magic_api * api);
Uint32 calligraphy_api_version(void); Uint32 calligraphy_api_version(void);
int calligraphy_get_tool_count(magic_api * api); int calligraphy_get_tool_count(magic_api * api);
SDL_Surface * calligraphy_get_icon(magic_api * api, int which); SDL_Surface *calligraphy_get_icon(magic_api * api, int which);
char * calligraphy_get_name(magic_api * api, int which); char *calligraphy_get_name(magic_api * api, int which);
char * calligraphy_get_description(magic_api * api, int which, int mode); char *calligraphy_get_description(magic_api * api, int which, int mode);
void calligraphy_drag(magic_api * api, int which, SDL_Surface * canvas, void calligraphy_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void calligraphy_click(magic_api * api, int which, int mode, void calligraphy_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void calligraphy_release(magic_api * api, int which, void calligraphy_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void calligraphy_shutdown(magic_api * api); void calligraphy_shutdown(magic_api * api);
void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int calligraphy_requires_colors(magic_api * api, int which); int calligraphy_requires_colors(magic_api * api, int which);
@ -79,19 +76,17 @@ int calligraphy_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/calligraphy.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/calligraphy.ogg", api->data_directory);
api->data_directory);
calligraphy_snd = Mix_LoadWAV(fname); calligraphy_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy_brush.png", snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy_brush.png", api->data_directory);
api->data_directory);
calligraphy_brush = IMG_Load(fname); calligraphy_brush = IMG_Load(fname);
calligraphy_colored_brush = NULL; calligraphy_colored_brush = NULL;
if (calligraphy_brush == NULL) if (calligraphy_brush == NULL)
return(0); return (0);
calligraphy_last_time = 0; calligraphy_last_time = 0;
@ -100,53 +95,54 @@ int calligraphy_init(magic_api * api)
calligraphy_g = -1; calligraphy_g = -1;
calligraphy_b = -1; calligraphy_b = -1;
return(1); return (1);
} }
Uint32 calligraphy_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 calligraphy_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// Only one tool: // Only one tool:
int calligraphy_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int calligraphy_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icon: // Load our icon:
SDL_Surface * calligraphy_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *calligraphy_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy.png", snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy.png", api->data_directory);
api->data_directory); return (IMG_Load(fname));
return(IMG_Load(fname));
} }
// Return our name, localized: // Return our name, localized:
char * calligraphy_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *calligraphy_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Calligraphy"))); return (strdup(gettext_noop("Calligraphy")));
} }
// Return our description, localized: // Return our description, localized:
char * calligraphy_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *calligraphy_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{ {
return(strdup( return (strdup(gettext_noop("Click and drag the mouse around to draw in calligraphy.")));
gettext_noop("Click and drag the mouse around to draw in calligraphy.")));
} }
void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
Point2D * curve; Point2D *curve;
int i, n_points, thick, new_thick; int i, n_points, thick, new_thick;
Uint32 colr; Uint32 colr;
SDL_Rect src, dest; SDL_Rect src, dest;
// if (SDL_GetTicks() < calligraphy_last_time + 5) // if (SDL_GetTicks() < calligraphy_last_time + 5)
// return; // return;
calligraphy_control_points[0].x = calligraphy_control_points[1].x; calligraphy_control_points[0].x = calligraphy_control_points[1].x;
calligraphy_control_points[0].y = calligraphy_control_points[1].y; calligraphy_control_points[0].y = calligraphy_control_points[1].y;
calligraphy_control_points[1].x = calligraphy_control_points[2].x; calligraphy_control_points[1].x = calligraphy_control_points[2].x;
@ -170,82 +166,76 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
*/ */
n_points = calligraphy_dist(calligraphy_control_points[0].x, n_points = calligraphy_dist(calligraphy_control_points[0].x,
calligraphy_control_points[0].y, calligraphy_control_points[0].y,
calligraphy_control_points[1].x, calligraphy_control_points[1].x,
calligraphy_control_points[1].y) + calligraphy_control_points[1].y) +
calligraphy_dist(calligraphy_control_points[1].x, calligraphy_dist(calligraphy_control_points[1].x,
calligraphy_control_points[1].y, calligraphy_control_points[1].y,
calligraphy_control_points[2].x, calligraphy_control_points[2].x,
calligraphy_control_points[2].y) + calligraphy_control_points[2].y) +
calligraphy_dist(calligraphy_control_points[2].x, calligraphy_dist(calligraphy_control_points[2].x,
calligraphy_control_points[2].y, calligraphy_control_points[2].y, calligraphy_control_points[3].x, calligraphy_control_points[3].y);
calligraphy_control_points[3].x,
calligraphy_control_points[3].y);
if (n_points == 0) if (n_points == 0)
return; // No-op; not any points to plot return; // No-op; not any points to plot
curve = (Point2D *) malloc(sizeof(Point2D) * n_points); curve = (Point2D *) malloc(sizeof(Point2D) * n_points);
calligraphy_ComputeBezier(calligraphy_control_points, n_points, curve); calligraphy_ComputeBezier(calligraphy_control_points, n_points, curve);
colr = SDL_MapRGB(canvas->format, colr = SDL_MapRGB(canvas->format, calligraphy_r, calligraphy_g, calligraphy_b);
calligraphy_r,
calligraphy_g,
calligraphy_b);
new_thick = 40 - min((n_points /* / 2 */), 32); new_thick = 40 - min((n_points /* / 2 */ ), 32);
for (i = 0; i < n_points - 1; i++) for (i = 0; i < n_points - 1; i++)
{
thick = ((new_thick * i) +
(calligraphy_old_thick * (n_points - i))) / n_points;
/* The new way, using an antialiased brush bitmap */
x = curve[i].x;
y = curve[i].y;
src.x = calligraphy_brush->w - thick / 2 - thick / 4;
src.w = thick / 2 + thick / 4;
src.y = 0;
src.h = thick / 4;
dest.x = x - thick / 4;
dest.y = y - thick / 4;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
src.x = 0;
src.w = thick / 2 + thick / 4;
src.y = calligraphy_brush->h - thick / 4;
src.h = thick / 4;
dest.x = x - thick / 2;
dest.y = y;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
/* Old way; using putpixel:
SDL_LockSurface(canvas);
for (j = -(thick / 2); j < (thick / 2) + 1; j++)
{ {
x = curve[i].x + j; thick = ((new_thick * i) + (calligraphy_old_thick * (n_points - i))) / n_points;
y = curve[i].y - (j / 2); // 30 degrees
api->putpixel(canvas, x, y, colr);
api->putpixel(canvas, x + 1, y, colr); /* The new way, using an antialiased brush bitmap */
api->putpixel(canvas, x, y + 1, colr);
api->putpixel(canvas, x + 1, y + 1, colr); x = curve[i].x;
y = curve[i].y;
src.x = calligraphy_brush->w - thick / 2 - thick / 4;
src.w = thick / 2 + thick / 4;
src.y = 0;
src.h = thick / 4;
dest.x = x - thick / 4;
dest.y = y - thick / 4;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
src.x = 0;
src.w = thick / 2 + thick / 4;
src.y = calligraphy_brush->h - thick / 4;
src.h = thick / 4;
dest.x = x - thick / 2;
dest.y = y;
SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
/* Old way; using putpixel:
SDL_LockSurface(canvas);
for (j = -(thick / 2); j < (thick / 2) + 1; j++)
{
x = curve[i].x + j;
y = curve[i].y - (j / 2); // 30 degrees
api->putpixel(canvas, x, y, colr);
api->putpixel(canvas, x + 1, y, colr);
api->putpixel(canvas, x, y + 1, colr);
api->putpixel(canvas, x + 1, y + 1, colr);
}
SDL_UnlockSurface(canvas);
*/
} }
SDL_UnlockSurface(canvas);
*/
}
calligraphy_old_thick = (calligraphy_old_thick + new_thick) / 2; calligraphy_old_thick = (calligraphy_old_thick + new_thick) / 2;
@ -253,8 +243,20 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -272,8 +274,8 @@ void calligraphy_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface *
} }
void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
calligraphy_old_thick = 8; calligraphy_old_thick = 8;
calligraphy_last_time = 0; calligraphy_last_time = 0;
@ -290,8 +292,8 @@ void calligraphy_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
void calligraphy_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void calligraphy_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -313,9 +315,7 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
Uint8 a; Uint8 a;
Uint32 amask; Uint32 amask;
if (calligraphy_r == r && if (calligraphy_r == r && calligraphy_g == g && calligraphy_b == b)
calligraphy_g == g &&
calligraphy_b == b)
return; return;
calligraphy_r = r; calligraphy_r = r;
@ -325,9 +325,7 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
if (calligraphy_colored_brush != NULL) if (calligraphy_colored_brush != NULL)
SDL_FreeSurface(calligraphy_colored_brush); SDL_FreeSurface(calligraphy_colored_brush);
amask = ~(calligraphy_brush->format->Rmask | amask = ~(calligraphy_brush->format->Rmask | calligraphy_brush->format->Gmask | calligraphy_brush->format->Bmask);
calligraphy_brush->format->Gmask |
calligraphy_brush->format->Bmask);
calligraphy_colored_brush = calligraphy_colored_brush =
SDL_CreateRGBSurface(SDL_SWSURFACE, SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -335,30 +333,25 @@ void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
calligraphy_brush->h, calligraphy_brush->h,
calligraphy_brush->format->BitsPerPixel, calligraphy_brush->format->BitsPerPixel,
calligraphy_brush->format->Rmask, calligraphy_brush->format->Rmask,
calligraphy_brush->format->Gmask, calligraphy_brush->format->Gmask, calligraphy_brush->format->Bmask, amask);
calligraphy_brush->format->Bmask, amask);
if (calligraphy_colored_brush == NULL) if (calligraphy_colored_brush == NULL)
return; // FIXME: Error! return; // FIXME: Error!
SDL_LockSurface(calligraphy_brush); SDL_LockSurface(calligraphy_brush);
SDL_LockSurface(calligraphy_colored_brush); SDL_LockSurface(calligraphy_colored_brush);
for (y = 0; y < calligraphy_brush->h; y++) for (y = 0; y < calligraphy_brush->h; y++)
{
for (x = 0; x < calligraphy_brush->w; x++)
{ {
SDL_GetRGBA(api->getpixel(calligraphy_brush, x, y), for (x = 0; x < calligraphy_brush->w; x++)
calligraphy_brush->format, &r, &g, &b, &a); {
SDL_GetRGBA(api->getpixel(calligraphy_brush, x, y), calligraphy_brush->format, &r, &g, &b, &a);
api->putpixel(calligraphy_colored_brush, x, y, api->putpixel(calligraphy_colored_brush, x, y,
SDL_MapRGBA(calligraphy_colored_brush->format, SDL_MapRGBA(calligraphy_colored_brush->format, calligraphy_r, calligraphy_g, calligraphy_b, a));
calligraphy_r, }
calligraphy_g,
calligraphy_b, a));
} }
}
SDL_UnlockSurface(calligraphy_colored_brush); SDL_UnlockSurface(calligraphy_colored_brush);
SDL_UnlockSurface(calligraphy_brush); SDL_UnlockSurface(calligraphy_brush);
@ -384,32 +377,32 @@ cp[3] is the end point, or P3 in the above diagram
t is the parameter value, 0 <= t <= 1 t is the parameter value, 0 <= t <= 1
*/ */
static Point2D calligraphy_PointOnCubicBezier( Point2D* cp, float t ) static Point2D calligraphy_PointOnCubicBezier(Point2D * cp, float t)
{ {
float ax, bx, cx; float ax, bx, cx;
float ay, by, cy; float ay, by, cy;
float tSquared, tCubed; float tSquared, tCubed;
Point2D result; Point2D result;
/* calculate the polynomial coefficients */ /* calculate the polynomial coefficients */
cx = 3.0 * (cp[1].x - cp[0].x); cx = 3.0 * (cp[1].x - cp[0].x);
bx = 3.0 * (cp[2].x - cp[1].x) - cx; bx = 3.0 * (cp[2].x - cp[1].x) - cx;
ax = cp[3].x - cp[0].x - cx - bx; ax = cp[3].x - cp[0].x - cx - bx;
cy = 3.0 * (cp[1].y - cp[0].y); cy = 3.0 * (cp[1].y - cp[0].y);
by = 3.0 * (cp[2].y - cp[1].y) - cy; by = 3.0 * (cp[2].y - cp[1].y) - cy;
ay = cp[3].y - cp[0].y - cy - by; ay = cp[3].y - cp[0].y - cy - by;
/* calculate the curve point at parameter value t */ /* calculate the curve point at parameter value t */
tSquared = t * t; tSquared = t * t;
tCubed = tSquared * t; tCubed = tSquared * t;
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x; result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y; result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
return result; return result;
} }
@ -420,34 +413,37 @@ static Point2D calligraphy_PointOnCubicBezier( Point2D* cp, float t )
<sizeof(Point2D) numberOfPoints> <sizeof(Point2D) numberOfPoints>
*/ */
static void calligraphy_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve) static void calligraphy_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
{ {
float dt; float dt;
int i; int i;
dt = 1.0 / ( numberOfPoints - 1 ); dt = 1.0 / (numberOfPoints - 1);
for( i = 0; i < numberOfPoints; i++) for (i = 0; i < numberOfPoints; i++)
curve[i] = calligraphy_PointOnCubicBezier( cp, i*dt ); curve[i] = calligraphy_PointOnCubicBezier(cp, i * dt);
} }
static float calligraphy_dist(float x1, float y1, float x2, float y2) static float calligraphy_dist(float x1, float y1, float x2, float y2)
{ {
float d; float d;
d = (sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))); d = (sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
return d; return d;
} }
void calligraphy_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void calligraphy_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void calligraphy_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void calligraphy_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int calligraphy_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int calligraphy_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -38,7 +38,7 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * cartoon_snd; static Mix_Chunk *cartoon_snd;
#define OUTLINE_THRESH 48 #define OUTLINE_THRESH 48
@ -46,20 +46,16 @@ static Mix_Chunk * cartoon_snd;
int cartoon_init(magic_api * api); int cartoon_init(magic_api * api);
Uint32 cartoon_api_version(void); Uint32 cartoon_api_version(void);
int cartoon_get_tool_count(magic_api * api); int cartoon_get_tool_count(magic_api * api);
SDL_Surface * cartoon_get_icon(magic_api * api, int which); SDL_Surface *cartoon_get_icon(magic_api * api, int which);
char * cartoon_get_name(magic_api * api, int which); char *cartoon_get_name(magic_api * api, int which);
char * cartoon_get_description(magic_api * api, int which, int mode); char *cartoon_get_description(magic_api * api, int which, int mode);
static void do_cartoon(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_cartoon(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas, void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void cartoon_click(magic_api * api, int which, int mode, void cartoon_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void cartoon_release(magic_api * api, int which, void cartoon_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void cartoon_shutdown(magic_api * api); void cartoon_shutdown(magic_api * api);
void cartoon_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void cartoon_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int cartoon_requires_colors(magic_api * api, int which); int cartoon_requires_colors(magic_api * api, int which);
@ -74,51 +70,50 @@ int cartoon_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/cartoon.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/cartoon.wav", api->data_directory);
api->data_directory);
cartoon_snd = Mix_LoadWAV(fname); cartoon_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 cartoon_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 cartoon_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int cartoon_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int cartoon_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * cartoon_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *cartoon_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/cartoon.png", snprintf(fname, sizeof(fname), "%s/images/magic/cartoon.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * cartoon_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *cartoon_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Cartoon"))); return (strdup(gettext_noop("Cartoon")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * cartoon_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *cartoon_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop( return (strdup(gettext_noop("Click and drag the mouse around to turn the picture into a cartoon.")));
"Click and drag the mouse around to turn the picture into a cartoon.")));
} }
// Do the effect: // Do the effect:
static void do_cartoon(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, static void do_cartoon(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
Uint8 r1, g1, b1, r2, g2, b2; Uint8 r1, g1, b1, r2, g2, b2;
Uint8 r, g, b; Uint8 r, g, b;
@ -127,86 +122,90 @@ static void do_cartoon(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * can
/* First, convert colors to more cartoony ones: */ /* First, convert colors to more cartoony ones: */
for (yy = y - 16; yy < y + 16; yy = yy + 1) for (yy = y - 16; yy < y + 16; yy = yy + 1)
{
for (xx = x - 16; xx < x + 16; xx = xx + 1)
{ {
if (api->in_circle(xx - x, yy - y, 16)) for (xx = x - 16; xx < x + 16; xx = xx + 1)
{ {
/* Get original color: */ if (api->in_circle(xx - x, yy - y, 16))
{
/* Get original color: */
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b); SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
api->rgbtohsv(r, g, b, &hue, &sat, &val); api->rgbtohsv(r, g, b, &hue, &sat, &val);
val = val - 0.5; val = val - 0.5;
val = val * 4; val = val * 4;
val = val + 0.5; val = val + 0.5;
if (val < 0) if (val < 0)
val = 0; val = 0;
else if (val > 1.0) else if (val > 1.0)
val = 1.0; val = 1.0;
val = floor(val * 4) / 4; val = floor(val * 4) / 4;
hue = floor(hue * 4) / 4; hue = floor(hue * 4) / 4;
sat = floor(sat * 4) / 4; sat = floor(sat * 4) / 4;
api->hsvtorgb(hue, sat, val, &r, &g, &b); api->hsvtorgb(hue, sat, val, &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
} }
}
} }
}
/* Then, draw dark outlines where there's a large contrast change */ /* Then, draw dark outlines where there's a large contrast change */
for (yy = y - 16; yy < y + 16; yy++) for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{ {
if (api->in_circle(xx - x, yy - y, 16)) for (xx = x - 16; xx < x + 16; xx++)
{
/* Get original color: */
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
SDL_GetRGB(api->getpixel(last, xx + 1, yy),
last->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, xx + 1, yy + 1),
last->format, &r2, &g2, &b2);
if (abs(((r + g + b) / 3) - (r1 + g1 + b1) / 3) > OUTLINE_THRESH
|| abs(((r + g + b) / 3) - (r2 + g2 + b2) / 3) >
OUTLINE_THRESH || abs(r - r1) > OUTLINE_THRESH
|| abs(g - g1) > OUTLINE_THRESH
|| abs(b - b1) > OUTLINE_THRESH
|| abs(r - r2) > OUTLINE_THRESH
|| abs(g - g2) > OUTLINE_THRESH
|| abs(b - b2) > OUTLINE_THRESH)
{ {
api->putpixel(canvas, xx - 1, yy, if (api->in_circle(xx - x, yy - y, 16))
SDL_MapRGB(canvas->format, 0, 0, 0)); {
api->putpixel(canvas, xx, yy - 1, /* Get original color: */
SDL_MapRGB(canvas->format, 0, 0, 0));
api->putpixel(canvas, xx - 1, yy - 1, SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
SDL_MapRGB(canvas->format, 0, 0, 0));
SDL_GetRGB(api->getpixel(last, xx + 1, yy), last->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, xx + 1, yy + 1), last->format, &r2, &g2, &b2);
if (abs(((r + g + b) / 3) - (r1 + g1 + b1) / 3) > OUTLINE_THRESH
|| abs(((r + g + b) / 3) - (r2 + g2 + b2) / 3) >
OUTLINE_THRESH || abs(r - r1) > OUTLINE_THRESH
|| abs(g - g1) > OUTLINE_THRESH
|| abs(b - b1) > OUTLINE_THRESH
|| abs(r - r2) > OUTLINE_THRESH || abs(g - g2) > OUTLINE_THRESH || abs(b - b2) > OUTLINE_THRESH)
{
api->putpixel(canvas, xx - 1, yy, SDL_MapRGB(canvas->format, 0, 0, 0));
api->putpixel(canvas, xx, yy - 1, SDL_MapRGB(canvas->format, 0, 0, 0));
api->putpixel(canvas, xx - 1, yy - 1, SDL_MapRGB(canvas->format, 0, 0, 0));
}
}
} }
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas, void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_cartoon); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_cartoon);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -218,16 +217,15 @@ void cartoon_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void cartoon_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void cartoon_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
cartoon_drag(api, which, canvas, last, x, y, x, y, update_rect); cartoon_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void cartoon_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void cartoon_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -239,7 +237,8 @@ void cartoon_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void cartoon_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void cartoon_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -249,15 +248,17 @@ int cartoon_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUT
return 0; return 0;
} }
void cartoon_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void cartoon_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void cartoon_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void cartoon_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int cartoon_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int cartoon_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); /* FIXME - Can also be turned into a full-image effect */ return (MODE_PAINT); /* FIXME - Can also be turned into a full-image effect */
} }

View file

@ -1,70 +1,67 @@
#include <time.h> //For time() #include <time.h> //For time()
#include "tp_magic_api.h" #include "tp_magic_api.h"
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
#define CONFETTI_BRUSH_SIZE 8 //radius of each confetti circle #define CONFETTI_BRUSH_SIZE 8 //radius of each confetti circle
#define CONFETTI_QUANTITY 3 //how many circles will be created every click? #define CONFETTI_QUANTITY 3 //how many circles will be created every click?
struct confetti_rgb struct confetti_rgb
{ {
Uint8 r, g, b; Uint8 r, g, b;
}; };
struct confetti_rgb confetti_colors; //storage for colors, just for having everything in one place struct confetti_rgb confetti_colors; //storage for colors, just for having everything in one place
Mix_Chunk * confetti_snd; Mix_Chunk *confetti_snd;
/* Local function prototypes: */ /* Local function prototypes: */
Uint32 confetti_api_version(void); Uint32 confetti_api_version(void);
void confetti_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void confetti_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int confetti_init(magic_api * api); int confetti_init(magic_api * api);
int confetti_get_tool_count(magic_api * api); int confetti_get_tool_count(magic_api * api);
SDL_Surface * confetti_get_icon(magic_api * api, int which); SDL_Surface *confetti_get_icon(magic_api * api, int which);
char * confetti_get_name(magic_api * api, int which); char *confetti_get_name(magic_api * api, int which);
char * confetti_get_description(magic_api * api, int which, int mode); char *confetti_get_description(magic_api * api, int which, int mode);
int confetti_requires_colors(magic_api * api, int which); int confetti_requires_colors(magic_api * api, int which);
void confetti_release(magic_api * api, int which, void confetti_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void confetti_shutdown(magic_api * api); void confetti_shutdown(magic_api * api);
inline char confetti_get_greater(const char what1, const char what2); inline char confetti_get_greater(const char what1, const char what2);
inline char confetti_get_lesser(const char what1, const char what2); inline char confetti_get_lesser(const char what1, const char what2);
Uint32 confetti_get_new_color(void * ptr, SDL_Surface * canvas); Uint32 confetti_get_new_color(void *ptr, SDL_Surface * canvas);
void confetti_click(magic_api * api, int which, int mode, void confetti_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void confetti_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void confetti_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void confetti_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void confetti_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int confetti_modes(magic_api * api, int which); int confetti_modes(magic_api * api, int which);
// Housekeeping functions // Housekeeping functions
void confetti_drag(magic_api * api, int which, SDL_Surface * canvas, void confetti_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
Uint32 confetti_api_version(void) Uint32 confetti_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void confetti_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure void confetti_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
{ {
confetti_colors.r=r; confetti_colors.r = r;
confetti_colors.g=g; confetti_colors.g = g;
confetti_colors.b=b; confetti_colors.b = b;
} }
int confetti_init(magic_api * api) int confetti_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/confetti.ogg", api->data_directory);
confetti_snd = Mix_LoadWAV(fname);
return(1); snprintf(fname, sizeof(fname), "%s/sounds/magic/confetti.ogg", api->data_directory);
confetti_snd = Mix_LoadWAV(fname);
return (1);
} }
int confetti_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int confetti_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -72,137 +69,168 @@ int confetti_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * confetti_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *confetti_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/confetti.png", snprintf(fname, sizeof(fname), "%s/images/magic/confetti.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * confetti_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Confetti")); } char *confetti_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Confetti"));
}
char * confetti_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Click to throw confetti!")); } char *confetti_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click to throw confetti!"));
}
int confetti_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 1; } int confetti_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 1;
}
void confetti_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void confetti_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void confetti_shutdown(magic_api * api ATTRIBUTE_UNUSED) void confetti_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ Mix_FreeChunk(confetti_snd); } {
Mix_FreeChunk(confetti_snd);
}
//private functions //private functions
inline char confetti_get_greater(const char what1, const char what2) { if (what1>what2) return what1; else return what2; }
inline char confetti_get_lesser(const char what1, const char what2) { if (what1<what2) return what1; else return what2; } inline char confetti_get_greater(const char what1, const char what2)
{
if (what1 > what2)
return what1;
else
return what2;
}
inline char confetti_get_lesser(const char what1, const char what2)
{
if (what1 < what2)
return what1;
else
return what2;
}
// Interactivity functions // Interactivity functions
Uint32 confetti_get_new_color(void * ptr, SDL_Surface * canvas) //this function creates new color very similar to the one choosen Uint32 confetti_get_new_color(void *ptr, SDL_Surface * canvas) //this function creates new color very similar to the one choosen
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
float hsv_h, hsv_s, hsv_v;
Uint8 temp_r, temp_g, temp_b;
api->rgbtohsv(confetti_colors.r, confetti_colors.g, confetti_colors.b, &hsv_h, &hsv_s, &hsv_v); //color choosen by user is converted
//to HSV palette
hsv_h+=((rand()%60)-30)%360; //Every circle has different, but float hsv_h, hsv_s, hsv_v;
//smilar color Uint8 temp_r, temp_g, temp_b;
if (hsv_h<0)
hsv_h *= -1;
api->hsvtorgb(hsv_h, hsv_s, hsv_v, &temp_r, &temp_g, &temp_b); //...and come back to RGB
return SDL_MapRGB(canvas->format, temp_r, temp_g, temp_b); api->rgbtohsv(confetti_colors.r, confetti_colors.g, confetti_colors.b, &hsv_h, &hsv_s, &hsv_v); //color choosen by user is converted
//to HSV palette
hsv_h += ((rand() % 60) - 30) % 360; //Every circle has different, but
//smilar color
if (hsv_h < 0)
hsv_h *= -1;
api->hsvtorgb(hsv_h, hsv_s, hsv_v, &temp_r, &temp_g, &temp_b); //...and come back to RGB
return SDL_MapRGB(canvas->format, temp_r, temp_g, temp_b);
} }
static void confetti_circle(void * ptr, int which ATTRIBUTE_UNUSED, static void confetti_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
Uint32 color=confetti_get_new_color(api, canvas); Uint32 color = confetti_get_new_color(api, canvas);
for (yy = y - CONFETTI_BRUSH_SIZE/2; yy < y + CONFETTI_BRUSH_SIZE/2; yy++) for (yy = y - CONFETTI_BRUSH_SIZE / 2; yy < y + CONFETTI_BRUSH_SIZE / 2; yy++)
for (xx = x - CONFETTI_BRUSH_SIZE/2; xx < x + CONFETTI_BRUSH_SIZE/2; xx++) for (xx = x - CONFETTI_BRUSH_SIZE / 2; xx < x + CONFETTI_BRUSH_SIZE / 2; xx++)
if (api->in_circle(xx - x , yy - y , CONFETTI_BRUSH_SIZE/2)) if (api->in_circle(xx - x, yy - y, CONFETTI_BRUSH_SIZE / 2))
api->putpixel(canvas, xx, yy, color); api->putpixel(canvas, xx, yy, color);
} }
void confetti_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void confetti_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
unsigned char i; unsigned char i;
char min_x = 0, max_x = 0, min_y = 0, max_y = 0; char min_x = 0, max_x = 0, min_y = 0, max_y = 0;
char dx = 0, dy = 0; char dx = 0, dy = 0;
for (i=0; i<CONFETTI_QUANTITY; i++)
{
srand((dx+dy)/2 + time(0)); //to get a unique seed even if dx and dy aren't defined
dx=(rand()%100)-50; //generate a value between <-50; +50>
dy=(rand()%100)-50; //to spread confetti around the cursor position
if (!i)
{
min_x=max_x=dx;
min_y=max_y=dy;
}
else
{
min_x=confetti_get_lesser(min_x, dx); //any candidates to new min/max values? Hands up please...
max_x=confetti_get_greater(max_x, dx);
min_y=confetti_get_lesser(min_y, dy);
max_y=confetti_get_greater(max_y, dy);
}
confetti_circle((void *)api, which, canvas, last, x+dx, y+dy);
}
update_rect->x = x+min_x - CONFETTI_BRUSH_SIZE/2; for (i = 0; i < CONFETTI_QUANTITY; i++)
update_rect->y = y+ min_y - CONFETTI_BRUSH_SIZE/2; {
update_rect->w = CONFETTI_BRUSH_SIZE*1.5+max_x-min_x; srand((dx + dy) / 2 + time(0)); //to get a unique seed even if dx and dy aren't defined
update_rect->h = CONFETTI_BRUSH_SIZE*1.5+max_y-min_y; dx = (rand() % 100) - 50; //generate a value between <-50; +50>
dy = (rand() % 100) - 50; //to spread confetti around the cursor position
api->playsound(confetti_snd, (x * 255) / canvas->w,255);
if (!i)
{
min_x = max_x = dx;
min_y = max_y = dy;
}
else
{
min_x = confetti_get_lesser(min_x, dx); //any candidates to new min/max values? Hands up please...
max_x = confetti_get_greater(max_x, dx);
min_y = confetti_get_lesser(min_y, dy);
max_y = confetti_get_greater(max_y, dy);
}
confetti_circle((void *)api, which, canvas, last, x + dx, y + dy);
}
update_rect->x = x + min_x - CONFETTI_BRUSH_SIZE / 2;
update_rect->y = y + min_y - CONFETTI_BRUSH_SIZE / 2;
update_rect->w = CONFETTI_BRUSH_SIZE * 1.5 + max_x - min_x;
update_rect->h = CONFETTI_BRUSH_SIZE * 1.5 + max_y - min_y;
api->playsound(confetti_snd, (x * 255) / canvas->w, 255);
} }
void confetti_drag(magic_api * api, int which, SDL_Surface * canvas, void confetti_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
int temp; int temp;
if (ox>x) {temp=x; x=ox; ox=temp;} if (ox > x)
if (oy>y) {temp=y; y=oy; oy=temp; } {
temp = x;
confetti_click(api, which, MODE_PAINT, canvas, snapshot, x, y, update_rect); x = ox;
ox = temp;
}
if (oy > y)
{
temp = y;
y = oy;
oy = temp;
}
confetti_click(api, which, MODE_PAINT, canvas, snapshot, x, y, update_rect);
} }
void confetti_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void confetti_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void confetti_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void confetti_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int confetti_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int confetti_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -31,11 +31,11 @@
/* -------------------------- */ /* -------------------------- */
#include <stdio.h> #include <stdio.h>
#include <string.h> // For "strdup()" #include <string.h> // For "strdup()"
#include "tp_magic_api.h" // Tux Paint "Magic" tool API header #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_image.h" // For IMG_Load(), to load our PNG icon
#include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects #include "SDL_mixer.h" // For Mix_LoadWAV(), to load our sound effects
@ -43,7 +43,7 @@
/* --------------------- */ /* --------------------- */
/* Sound effects: */ /* Sound effects: */
static Mix_Chunk * snd_effect; static Mix_Chunk *snd_effect;
/* Our local function prototypes: */ /* Our local function prototypes: */
@ -57,18 +57,16 @@ static Mix_Chunk * snd_effect;
Uint32 distortion_api_version(void); Uint32 distortion_api_version(void);
int distortion_init(magic_api * api); int distortion_init(magic_api * api);
int distortion_get_tool_count(magic_api * api); int distortion_get_tool_count(magic_api * api);
SDL_Surface * distortion_get_icon(magic_api * api, int which); SDL_Surface *distortion_get_icon(magic_api * api, int which);
char * distortion_get_name(magic_api * api, int which); char *distortion_get_name(magic_api * api, int which);
char * distortion_get_description(magic_api * api, int which, int mode); char *distortion_get_description(magic_api * api, int which, int mode);
int distortion_requires_colors(magic_api * api, int which); int distortion_requires_colors(magic_api * api, int which);
void distortion_shutdown(magic_api * api); void distortion_shutdown(magic_api * api);
void distortion_click(magic_api * api, int which, int mode, void distortion_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void distortion_release(magic_api * api, int which, void distortion_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void distortion_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void distortion_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void distortion_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void distortion_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
@ -76,12 +74,9 @@ void distortion_switchout(magic_api * api, int which, int mode, SDL_Surface * ca
int distortion_modes(magic_api * api, int which); int distortion_modes(magic_api * api, int which);
void distortion_drag(magic_api * api, int which, SDL_Surface * canvas, void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
static void distortion_line_callback(void * ptr, int which, static void distortion_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y);
/* Setup Functions: */ /* Setup Functions: */
@ -89,7 +84,7 @@ static void distortion_line_callback(void * ptr, int which,
Uint32 distortion_api_version(void) Uint32 distortion_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
@ -99,15 +94,13 @@ int distortion_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), snprintf(fname, sizeof(fname), "%s/sounds/magic/distortion.ogg", api->data_directory);
"%s/sounds/magic/distortion.ogg",
api->data_directory);
// Try to load the file! // Try to load the file!
snd_effect = Mix_LoadWAV(fname); snd_effect = Mix_LoadWAV(fname);
return(1); return (1);
} }
@ -115,39 +108,39 @@ int distortion_init(magic_api * api)
int distortion_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int distortion_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load icons // Load icons
SDL_Surface * distortion_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *distortion_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/distortion.png", snprintf(fname, sizeof(fname), "%s/images/magic/distortion.png", api->data_directory);
api->data_directory);
// Try to load the image, and return the results to Tux Paint: // Try to load the image, and return the results to Tux Paint:
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Report our "Magic" tool names // Report our "Magic" tool names
char * distortion_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *distortion_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Distortion"))); return (strdup(gettext_noop("Distortion")));
} }
// Report our "Magic" tool descriptions // Report our "Magic" tool descriptions
char * distortion_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *distortion_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag the mouse to cause distortion in your picture."))); return (strdup(gettext_noop("Click and drag the mouse to cause distortion in your picture.")));
} }
// Report whether we accept colors // Report whether we accept colors
@ -172,8 +165,7 @@ void distortion_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Affect the canvas on click: // Affect the canvas on click:
void distortion_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void distortion_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
distortion_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); distortion_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
@ -182,15 +174,25 @@ void distortion_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on drag: // Affect the canvas on drag:
void distortion_drag(magic_api * api, int which, SDL_Surface * canvas, void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, snapshot, api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, distortion_line_callback);
ox, oy, x, y, 1, distortion_line_callback);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 8; update_rect->x = ox - 8;
@ -199,33 +201,32 @@ void distortion_drag(magic_api * api, int which, SDL_Surface * canvas,
update_rect->h = (y + 8) - update_rect->h; update_rect->h = (y + 8) - update_rect->h;
api->playsound(snd_effect, api->playsound(snd_effect, (x * 255) / canvas->w, // pan
(x * 255) / canvas->w, // pan 255); // distance
255); // distance
} }
// Affect the canvas on release: // Affect the canvas on release:
void distortion_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void distortion_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void distortion_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void distortion_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
// Our "callback" function // Our "callback" function
static void distortion_line_callback(void * ptr, int which ATTRIBUTE_UNUSED, static void distortion_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
@ -234,28 +235,28 @@ static void distortion_line_callback(void * ptr, int which ATTRIBUTE_UNUSED,
// Tux Paint sends to us with the values we enumerated above. // Tux Paint sends to us with the values we enumerated above.
for (yy = -8; yy < 8; yy++) for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{ {
if (api->in_circle(xx, yy, 8)) for (xx = -8; xx < 8; xx++)
{ {
api->putpixel(canvas, x + xx, y + yy, if (api->in_circle(xx, yy, 8))
api->getpixel(snapshot, {
x + xx / 2, y + yy)); api->putpixel(canvas, x + xx, y + yy, api->getpixel(snapshot, x + xx / 2, y + yy));
} }
}
} }
}
} }
void distortion_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void distortion_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void distortion_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void distortion_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int distortion_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int distortion_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -35,27 +35,24 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * emboss_snd; static Mix_Chunk *emboss_snd;
// Prototypes // Prototypes
Uint32 emboss_api_version(void); Uint32 emboss_api_version(void);
int emboss_init(magic_api * api); int emboss_init(magic_api * api);
int emboss_get_tool_count(magic_api * api); int emboss_get_tool_count(magic_api * api);
SDL_Surface * emboss_get_icon(magic_api * api, int which); SDL_Surface *emboss_get_icon(magic_api * api, int which);
char * emboss_get_name(magic_api * api, int which); char *emboss_get_name(magic_api * api, int which);
char * emboss_get_description(magic_api * api, int which, int mode); char *emboss_get_description(magic_api * api, int which, int mode);
void emboss_drag(magic_api * api, int which, SDL_Surface * canvas, void emboss_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void emboss_click(magic_api * api, int which, int mode, void emboss_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void emboss_release(magic_api * api, int which, void emboss_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void emboss_shutdown(magic_api * api); void emboss_shutdown(magic_api * api);
void emboss_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void emboss_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -65,7 +62,10 @@ void emboss_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas
int emboss_modes(magic_api * api, int which); int emboss_modes(magic_api * api, int which);
Uint32 emboss_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 emboss_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -73,118 +73,125 @@ int emboss_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/emboss.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/emboss.ogg", api->data_directory);
api->data_directory);
emboss_snd = Mix_LoadWAV(fname); emboss_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int emboss_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int emboss_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * emboss_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *emboss_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/emboss.png", snprintf(fname, sizeof(fname), "%s/images/magic/emboss.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * emboss_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *emboss_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Emboss"))); return (strdup(gettext_noop("Emboss")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * emboss_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *emboss_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag the mouse to emboss the picture."))); return (strdup(gettext_noop("Click and drag the mouse to emboss the picture.")));
} }
// Do the effect: // Do the effect:
static void do_emboss(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, static void do_emboss(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
Uint8 r1, g1, b1, Uint8 r1, g1, b1, r2, g2, b2;
r2, g2, b2;
int r, g, b; int r, g, b;
float h, s, v; float h, s, v;
int avg1, avg2; int avg1, avg2;
for (yy = -16; yy < 16; yy++) for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{ {
if (api->in_circle(xx, yy, 16)) for (xx = -16; xx < 16; xx++)
{
if (!api->touched(x + xx, y + yy))
{ {
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1, &b1); if (api->in_circle(xx, yy, 16))
SDL_GetRGB(api->getpixel(last, x + xx + 2, y + yy + 2), last->format, &r2, &g2, &b2); {
if (!api->touched(x + xx, y + yy))
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, x + xx + 2, y + yy + 2), last->format, &r2, &g2, &b2);
avg1 = (r1 + g1 + b1) / 3; avg1 = (r1 + g1 + b1) / 3;
avg2 = (r2 + g2 + b2) / 3; avg2 = (r2 + g2 + b2) / 3;
api->rgbtohsv(r1, g1, b1, &h, &s, &v); api->rgbtohsv(r1, g1, b1, &h, &s, &v);
r = 128 + (((avg1 - avg2) * 3) / 2); r = 128 + (((avg1 - avg2) * 3) / 2);
if (r < 0) r = 0; if (r < 0)
if (r > 255) r = 255; r = 0;
g = b = r; if (r > 255)
r = 255;
g = b = r;
v = (r / 255.0); v = (r / 255.0);
api->hsvtorgb(h, s, v, &r1, &g1, &b1); api->hsvtorgb(h, s, v, &r1, &g1, &b1);
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r1, g1, b1)); api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r1, g1, b1));
}
}
} }
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void emboss_drag(magic_api * api, int which, SDL_Surface * canvas, void emboss_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_emboss); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_emboss);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
update_rect->w = (x + 16) - update_rect->x; update_rect->w = (x + 16) - update_rect->x;
update_rect->h = (y + 16) - update_rect->h; update_rect->h = (y + 16) - update_rect->h;
api->playsound(emboss_snd, api->playsound(emboss_snd, (x * 255) / canvas->w, 255);
(x * 255) / canvas->w, 255);
} }
// Affect the canvas on click: // Affect the canvas on click:
void emboss_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void emboss_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
emboss_drag(api, which, canvas, last, x, y, x, y, update_rect); emboss_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void emboss_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void emboss_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -196,7 +203,8 @@ void emboss_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void emboss_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void emboss_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -206,15 +214,17 @@ int emboss_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
return 0; return 0;
} }
void emboss_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void emboss_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void emboss_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void emboss_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int emboss_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int emboss_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); /* FIXME - Can also be turned into a full-image effect */ return (MODE_PAINT); /* FIXME - Can also be turned into a full-image effect */
} }

View file

@ -33,13 +33,14 @@
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
enum { enum
{
TOOL_FADE, TOOL_FADE,
TOOL_DARKEN, TOOL_DARKEN,
NUM_TOOLS NUM_TOOLS
}; };
static Mix_Chunk * snd_effects[NUM_TOOLS]; static Mix_Chunk *snd_effects[NUM_TOOLS];
/* Local function prototypes: */ /* Local function prototypes: */
@ -47,24 +48,17 @@ static Mix_Chunk * snd_effects[NUM_TOOLS];
int fade_darken_init(magic_api * api); int fade_darken_init(magic_api * api);
Uint32 fade_darken_api_version(void); Uint32 fade_darken_api_version(void);
int fade_darken_get_tool_count(magic_api * api); int fade_darken_get_tool_count(magic_api * api);
SDL_Surface * fade_darken_get_icon(magic_api * api, int which); SDL_Surface *fade_darken_get_icon(magic_api * api, int which);
char * fade_darken_get_name(magic_api * api, int which); char *fade_darken_get_name(magic_api * api, int which);
char * fade_darken_get_description(magic_api * api, int which, int mode); char *fade_darken_get_description(magic_api * api, int which, int mode);
static void do_fade_darken(void * ptr, int which, static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last, static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
static void do_fade_darken_paint(void * ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas, void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void fade_darken_click(magic_api * api, int which, int mode, void fade_darken_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fade_darken_release(magic_api * api, int which, void fade_darken_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fade_darken_shutdown(magic_api * api); void fade_darken_shutdown(magic_api * api);
void fade_darken_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void fade_darken_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int fade_darken_requires_colors(magic_api * api, int which); int fade_darken_requires_colors(magic_api * api, int which);
@ -76,139 +70,144 @@ int fade_darken_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/fade.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/fade.wav", api->data_directory);
api->data_directory);
snd_effects[TOOL_FADE] = Mix_LoadWAV(fname); snd_effects[TOOL_FADE] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/darken.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/darken.wav", api->data_directory);
api->data_directory);
snd_effects[TOOL_DARKEN] = Mix_LoadWAV(fname); snd_effects[TOOL_DARKEN] = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 fade_darken_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 fade_darken_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// Multiple tools: // Multiple tools:
int fade_darken_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int fade_darken_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
// Load our icon: // Load our icon:
SDL_Surface * fade_darken_get_icon(magic_api * api, int which) SDL_Surface *fade_darken_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == TOOL_FADE) if (which == TOOL_FADE)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/fade.png", snprintf(fname, sizeof(fname), "%s/images/magic/fade.png", api->data_directory);
api->data_directory); }
}
else if (which == TOOL_DARKEN) else if (which == TOOL_DARKEN)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/darken.png", snprintf(fname, sizeof(fname), "%s/images/magic/darken.png", api->data_directory);
api->data_directory); }
}
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our name, localized: // Return our name, localized:
char * fade_darken_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *fade_darken_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == TOOL_FADE) if (which == TOOL_FADE)
return(strdup(gettext_noop("Lighten"))); return (strdup(gettext_noop("Lighten")));
else if (which == TOOL_DARKEN) else if (which == TOOL_DARKEN)
return(strdup(gettext_noop("Darken"))); return (strdup(gettext_noop("Darken")));
return(NULL); return (NULL);
} }
// Return our description, localized: // Return our description, localized:
char * fade_darken_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode) char *fade_darken_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
{ {
if (which == TOOL_FADE) if (which == TOOL_FADE)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return(strdup(gettext_noop("Click and drag the mouse to lighten parts of your picture."))); return (strdup(gettext_noop("Click and drag the mouse to lighten parts of your picture.")));
else if (mode == MODE_FULLSCREEN) else if (mode == MODE_FULLSCREEN)
return(strdup(gettext_noop("Click to lighten your entire picture."))); return (strdup(gettext_noop("Click to lighten your entire picture.")));
} }
else if (which == TOOL_DARKEN) else if (which == TOOL_DARKEN)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return(strdup(gettext_noop("Click and drag the mouse to darken parts of your picture."))); return (strdup(gettext_noop("Click and drag the mouse to darken parts of your picture.")));
else if (mode == MODE_FULLSCREEN) else if (mode == MODE_FULLSCREEN)
return(strdup(gettext_noop("Click to darken your entire picture."))); return (strdup(gettext_noop("Click to darken your entire picture.")));
} }
return(NULL); return (NULL);
} }
static void do_fade_darken(void * ptr, int which, static void do_fade_darken(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{ {
Uint8 r, g, b; Uint8 r, g, b;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r, &g, &b); SDL_GetRGB(api->getpixel(last, x, y), last->format, &r, &g, &b);
if (which == TOOL_FADE) if (which == TOOL_FADE)
{ {
r = min(r + 48, 255); r = min(r + 48, 255);
g = min(g + 48, 255); g = min(g + 48, 255);
b = min(b + 48, 255); b = min(b + 48, 255);
} }
else if (which == TOOL_DARKEN) else if (which == TOOL_DARKEN)
{ {
r = max(r - 48, 0); r = max(r - 48, 0);
g = max(g - 48, 0); g = max(g - 48, 0);
b = max(b - 48, 0); b = max(b - 48, 0);
} }
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b)); api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
} }
// Callback that does the fade_darken color effect on a circle centered around x,y // Callback that does the fade_darken color effect on a circle centered around x,y
static void do_fade_darken_paint(void * ptr, int which, static void do_fade_darken_paint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{ {
int xx, yy; int xx, yy;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - 16; yy < y + 16; yy++) for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{ {
if (api->in_circle(xx - x, yy - y, 16) && for (xx = x - 16; xx < x + 16; xx++)
!api->touched(xx, yy)) {
{ if (api->in_circle(xx - x, yy - y, 16) && !api->touched(xx, yy))
do_fade_darken(api, which, canvas, last, xx, yy); {
} do_fade_darken(api, which, canvas, last, xx, yy);
}
}
} }
}
} }
// Ask Tux Paint to call our 'do_fade_darken_paint()' callback over a line // Ask Tux Paint to call our 'do_fade_darken_paint()' callback over a line
void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas, void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
SDL_LockSurface(last); SDL_LockSurface(last);
SDL_LockSurface(canvas); SDL_LockSurface(canvas);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_fade_darken_paint); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_fade_darken_paint);
SDL_UnlockSurface(canvas); SDL_UnlockSurface(canvas);
SDL_UnlockSurface(last); SDL_UnlockSurface(last);
api->playsound(snd_effects[which], (x * 255) / canvas->w, 255); api->playsound(snd_effects[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -219,32 +218,31 @@ void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
// Ask Tux Paint to call our 'do_fade_darken_paint()' callback at a single point, // Ask Tux Paint to call our 'do_fade_darken_paint()' callback at a single point,
// or 'do_fade_darken()' on the entire image // or 'do_fade_darken()' on the entire image
void fade_darken_click(magic_api * api, int which, int mode, void fade_darken_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
fade_darken_drag(api, which, canvas, last, x, y, x, y, update_rect); fade_darken_drag(api, which, canvas, last, x, y, x, y, update_rect);
else else
{ {
int xx, yy; int xx, yy;
for (yy = 0; yy < canvas->h; yy++) for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++) for (xx = 0; xx < canvas->w; xx++)
do_fade_darken(api, which, canvas, last, xx, yy); do_fade_darken(api, which, canvas, last, xx, yy);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
/* FIXME: Play sfx */ /* FIXME: Play sfx */
} }
} }
// Release // Release
void fade_darken_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void fade_darken_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -260,7 +258,7 @@ void fade_darken_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// We don't use colors // We don't use colors
void fade_darken_set_color(magic_api * api ATTRIBUTE_UNUSED, void fade_darken_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -270,15 +268,17 @@ int fade_darken_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTR
return 0; return 0;
} }
void fade_darken_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fade_darken_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void fade_darken_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fade_darken_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int fade_darken_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int fade_darken_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT | MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }

View file

@ -39,15 +39,13 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * fill_snd; static Mix_Chunk *fill_snd;
static Uint8 fill_r, fill_g, fill_b; static Uint8 fill_r, fill_g, fill_b;
/* Local function prototypes: */ /* Local function prototypes: */
static int colors_close(magic_api * api, SDL_Surface * canvas, static int colors_close(magic_api * api, SDL_Surface * canvas, Uint32 c1, Uint32 c2);
Uint32 c1, Uint32 c2); static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr);
static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y,
Uint32 cur_colr, Uint32 old_colr);
int fill_modes(magic_api * api, int which); int fill_modes(magic_api * api, int which);
void fill_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void fill_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fill_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void fill_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
@ -55,18 +53,15 @@ int fill_requires_colors(magic_api * api, int which);
void fill_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void fill_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void fill_shutdown(magic_api * api); void fill_shutdown(magic_api * api);
void fill_release(magic_api * api, int which, void fill_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fill_click(magic_api * api, int which, int mode, void fill_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fill_drag(magic_api * api, int which, SDL_Surface * canvas, void fill_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect); char *fill_get_description(magic_api * api, int which, int mode);
char * fill_get_description(magic_api * api, int which, int mode); char *fill_get_name(magic_api * api, int which);
char * fill_get_name(magic_api * api, int which);
int fill_get_tool_count(magic_api * api); int fill_get_tool_count(magic_api * api);
SDL_Surface * fill_get_icon(magic_api * api, int which); SDL_Surface *fill_get_icon(magic_api * api, int which);
Uint32 fill_api_version(void); Uint32 fill_api_version(void);
int fill_init(magic_api * api); int fill_init(magic_api * api);
@ -76,61 +71,59 @@ int fill_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/fill.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/fill.wav", api->data_directory);
api->data_directory);
fill_snd = Mix_LoadWAV(fname); fill_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 fill_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 fill_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int fill_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int fill_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * fill_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *fill_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/fill.png", snprintf(fname, sizeof(fname), "%s/images/magic/fill.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * fill_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *fill_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Fill"))); return (strdup(gettext_noop("Fill")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * fill_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *fill_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop( return (strdup(gettext_noop("Click in the picture to fill that area with color.")));
"Click in the picture to fill that area with color.")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void fill_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, void fill_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// Affect the canvas on click: // Affect the canvas on click:
void fill_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, void fill_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, SDL_Rect * update_rect) int x, int y, SDL_Rect * update_rect)
{ {
do_flood_fill(api, canvas, x, y, SDL_MapRGB(canvas->format, do_flood_fill(api, canvas, x, y, SDL_MapRGB(canvas->format, fill_r, fill_g, fill_b), api->getpixel(canvas, x, y));
fill_r, fill_g, fill_b),
api->getpixel(canvas, x, y));
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
@ -139,8 +132,8 @@ void fill_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_
} }
void fill_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void fill_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -164,42 +157,41 @@ int fill_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
} }
static int colors_close(magic_api * api, SDL_Surface * canvas, static int colors_close(magic_api * api, SDL_Surface * canvas, Uint32 c1, Uint32 c2)
Uint32 c1, Uint32 c2)
{ {
Uint8 r1, g1, b1, r2, g2, b2; Uint8 r1, g1, b1, r2, g2, b2;
if (c1 == c2) if (c1 == c2)
{ {
/* Get it over with quick, if possible! */ /* Get it over with quick, if possible! */
return 1; return 1;
} }
else else
{ {
double r, g, b; double r, g, b;
SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
// use distance in linear RGB space SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
r = api->sRGB_to_linear(r1) - api->sRGB_to_linear(r2); SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
r *= r;
g = api->sRGB_to_linear(g1) - api->sRGB_to_linear(g2);
g *= g;
b = api->sRGB_to_linear(b1) - api->sRGB_to_linear(b2);
b *= b;
// easy to confuse: // use distance in linear RGB space
// dark grey, brown, purple r = api->sRGB_to_linear(r1) - api->sRGB_to_linear(r2);
// light grey, tan r *= r;
// red, orange g = api->sRGB_to_linear(g1) - api->sRGB_to_linear(g2);
return r + g + b < 0.04; g *= g;
} b = api->sRGB_to_linear(b1) - api->sRGB_to_linear(b2);
b *= b;
// easy to confuse:
// dark grey, brown, purple
// light grey, tan
// red, orange
return r + g + b < 0.04;
}
} }
static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y, static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr)
Uint32 cur_colr, Uint32 old_colr)
{ {
int fillL, fillR, i, in_line; int fillL, fillR, i, in_line;
static unsigned char prog_anim; static unsigned char prog_anim;
@ -214,10 +206,10 @@ static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y,
prog_anim++; prog_anim++;
if ((prog_anim % 4) == 0) if ((prog_anim % 4) == 0)
{ {
api->update_progress_bar(); api->update_progress_bar();
api->playsound(fill_snd, (x * 255) / canvas->w, 255); api->playsound(fill_snd, (x * 255) / canvas->w, 255);
} }
/* Find left side, filling along the way */ /* Find left side, filling along the way */
@ -225,15 +217,12 @@ static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y,
in_line = 1; in_line = 1;
while (in_line) while (in_line)
{ {
api->putpixel(canvas, fillL, y, cur_colr); api->putpixel(canvas, fillL, y, cur_colr);
fillL--; fillL--;
in_line = in_line = (fillL < 0) ? 0 : colors_close(api, canvas, api->getpixel(canvas, fillL, y), old_colr);
(fillL < 0) ? 0 : colors_close(api, canvas, }
api->getpixel(canvas, fillL, y),
old_colr);
}
fillL++; fillL++;
@ -241,14 +230,12 @@ static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y,
in_line = 1; in_line = 1;
while (in_line) while (in_line)
{ {
api->putpixel(canvas, fillR, y, cur_colr); api->putpixel(canvas, fillR, y, cur_colr);
fillR++; fillR++;
in_line = (fillR >= canvas->w) ? 0 : colors_close(api, canvas, in_line = (fillR >= canvas->w) ? 0 : colors_close(api, canvas, api->getpixel(canvas, fillR, y), old_colr);
api->getpixel(canvas, fillR, y), }
old_colr);
}
fillR--; fillR--;
@ -256,26 +243,26 @@ static void do_flood_fill(magic_api * api, SDL_Surface * canvas, int x, int y,
/* Search top and bottom */ /* Search top and bottom */
for (i = fillL; i <= fillR; i++) for (i = fillL; i <= fillR; i++)
{ {
if (y > 0 && colors_close(api, canvas, api->getpixel(canvas, i, y - 1), if (y > 0 && colors_close(api, canvas, api->getpixel(canvas, i, y - 1), old_colr))
old_colr)) do_flood_fill(api, canvas, i, y - 1, cur_colr, old_colr);
do_flood_fill(api, canvas, i, y - 1, cur_colr, old_colr);
if (y < canvas->h if (y < canvas->h && colors_close(api, canvas, api->getpixel(canvas, i, y + 1), old_colr))
&& colors_close(api, canvas, api->getpixel(canvas, i, y + 1), old_colr)) do_flood_fill(api, canvas, i, y + 1, cur_colr, old_colr);
do_flood_fill(api, canvas, i, y + 1, cur_colr, old_colr); }
}
} }
void fill_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fill_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void fill_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fill_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int fill_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int fill_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -31,7 +31,7 @@
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
Mix_Chunk * fisheye_snd; Mix_Chunk *fisheye_snd;
int last_x, last_y; int last_x, last_y;
/* Local function prototypes */ /* Local function prototypes */
@ -39,39 +39,35 @@ Uint32 fisheye_api_version(void);
void fisheye_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void fisheye_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int fisheye_init(magic_api * api); int fisheye_init(magic_api * api);
int fisheye_get_tool_count(magic_api * api); int fisheye_get_tool_count(magic_api * api);
SDL_Surface * fisheye_get_icon(magic_api * api, int which); SDL_Surface *fisheye_get_icon(magic_api * api, int which);
char * fisheye_get_name(magic_api * api, int which); char *fisheye_get_name(magic_api * api, int which);
char * fisheye_get_description(magic_api * api, int which, int mode); char *fisheye_get_description(magic_api * api, int which, int mode);
int fisheye_requires_colors(magic_api * api, int which); int fisheye_requires_colors(magic_api * api, int which);
void fisheye_release(magic_api * api, int which, void fisheye_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fisheye_shutdown(magic_api * api); void fisheye_shutdown(magic_api * api);
void fisheye_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, void fisheye_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas, void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void fisheye_click(magic_api * api, int which, int mode, void fisheye_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fisheye_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void fisheye_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void fisheye_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void fisheye_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int fisheye_modes(magic_api * api, int which); int fisheye_modes(magic_api * api, int which);
// Housekeeping functions // Housekeeping functions
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas, void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
Uint32 fisheye_api_version(void) Uint32 fisheye_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void fisheye_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void fisheye_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -79,11 +75,11 @@ void fisheye_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSE
int fisheye_init(magic_api * api) int fisheye_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/fisheye.ogg", api->data_directory);
fisheye_snd = Mix_LoadWAV(fname);
return(1); snprintf(fname, sizeof(fname), "%s/sounds/magic/fisheye.ogg", api->data_directory);
fisheye_snd = Mix_LoadWAV(fname);
return (1);
} }
int fisheye_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int fisheye_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -91,186 +87,203 @@ int fisheye_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * fisheye_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *fisheye_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/fisheye.png", snprintf(fname, sizeof(fname), "%s/images/magic/fisheye.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * fisheye_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Fisheye")); } //Needs better name char *fisheye_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Fisheye"));
} //Needs better name
char * fisheye_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Click on part of your picture to create a fisheye effect.")); } char *fisheye_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click on part of your picture to create a fisheye effect."));
}
int fisheye_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 0; } int fisheye_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 0;
}
void fisheye_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void fisheye_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void fisheye_shutdown(magic_api * api ATTRIBUTE_UNUSED) void fisheye_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ Mix_FreeChunk(fisheye_snd); } {
Mix_FreeChunk(fisheye_snd);
}
// do-fisheye // do-fisheye
void fisheye_draw(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, void fisheye_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y) int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
SDL_Surface * oryg, *temp_src, *temp_dest, *output;
SDL_Rect rect, temp_rect;
int xx, yy;
unsigned short int i;
if(api->in_circle(last_x - x, last_y - y, 80)) return; SDL_Surface *oryg, *temp_src, *temp_dest, *output;
SDL_Rect rect, temp_rect;
int xx, yy;
unsigned short int i;
last_x = x; if (api->in_circle(last_x - x, last_y - y, 80))
last_y = y; return;
oryg=SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel, last_x = x;
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); last_y = y;
output=SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel, oryg = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
rect.x=x-40;
rect.y=y-40;
rect.w=rect.h=80;
SDL_BlitSurface(canvas, &rect, oryg, NULL); //here we have a piece of source image. Now we've to scale it (keeping aspect ratio)
//do vertical fisheye
for (i=0; i<40; i++)
{
temp_src=SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
//let's take a smooth bar of scaled bitmap and copy it to temp
//left side first
rect.x=i;
rect.y=0;
rect.w=1;
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src
temp_dest=SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80+2*i, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
temp_dest=api->scale(temp_src, 1, 80+2*i, 0); //temp_dest stores scaled temp_src
temp_rect.x=0;
temp_rect.y=i;
temp_rect.w=1;
temp_rect.h=80;
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output output = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
//right side then canvas->format->Amask);
rect.x=79-i;
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src //OK
temp_dest=api->scale(temp_src, 1, 80+2*i, 0); //temp_dest stores scaled temp_src
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output rect.x = x - 40;
} rect.y = y - 40;
rect.w = rect.h = 80;
//do horizontal fisheye
for (i=0; i<40; i++)
{
temp_src=SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
temp_dest=SDL_CreateRGBSurface(SDL_SWSURFACE, 80+2*i, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
//upper side first
rect.x=0;
rect.y=i;
rect.w=80;
rect.h=1;
temp_rect.x=i;
temp_rect.y=0;
temp_rect.w=80;
temp_rect.h=1;
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest=api->scale(temp_src, 80+2*i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
//lower side then
rect.y=79-i; SDL_BlitSurface(canvas, &rect, oryg, NULL); //here we have a piece of source image. Now we've to scale it (keeping aspect ratio)
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest=api->scale(temp_src, 80+2*i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
}
rect.x=x-40; //do vertical fisheye
rect.y=y-40; for (i = 0; i < 40; i++)
rect.w=rect.h=80; {
temp_src = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
//let's blit an area surrounded by a circle //let's take a smooth bar of scaled bitmap and copy it to temp
//left side first
rect.x = i;
rect.y = 0;
rect.w = 1;
for (yy = y-40; yy < y+40; yy++) SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src
for (xx = x-40; xx < x+40; xx++)
if (api->in_circle(xx-x, yy-y, 40)) temp_dest = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 80 + 2 * i, canvas->format->BitsPerPixel,
api->putpixel(canvas, xx, yy, api->getpixel(output, xx+40-x, yy+40-y)); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
temp_rect.x = 0;
temp_rect.y = i;
temp_rect.w = 1;
temp_rect.h = 80;
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
//right side then
rect.x = 79 - i;
SDL_BlitSurface(oryg, &rect, temp_src, NULL); //this bar is copied to temp_src //OK
temp_dest = api->scale(temp_src, 1, 80 + 2 * i, 0); //temp_dest stores scaled temp_src
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect); //let's copy it to output
}
//do horizontal fisheye
for (i = 0; i < 40; i++)
{
temp_src = SDL_CreateRGBSurface(SDL_SWSURFACE, 80, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
temp_dest = SDL_CreateRGBSurface(SDL_SWSURFACE, 80 + 2 * i, 1, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
//upper side first
rect.x = 0;
rect.y = i;
rect.w = 80;
rect.h = 1;
temp_rect.x = i;
temp_rect.y = 0;
temp_rect.w = 80;
temp_rect.h = 1;
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
//lower side then
rect.y = 79 - i;
SDL_BlitSurface(output, &rect, temp_src, NULL);
temp_dest = api->scale(temp_src, 80 + 2 * i, 1, 0);
SDL_BlitSurface(temp_dest, &temp_rect, output, &rect);
}
rect.x = x - 40;
rect.y = y - 40;
rect.w = rect.h = 80;
//let's blit an area surrounded by a circle
for (yy = y - 40; yy < y + 40; yy++)
for (xx = x - 40; xx < x + 40; xx++)
if (api->in_circle(xx - x, yy - y, 40))
api->putpixel(canvas, xx, yy, api->getpixel(output, xx + 40 - x, yy + 40 - y));
SDL_FreeSurface(oryg); SDL_FreeSurface(oryg);
SDL_FreeSurface(output); SDL_FreeSurface(output);
SDL_FreeSurface(temp_dest); SDL_FreeSurface(temp_dest);
SDL_FreeSurface(temp_src); SDL_FreeSurface(temp_src);
api->playsound(fisheye_snd, (x * 255) / canvas->w,255); api->playsound(fisheye_snd, (x * 255) / canvas->w, 255);
} }
void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas, void fisheye_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, fisheye_draw); api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, fisheye_draw);
update_rect->x = min(ox, x) - 40; update_rect->x = min(ox, x) - 40;
update_rect->y = min(oy, y) - 40; update_rect->y = min(oy, y) - 40;
update_rect->w = max(ox, x) - update_rect->x + 40; update_rect->w = max(ox, x) - update_rect->x + 40;
update_rect->h = max(oy, y) - update_rect->y + 40; update_rect->h = max(oy, y) - update_rect->y + 40;
} }
void fisheye_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void fisheye_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
last_x = -80; /* A value that will be beyond any clicked position */ last_x = -80; /* A value that will be beyond any clicked position */
last_y = -80; last_y = -80;
fisheye_drag(api, which, canvas, last, x, y, x, y, update_rect); fisheye_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void fisheye_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fisheye_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
{ SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
} }
void fisheye_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fisheye_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int fisheye_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int fisheye_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -36,19 +36,21 @@
/* Our globals: */ /* Our globals: */
enum { SIDE_LEFT, SIDE_RIGHT }; enum
enum { LEAFSIDE_RIGHT_DOWN, { SIDE_LEFT, SIDE_RIGHT };
LEAFSIDE_LEFT_DOWN, enum
LEAFSIDE_RIGHT_UP, { LEAFSIDE_RIGHT_DOWN,
LEAFSIDE_LEFT_UP }; LEAFSIDE_LEFT_DOWN,
LEAFSIDE_RIGHT_UP,
LEAFSIDE_LEFT_UP
};
static Mix_Chunk * flower_click_snd, * flower_release_snd; static Mix_Chunk *flower_click_snd, *flower_release_snd;
static Uint8 flower_r, flower_g, flower_b; static Uint8 flower_r, flower_g, flower_b;
static int flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y; static int flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y;
static int flower_side_first; static int flower_side_first;
static int flower_side_decided; static int flower_side_decided;
static SDL_Surface * flower_base, * flower_leaf, * flower_petals, static SDL_Surface *flower_base, *flower_leaf, *flower_petals, *flower_petals_colorized;
* flower_petals_colorized;
/* Local function prototypes: */ /* Local function prototypes: */
@ -59,36 +61,31 @@ typedef struct
static void flower_drawbase(magic_api * api, SDL_Surface * canvas); static void flower_drawbase(magic_api * api, SDL_Surface * canvas);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y); static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
static Point2D flower_PointOnCubicBezier(Point2D* cp, float t); static Point2D flower_PointOnCubicBezier(Point2D * cp, float t);
static void flower_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve); static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void flower_colorize_petals(magic_api * api); static void flower_colorize_petals(magic_api * api);
Uint32 flower_api_version(void); Uint32 flower_api_version(void);
int flower_init(magic_api * api); int flower_init(magic_api * api);
int flower_get_tool_count(magic_api * api); int flower_get_tool_count(magic_api * api);
SDL_Surface * flower_get_icon(magic_api * api, int which); SDL_Surface *flower_get_icon(magic_api * api, int which);
char * flower_get_name(magic_api * api, int which); char *flower_get_name(magic_api * api, int which);
char * flower_get_description(magic_api * api, int which, int mode); char *flower_get_description(magic_api * api, int which, int mode);
static void flower_predrag(magic_api * api, SDL_Surface * canvas, static void flower_predrag(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y);
SDL_Surface * last, int ox, int oy, int x, int y);
void flower_drag(magic_api * api, int which, SDL_Surface * canvas, void flower_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void flower_click(magic_api * api, int which, int mode, void flower_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void flower_release(magic_api * api, int which, void flower_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y); static void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
static void flower_drawbase(magic_api * api, SDL_Surface * canvas); static void flower_drawbase(magic_api * api, SDL_Surface * canvas);
static void flower_drawstalk(magic_api * api, SDL_Surface * canvas, static void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int top_x, int top_y, int minx, int maxx, int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final);
int bottom_x, int bottom_y, int final);
void flower_shutdown(magic_api * api); void flower_shutdown(magic_api * api);
void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int flower_requires_colors(magic_api * api, int which); int flower_requires_colors(magic_api * api, int which);
static Point2D flower_PointOnCubicBezier( Point2D* cp, float t ); static Point2D flower_PointOnCubicBezier(Point2D * cp, float t);
static void flower_ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve ); static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void flower_colorize_petals(magic_api * api); static void flower_colorize_petals(magic_api * api);
void flower_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void flower_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void flower_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void flower_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
@ -96,7 +93,10 @@ int flower_modes(magic_api * api, int which);
Uint32 flower_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 flower_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -104,61 +104,55 @@ int flower_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/flower_click.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/flower_click.ogg", api->data_directory);
api->data_directory);
flower_click_snd = Mix_LoadWAV(fname); flower_click_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/flower_release.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/flower_release.ogg", api->data_directory);
api->data_directory);
flower_release_snd = Mix_LoadWAV(fname); flower_release_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_base.png", snprintf(fname, sizeof(fname), "%s/images/magic/flower_base.png", api->data_directory);
api->data_directory);
flower_base = IMG_Load(fname); flower_base = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_leaf.png", snprintf(fname, sizeof(fname), "%s/images/magic/flower_leaf.png", api->data_directory);
api->data_directory);
flower_leaf = IMG_Load(fname); flower_leaf = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_petals.png", snprintf(fname, sizeof(fname), "%s/images/magic/flower_petals.png", api->data_directory);
api->data_directory);
flower_petals = IMG_Load(fname); flower_petals = IMG_Load(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int flower_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int flower_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * flower_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *flower_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/flower.png", snprintf(fname, sizeof(fname), "%s/images/magic/flower.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * flower_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *flower_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Flower"))); return (strdup(gettext_noop("Flower")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * flower_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *flower_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag to draw a flower stalk. Let go to finish the flower."))); return (strdup(gettext_noop("Click and drag to draw a flower stalk. Let go to finish the flower.")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y)
{ {
if (x < flower_min_x) if (x < flower_min_x)
flower_min_x = x; flower_min_x = x;
@ -177,23 +171,22 @@ static void flower_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canva
// Determine which way to bend first: // Determine which way to bend first:
// //
if (flower_side_decided == 0) if (flower_side_decided == 0)
{
if (x < flower_bottom_x - 10)
{ {
flower_side_first = SIDE_LEFT; if (x < flower_bottom_x - 10)
flower_side_decided = 1; {
flower_side_first = SIDE_LEFT;
flower_side_decided = 1;
}
else if (x > flower_bottom_x + 10)
{
flower_side_first = SIDE_RIGHT;
flower_side_decided = 1;
}
} }
else if (x > flower_bottom_x + 10)
{
flower_side_first = SIDE_RIGHT;
flower_side_decided = 1;
}
}
} }
void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
flower_predrag(api, canvas, last, ox, oy, x, y); flower_predrag(api, canvas, last, ox, oy, x, y);
@ -206,21 +199,19 @@ void flower_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canv
/* Draw the base and the stalk (low-quality) for now: */ /* Draw the base and the stalk (low-quality) for now: */
flower_drawstalk(api, canvas, flower_drawstalk(api, canvas,
x, y, flower_min_x, flower_max_x, x, y, flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y, !(api->button_down()));
flower_bottom_x, flower_bottom_y, !(api->button_down()));
flower_drawbase(api, canvas); flower_drawbase(api, canvas);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
} }
// Affect the canvas on click: // Affect the canvas on click:
void flower_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void flower_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
flower_min_x = x; flower_min_x = x;
flower_max_x = x; flower_max_x = x;
@ -231,14 +222,13 @@ void flower_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
flower_side_first = SIDE_LEFT; flower_side_first = SIDE_LEFT;
flower_drag(api, which, canvas, last, x, y, x, y, update_rect); flower_drag(api, which, canvas, last, x, y, x, y, update_rect);
api->playsound(flower_click_snd, (x * 255) / canvas->w, 255); api->playsound(flower_click_snd, (x * 255) / canvas->w, 255);
} }
// Affect the canvas on release: // Affect the canvas on release:
void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED, void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
/* Don't let flower be too low compared to base: */ /* Don't let flower be too low compared to base: */
@ -250,7 +240,7 @@ void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
flower_predrag(api, canvas, last, x, y, x, y); flower_predrag(api, canvas, last, x, y, x, y);
/* Erase any old stuff: */ /* Erase any old stuff: */
SDL_BlitSurface(last, NULL, canvas, NULL); SDL_BlitSurface(last, NULL, canvas, NULL);
@ -258,15 +248,13 @@ void flower_release(magic_api * api, int which ATTRIBUTE_UNUSED,
/* Draw high-quality stalk, and flower: */ /* Draw high-quality stalk, and flower: */
flower_drawstalk(api, canvas, flower_drawstalk(api, canvas, x, y, flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y, 1);
x, y, flower_min_x, flower_max_x,
flower_bottom_x, flower_bottom_y, 1);
flower_drawflower(api, canvas, x, y); flower_drawflower(api, canvas, x, y);
flower_drawbase(api, canvas); flower_drawbase(api, canvas);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -297,11 +285,10 @@ static void flower_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canv
} }
static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas, static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int top_x, int top_y, int minx, int maxx, int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final)
int bottom_x, int bottom_y, int final)
{ {
Point2D control_points[4]; Point2D control_points[4];
Point2D * curve; Point2D *curve;
int i, n_points; int i, n_points;
int left, right; int left, right;
SDL_Rect dest, src; SDL_Rect dest, src;
@ -315,22 +302,22 @@ static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
control_points[0].y = top_y; control_points[0].y = top_y;
if (flower_side_first == SIDE_LEFT) if (flower_side_first == SIDE_LEFT)
{ {
control_points[1].x = minx; control_points[1].x = minx;
control_points[2].x = maxx; control_points[2].x = maxx;
} }
else else
{ {
control_points[1].x = maxx; control_points[1].x = maxx;
control_points[2].x = minx; control_points[2].x = minx;
} }
control_points[1].y = ((bottom_y - top_y) / 3) + top_y; control_points[1].y = ((bottom_y - top_y) / 3) + top_y;
control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y; control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y;
control_points[3].x = bottom_x; control_points[3].x = bottom_x;
control_points[3].y = bottom_y; control_points[3].y = bottom_y;
if (final == 0) if (final == 0)
n_points = 8; n_points = 8;
else else
@ -342,129 +329,128 @@ static void flower_drawstalk(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
/* Draw the curve: */ /* Draw the curve: */
for (i = 0; i < n_points - 1; i++) for (i = 0; i < n_points - 1; i++)
{
if (final == 0)
{ {
dest.x = curve[i].x; if (final == 0)
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
}
else
{
left = min(curve[i].x, curve[i + 1].x);
right = max(curve[i].x, curve[i + 1].x);
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
/* When we're done (final render), we can add some random leaves: */
if (final && i > 32 && i < n_points - 32 && (i % 16) == 0 &&
(rand() % 5) > 0)
{
/* Check for hard left/right angles: */
side = -1;
if (curve[i - 2].x - curve[i + 2].x > 5)
{
/* Hard lower-left-to-upper-right (/),
stick either a left-upward or right-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_UP;
else
side = LEAFSIDE_RIGHT_DOWN;
}
else if (curve[i - 2].x - curve[i + 2].x < -5)
{
/* Hard lower-right-to-upper-left (\)
stick either a right-upward or left-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_UP;
}
else if (abs(curve[i - 2].x - curve[i + 2].x) < 5)
{
/* Mostly up; stick left- or right-downward: */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_DOWN;
}
/* Draw the appropriately-oriented leaf, if any: */
if (side == LEAFSIDE_RIGHT_DOWN)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, NULL, canvas, &dest);
}
else if (side == LEAFSIDE_LEFT_DOWN)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{ {
src.x = xx;
src.y = 0;
src.w = 1;
src.h = flower_leaf->h;
dest.x = curve[i].x - xx;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_RIGHT_UP)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = flower_leaf->w;
src.h = 1;
dest.x = curve[i].x; dest.x = curve[i].x;
dest.y = curve[i].y - yy; dest.y = curve[i].y;
dest.w = 2;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest); dest.h = 2;
} }
} else
else if (side == LEAFSIDE_LEFT_UP)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{ {
for (yy = 0; yy < flower_leaf->h; yy++) left = min(curve[i].x, curve[i + 1].x);
{ right = max(curve[i].x, curve[i + 1].x);
src.x = xx;
src.y = yy;
src.w = 1;
src.h = 1;
dest.x = curve[i].x - xx; dest.x = left;
dest.y = curve[i].y - yy; dest.y = curve[i].y;
dest.w = right - left + 1;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest); dest.h = 2;
} }
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
/* When we're done (final render), we can add some random leaves: */
if (final && i > 32 && i < n_points - 32 && (i % 16) == 0 && (rand() % 5) > 0)
{
/* Check for hard left/right angles: */
side = -1;
if (curve[i - 2].x - curve[i + 2].x > 5)
{
/* Hard lower-left-to-upper-right (/),
stick either a left-upward or right-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_UP;
else
side = LEAFSIDE_RIGHT_DOWN;
}
else if (curve[i - 2].x - curve[i + 2].x < -5)
{
/* Hard lower-right-to-upper-left (\)
stick either a right-upward or left-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_UP;
}
else if (abs(curve[i - 2].x - curve[i + 2].x) < 5)
{
/* Mostly up; stick left- or right-downward: */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_DOWN;
}
/* Draw the appropriately-oriented leaf, if any: */
if (side == LEAFSIDE_RIGHT_DOWN)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, NULL, canvas, &dest);
}
else if (side == LEAFSIDE_LEFT_DOWN)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
src.x = xx;
src.y = 0;
src.w = 1;
src.h = flower_leaf->h;
dest.x = curve[i].x - xx;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_RIGHT_UP)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = flower_leaf->w;
src.h = 1;
dest.x = curve[i].x;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_LEFT_UP)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = xx;
src.y = yy;
src.w = 1;
src.h = 1;
dest.x = curve[i].x - xx;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
}
} }
}
} }
}
free(curve); free(curve);
} }
@ -518,32 +504,32 @@ cp[3] is the end point, or P3 in the above diagram
t is the parameter value, 0 <= t <= 1 t is the parameter value, 0 <= t <= 1
*/ */
static Point2D flower_PointOnCubicBezier( Point2D* cp, float t ) static Point2D flower_PointOnCubicBezier(Point2D * cp, float t)
{ {
float ax, bx, cx; float ax, bx, cx;
float ay, by, cy; float ay, by, cy;
float tSquared, tCubed; float tSquared, tCubed;
Point2D result; Point2D result;
/* calculate the polynomial coefficients */ /* calculate the polynomial coefficients */
cx = 3.0 * (cp[1].x - cp[0].x); cx = 3.0 * (cp[1].x - cp[0].x);
bx = 3.0 * (cp[2].x - cp[1].x) - cx; bx = 3.0 * (cp[2].x - cp[1].x) - cx;
ax = cp[3].x - cp[0].x - cx - bx; ax = cp[3].x - cp[0].x - cx - bx;
cy = 3.0 * (cp[1].y - cp[0].y); cy = 3.0 * (cp[1].y - cp[0].y);
by = 3.0 * (cp[2].y - cp[1].y) - cy; by = 3.0 * (cp[2].y - cp[1].y) - cy;
ay = cp[3].y - cp[0].y - cy - by; ay = cp[3].y - cp[0].y - cy - by;
/* calculate the curve point at parameter value t */ /* calculate the curve point at parameter value t */
tSquared = t * t; tSquared = t * t;
tCubed = tSquared * t; tCubed = tSquared * t;
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x; result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y; result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
return result; return result;
} }
/* /*
@ -553,15 +539,15 @@ static Point2D flower_PointOnCubicBezier( Point2D* cp, float t )
<sizeof(Point2D) numberOfPoints> <sizeof(Point2D) numberOfPoints>
*/ */
static void flower_ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve ) static void flower_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
{ {
float dt; float dt;
int i; int i;
dt = 1.0 / ( numberOfPoints - 1 ); dt = 1.0 / (numberOfPoints - 1);
for( i = 0; i < numberOfPoints; i++) for (i = 0; i < numberOfPoints; i++)
curve[i] = flower_PointOnCubicBezier( cp, i*dt ); curve[i] = flower_PointOnCubicBezier(cp, i * dt);
} }
@ -576,9 +562,7 @@ static void flower_colorize_petals(magic_api * api)
/* Create a surface to render into: */ /* Create a surface to render into: */
amask = ~(flower_petals->format->Rmask | amask = ~(flower_petals->format->Rmask | flower_petals->format->Gmask | flower_petals->format->Bmask);
flower_petals->format->Gmask |
flower_petals->format->Bmask);
flower_petals_colorized = flower_petals_colorized =
SDL_CreateRGBSurface(SDL_SWSURFACE, SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -586,8 +570,7 @@ static void flower_colorize_petals(magic_api * api)
flower_petals->h, flower_petals->h,
flower_petals->format->BitsPerPixel, flower_petals->format->BitsPerPixel,
flower_petals->format->Rmask, flower_petals->format->Rmask,
flower_petals->format->Gmask, flower_petals->format->Gmask, flower_petals->format->Bmask, amask);
flower_petals->format->Bmask, amask);
/* Render the new petals: */ /* Render the new petals: */
@ -595,40 +578,37 @@ static void flower_colorize_petals(magic_api * api)
SDL_LockSurface(flower_petals_colorized); SDL_LockSurface(flower_petals_colorized);
for (y = 0; y < flower_petals->h; y++) for (y = 0; y < flower_petals->h; y++)
{
for (x = 0; x < flower_petals->w; x++)
{ {
SDL_GetRGBA(api->getpixel(flower_petals, x, y), for (x = 0; x < flower_petals->w; x++)
flower_petals->format, &r, &g, &b, &a); {
SDL_GetRGBA(api->getpixel(flower_petals, x, y), flower_petals->format, &r, &g, &b, &a);
api->putpixel(flower_petals_colorized, x, y, api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format, SDL_MapRGBA(flower_petals_colorized->format, flower_r, flower_g, flower_b, a));
flower_r, flower_g, flower_b, a));
if (api->in_circle((x - flower_petals->w / 2), if (api->in_circle((x - flower_petals->w / 2), (y - flower_petals->h / 2), 8))
(y - flower_petals->h / 2), {
8)) api->putpixel(flower_petals_colorized, x, y,
{ SDL_MapRGBA(flower_petals_colorized->format, 0xFF, 0xFF, 0x00, a));
api->putpixel(flower_petals_colorized, x, y, }
SDL_MapRGBA(flower_petals_colorized->format, }
0xFF, 0xFF, 0x00, a));
}
} }
}
SDL_UnlockSurface(flower_petals_colorized); SDL_UnlockSurface(flower_petals_colorized);
SDL_UnlockSurface(flower_petals); SDL_UnlockSurface(flower_petals);
} }
void flower_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void flower_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void flower_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void flower_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int flower_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int flower_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }

View file

@ -36,26 +36,23 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * foam_snd; static Mix_Chunk *foam_snd;
static Uint8 foam_r, foam_g, foam_b; static Uint8 foam_r, foam_g, foam_b;
static int foam_mask_w, foam_mask_h; static int foam_mask_w, foam_mask_h;
static int * foam_mask, * foam_mask_tmp; static int *foam_mask, *foam_mask_tmp;
static SDL_Surface * foam_7, * foam_5, * foam_3, * foam_1; static SDL_Surface *foam_7, *foam_5, *foam_3, *foam_1;
Uint32 foam_api_version(void); Uint32 foam_api_version(void);
int foam_init(magic_api * api); int foam_init(magic_api * api);
char * foam_get_description(magic_api * api, int which, int mode); char *foam_get_description(magic_api * api, int which, int mode);
void foam_release(magic_api * api, int which, void foam_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void foam_drag(magic_api * api, int which, SDL_Surface * canvas, void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void foam_click(magic_api * api, int which, int mode, void foam_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect); SDL_Surface *foam_get_icon(magic_api * api, int which);
SDL_Surface * foam_get_icon(magic_api * api, int which); char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED);
char * foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED);
void foam_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void foam_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void foam_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void foam_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
void foam_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void foam_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -67,107 +64,113 @@ int foam_requires_colors(magic_api * api, int which);
#define FOAM_PROP 8 #define FOAM_PROP 8
#define FOAM_RADIUS 3 #define FOAM_RADIUS 3
Uint32 foam_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 foam_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
int foam_init(magic_api * api) int foam_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
SDL_Surface * foam_data; SDL_Surface *foam_data;
snprintf(fname, sizeof(fname), "%s/sounds/magic/foam.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/foam.ogg", api->data_directory);
api->data_directory);
foam_snd = Mix_LoadWAV(fname); foam_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/foam_data.png", snprintf(fname, sizeof(fname), "%s/images/magic/foam_data.png", api->data_directory);
api->data_directory);
foam_data = IMG_Load(fname); foam_data = IMG_Load(fname);
foam_7 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 4) / 4, foam_7 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 4) / 4, ((api->canvas_h / FOAM_PROP) * 4) / 4, 0);
((api->canvas_h / FOAM_PROP) * 4) / 4, 0); foam_5 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 3) / 4, ((api->canvas_h / FOAM_PROP) * 3) / 4, 0);
foam_5 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 3) / 4, foam_3 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 2) / 4, ((api->canvas_h / FOAM_PROP) * 2) / 4, 0);
((api->canvas_h / FOAM_PROP) * 3) / 4, 0); foam_1 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 1) / 4, ((api->canvas_h / FOAM_PROP) * 1) / 4, 0);
foam_3 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 2) / 4,
((api->canvas_h / FOAM_PROP) * 2) / 4, 0);
foam_1 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 1) / 4,
((api->canvas_h / FOAM_PROP) * 1) / 4, 0);
SDL_FreeSurface(foam_data); SDL_FreeSurface(foam_data);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int foam_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int foam_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * foam_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *foam_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/foam.png", snprintf(fname, sizeof(fname), "%s/images/magic/foam.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *foam_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Foam"))); return (strdup(gettext_noop("Foam")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * foam_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *foam_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag the mouse to cover an area with foamy bubbles."))); return (strdup(gettext_noop("Click and drag the mouse to cover an area with foamy bubbles.")));
} }
// Do the effect: // Do the effect:
static void do_foam(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, static void do_foam(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy, nx, ny; int xx, yy, nx, ny;
/* SDL_Rect dest; */ /* SDL_Rect dest; */
for (yy = -FOAM_RADIUS; yy < FOAM_RADIUS; yy++) for (yy = -FOAM_RADIUS; yy < FOAM_RADIUS; yy++)
{
for (xx = -FOAM_RADIUS; xx < FOAM_RADIUS; xx++)
{ {
if (api->in_circle(xx, yy, FOAM_RADIUS)) for (xx = -FOAM_RADIUS; xx < FOAM_RADIUS; xx++)
{
nx = (x / FOAM_PROP) + xx;
ny = (y / FOAM_PROP) + yy;
if (nx >= 0 && ny >= 0 &&
nx < foam_mask_w &&
ny < foam_mask_h)
{ {
foam_mask[ny * foam_mask_w + nx] = 1; if (api->in_circle(xx, yy, FOAM_RADIUS))
{
nx = (x / FOAM_PROP) + xx;
ny = (y / FOAM_PROP) + yy;
if (nx >= 0 && ny >= 0 && nx < foam_mask_w && ny < foam_mask_h)
{
foam_mask[ny * foam_mask_w + nx] = 1;
}
}
} }
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void foam_drag(magic_api * api, int which, SDL_Surface * canvas, void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_foam); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_foam);
foam_release(api, which, canvas, last, x, y, update_rect); foam_release(api, which, canvas, last, x, y, update_rect);
/* FIXME */ /* FIXME */
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
@ -179,19 +182,19 @@ void foam_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void foam_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, void foam_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
{ {
int i; int i;
if (foam_mask == NULL) if (foam_mask == NULL)
{ {
foam_mask_w = canvas->w / FOAM_PROP; foam_mask_w = canvas->w / FOAM_PROP;
foam_mask_h = canvas->h / FOAM_PROP; foam_mask_h = canvas->h / FOAM_PROP;
foam_mask = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h)); foam_mask = (int *)malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
foam_mask_tmp = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h)); foam_mask_tmp = (int *)malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
} }
for (i = 0; i < foam_mask_w * foam_mask_h; i++) for (i = 0; i < foam_mask_w * foam_mask_h; i++)
foam_mask[i] = 0; foam_mask[i] = 0;
@ -207,30 +210,30 @@ static int foam_mask_test(int r, int x, int y)
tot = 0; tot = 0;
for (yy = 0; yy < r; yy++) for (yy = 0; yy < r; yy++)
{
for (xx = 0; xx < r; xx++)
{ {
if (x + xx < foam_mask_w && y + yy < foam_mask_h) for (xx = 0; xx < r; xx++)
{ {
bub_r = foam_mask[((y + yy) * foam_mask_w) + (x + xx)]; if (x + xx < foam_mask_w && y + yy < foam_mask_h)
tot = tot + bub_r; {
} bub_r = foam_mask[((y + yy) * foam_mask_w) + (x + xx)];
tot = tot + bub_r;
}
}
} }
}
return(tot); return (tot);
} }
// Affect the canvas on release: // Affect the canvas on release:
void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
{ {
int xx, yy; int xx, yy;
int changes, max_iters; int changes, max_iters;
SDL_Rect dest; SDL_Rect dest;
int n; int n;
SDL_Surface * img; SDL_Surface *img;
SDL_BlitSurface(last, NULL, canvas, NULL); SDL_BlitSurface(last, NULL, canvas, NULL);
@ -240,161 +243,161 @@ void foam_release(magic_api * api ATTRIBUTE_UNUSED ATTRIBUTE_UNUSED, int which A
max_iters = 2; max_iters = 2;
do do
{
changes = 0;
max_iters--;
for (yy = 0; yy < foam_mask_h - 7; yy++)
{ {
for (xx = 0; xx < foam_mask_w - 7; xx++) changes = 0;
{ max_iters--;
if (foam_mask_test(7, xx, yy) >= 40)
for (yy = 0; yy < foam_mask_h - 7; yy++)
{ {
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 7; for (xx = 0; xx < foam_mask_w - 7; xx++)
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0; {
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1; if (foam_mask_test(7, xx, yy) >= 40)
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 0; {
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 1; foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 7;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 5)] = 2; foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 6)] = 0; foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0; foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 1; foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0; foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0; foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 0; foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 5)] = 2; foam_mask[((yy + 1) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 6)] = 0; foam_mask[((yy + 1) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1; foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0; foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 0; foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0; foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0; foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 5)] = 0; foam_mask[((yy + 2) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 6)] = 1; foam_mask[((yy + 2) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 1; foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 5)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 6)] = 0; foam_mask[((yy + 3) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 1; foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 0; foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0; foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 0; foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0; foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 5)] = 0; foam_mask[((yy + 4) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 6)] = 1; foam_mask[((yy + 4) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 0)] = 2; foam_mask[((yy + 5) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 1)] = 0; foam_mask[((yy + 5) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 2)] = 0; foam_mask[((yy + 5) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 3)] = 7; foam_mask[((yy + 5) * foam_mask_w) + (xx + 3)] = 7;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 4)] = 0; foam_mask[((yy + 5) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 5)] = 3; foam_mask[((yy + 5) * foam_mask_w) + (xx + 5)] = 3;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 6)] = 0; foam_mask[((yy + 5) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 0)] = 0; foam_mask[((yy + 6) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 1)] = 0; foam_mask[((yy + 6) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 2)] = 1; foam_mask[((yy + 6) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 3)] = 0; foam_mask[((yy + 6) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 4)] = 1; foam_mask[((yy + 6) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 5)] = 0; foam_mask[((yy + 6) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 6)] = 2; foam_mask[((yy + 6) * foam_mask_w) + (xx + 6)] = 2;
changes = 1; changes = 1;
}
else if (foam_mask_test(5, xx, yy) >= 30)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 5;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
changes = 1;
}
else if (foam_mask_test(3, xx, yy) >= 8)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 3;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 1;
changes = 1;
}
}
} }
else if (foam_mask_test(5, xx, yy) >= 30)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 5;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
changes = 1;
}
else if (foam_mask_test(3, xx, yy) >= 8)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 3;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 1;
changes = 1;
}
}
} }
}
while (changes && max_iters > 0); while (changes && max_iters > 0);
for (yy = 0; yy < foam_mask_h; yy++) for (yy = 0; yy < foam_mask_h; yy++)
{
for (xx = 0; xx < foam_mask_w; xx++)
{ {
n = foam_mask[yy * foam_mask_w + xx]; for (xx = 0; xx < foam_mask_w; xx++)
{
n = foam_mask[yy * foam_mask_w + xx];
img = NULL; img = NULL;
if (n == 1)
img = foam_1;
else if (n == 3)
img = foam_3;
else if (n == 5)
img = foam_5;
else if (n == 7)
img = foam_7;
if (img != NULL) if (n == 1)
{ img = foam_1;
dest.x = (xx * FOAM_PROP) - (img->w / 2) + ((rand() % 15) - 7); else if (n == 3)
dest.y = (yy * FOAM_PROP) - (img->h / 2) + ((rand() % 15) - 7); img = foam_3;
else if (n == 5)
img = foam_5;
else if (n == 7)
img = foam_7;
SDL_BlitSurface(img, NULL, canvas, &dest); if (img != NULL)
} {
dest.x = (xx * FOAM_PROP) - (img->w / 2) + ((rand() % 15) - 7);
dest.y = (yy * FOAM_PROP) - (img->h / 2) + ((rand() % 15) - 7);
SDL_BlitSurface(img, NULL, canvas, &dest);
}
}
} }
}
memcpy(foam_mask, foam_mask_tmp, (sizeof(int) * (foam_mask_w * foam_mask_h))); memcpy(foam_mask, foam_mask_tmp, (sizeof(int) * (foam_mask_w * foam_mask_h)));
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -409,7 +412,7 @@ void foam_shutdown(magic_api * api ATTRIBUTE_UNUSED)
if (foam_mask != NULL) if (foam_mask != NULL)
free(foam_mask); free(foam_mask);
if (foam_1 != NULL) if (foam_1 != NULL)
SDL_FreeSurface(foam_1); SDL_FreeSurface(foam_1);
if (foam_3 != NULL) if (foam_3 != NULL)
@ -431,18 +434,20 @@ void foam_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
// Use colors: // Use colors:
int foam_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int foam_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return 0; /* FIXME: Would be nice to tint the bubbles */ return 0; /* FIXME: Would be nice to tint the bubbles */
} }
void foam_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void foam_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void foam_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void foam_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int foam_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int foam_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -15,76 +15,67 @@ int fold_ox, fold_oy;
int fold_x, fold_y; int fold_x, fold_y;
Uint8 fold_shadow_value; Uint8 fold_shadow_value;
Uint8 corner; Uint8 corner;
Mix_Chunk * fold_snd; Mix_Chunk *fold_snd;
Uint8 fold_r, fold_g, fold_b; Uint8 fold_r, fold_g, fold_b;
Uint32 fold_color; Uint32 fold_color;
SDL_Surface * fold_surface_src, * fold_surface_dst; SDL_Surface *fold_surface_src, *fold_surface_dst;
void fold_draw(magic_api * api, int which, void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect); static void fold_erase(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void fold_erase(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, void translate_coords(SDL_Surface * canvas, int angle);
int x, int y); SDL_Surface *rotate(magic_api * api, SDL_Surface * canvas, int angle);
void translate_coords(SDL_Surface * canvas,int angle);
SDL_Surface * rotate(magic_api * api, SDL_Surface * canvas, int angle);
void fold_draw(magic_api * api, int which, void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect); static void fold_print_line(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void fold_print_line(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void fold_print_dark_line(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y); void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b, int rotation);
static void fold_print_dark_line(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void translate_xy(SDL_Surface * canvas, int x, int y, int * a, int * b, int rotation);
Uint32 fold_api_version(void); Uint32 fold_api_version(void);
void fold_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void fold_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int fold_init(magic_api * api); int fold_init(magic_api * api);
int fold_get_tool_count(magic_api * api); int fold_get_tool_count(magic_api * api);
SDL_Surface * fold_get_icon(magic_api * api, int which); SDL_Surface *fold_get_icon(magic_api * api, int which);
char * fold_get_name(magic_api * api, int which); char *fold_get_name(magic_api * api, int which);
char * fold_get_description(magic_api * api, int which, int mode); char *fold_get_description(magic_api * api, int which, int mode);
int fold_requires_colors(magic_api * api, int which); int fold_requires_colors(magic_api * api, int which);
void fold_release(magic_api * api, int which, void fold_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fold_shutdown(magic_api * api); void fold_shutdown(magic_api * api);
void fold_click(magic_api * ptr, int which, int mode, void fold_click(magic_api * ptr, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fold_preview(magic_api * api, int which, SDL_Surface * canvas, void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
int fold_modes(magic_api * api, int which); int fold_modes(magic_api * api, int which);
// Housekeeping functions
// Housekeeping functions
void fold_drag(magic_api * api, int which, SDL_Surface * canvas, void fold_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void fold_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void fold_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas); inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas);
void fold_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void fold_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
Uint32 fold_api_version(void) Uint32 fold_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void fold_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure void fold_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
{ {
fold_r=r; fold_r = r;
fold_g=g; fold_g = g;
fold_b=b; fold_b = b;
} }
int fold_init(magic_api * api) int fold_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/fold.wav", api->data_directory); snprintf(fname, sizeof(fname), "%s/sounds/magic/fold.wav", api->data_directory);
fold_snd = Mix_LoadWAV(fname); fold_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int fold_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int fold_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -92,386 +83,421 @@ int fold_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * fold_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) SDL_Surface *fold_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/fold.png", snprintf(fname, sizeof(fname), "%s/images/magic/fold.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * fold_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return(gettext_noop("Fold")); } char *fold_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char * fold_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Choose a background color and click to turn the corner of the page over.")); }
int fold_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 1; } //selected color will be a "backpage" color
static void fold_shadow(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * temp,
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; return (gettext_noop("Fold"));
Uint8 r,g,b,a; }
SDL_GetRGBA(api->getpixel(temp, x, y),
temp->format, &r, &g, &b, &a); char *fold_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format, {
max(r-160+fold_shadow_value*4,0), max(g-160+fold_shadow_value*4,0), max(b-160+fold_shadow_value*4,0), a)); return strdup(gettext_noop("Choose a background color and click to turn the corner of the page over."));
}
int fold_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 1;
} //selected color will be a "backpage" color
static void fold_shadow(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * temp, int x, int y)
{
magic_api *api = (magic_api *) ptr;
Uint8 r, g, b, a;
SDL_GetRGBA(api->getpixel(temp, x, y), temp->format, &r, &g, &b, &a);
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format,
max(r - 160 + fold_shadow_value * 4, 0), max(g - 160 + fold_shadow_value * 4,
0),
max(b - 160 + fold_shadow_value * 4, 0), a));
} }
void fold_draw(magic_api * api, int which, void fold_draw(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
float right_step_x, right_step_y, left_step_x, left_step_y; float right_step_x, right_step_y, left_step_x, left_step_y;
float dist_x, dist_y; float dist_x, dist_y;
int left_y, right_x; int left_y, right_x;
float w, h; float w, h;
SDL_Surface * temp; SDL_Surface *temp;
temp=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
SDL_BlitSurface(canvas,0,temp,0);
right_step_x=(float)(x-left_arm_x)/(float)(left_arm_x-fold_ox); temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
right_step_y=(float)(y-left_arm_y)/(float)(left_arm_x-fold_ox); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
left_step_x=(float)(x-right_arm_x)/(float)(right_arm_y-fold_oy); canvas->format->Amask);
left_step_y=(float)(y-right_arm_y)/(float)(right_arm_y-fold_oy); SDL_BlitSurface(canvas, 0, temp, 0);
for (w=0;w < canvas->w;w+=0.5)
for(h=0;h < canvas->h;h+=0.5) right_step_x = (float)(x - left_arm_x) / (float)(left_arm_x - fold_ox);
right_step_y = (float)(y - left_arm_y) / (float)(left_arm_x - fold_ox);
left_step_x = (float)(x - right_arm_x) / (float)(right_arm_y - fold_oy);
left_step_y = (float)(y - right_arm_y) / (float)(right_arm_y - fold_oy);
for (w = 0; w < canvas->w; w += 0.5)
for (h = 0; h < canvas->h; h += 0.5)
{ {
dist_x=right_step_x*w+left_step_x*h; dist_x = right_step_x * w + left_step_x * h;
dist_y=right_step_y*w+left_step_y*h; dist_y = right_step_y * w + left_step_y * h;
api->putpixel(canvas, x-dist_x, y-dist_y, api->getpixel(temp,w,h)); api->putpixel(canvas, x - dist_x, y - dist_y, api->getpixel(temp, w, h));
} }
// Erasing the triangle. // Erasing the triangle.
// The 1 pixel in plus is a workaround for api-line not getting the end in some lines. // The 1 pixel in plus is a workaround for api-line not getting the end in some lines.
if (left_arm_x > canvas->w) if (left_arm_x > canvas->w)
{ {
left_y=(float)right_arm_y/left_arm_x*(left_arm_x-canvas->w); left_y = (float)right_arm_y / left_arm_x * (left_arm_x - canvas->w);
for (h = 0; h <= right_arm_y; h++) for (h = 0; h <= right_arm_y; h++)
api->line((void *)api, which, canvas, snapshot, canvas->w, left_y-h, -1, right_arm_y-h, 1, fold_erase); api->line((void *)api, which, canvas, snapshot, canvas->w, left_y - h, -1, right_arm_y - h, 1, fold_erase);
} }
else if (right_arm_y > canvas->h) else if (right_arm_y > canvas->h)
{ {
right_x=(float)left_arm_x/right_arm_y*(right_arm_y-canvas->h); right_x = (float)left_arm_x / right_arm_y * (right_arm_y - canvas->h);
for (w = 0; w <= left_arm_x; w++) for (w = 0; w <= left_arm_x; w++)
api->line((void *)api, which, canvas, snapshot, left_arm_x-w, 0, right_x-w, canvas->h +1, 1, fold_erase); api->line((void *)api, which, canvas, snapshot, left_arm_x - w, 0, right_x - w, canvas->h + 1, 1, fold_erase);
} }
else else
for (w = 0; w <= min(left_arm_x,right_arm_y); w++) // The -1 values are because api->line for (w = 0; w <= min(left_arm_x, right_arm_y); w++) // The -1 values are because api->line
api->line((void *)api, which, canvas, snapshot, left_arm_x-w, 0, -1, right_arm_y-w, 1, fold_erase); api->line((void *)api, which, canvas, snapshot, left_arm_x - w, 0, -1, right_arm_y - w, 1, fold_erase);
SDL_BlitSurface(canvas,0,temp,0); SDL_BlitSurface(canvas, 0, temp, 0);
// Shadows // Shadows
if (left_arm_x > canvas->w) if (left_arm_x > canvas->w)
{ {
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value+=1) for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, canvas->w, left_y-fold_shadow_value, 0, right_arm_y-fold_shadow_value, 1, fold_shadow); api->line((void *)api, which, canvas, temp, canvas->w, left_y - fold_shadow_value, 0,
right_arm_y - fold_shadow_value, 1, fold_shadow);
} }
else if (right_arm_y > canvas->h) else if (right_arm_y > canvas->h)
{ {
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value+=1) for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, left_arm_x-fold_shadow_value, 0, right_x - fold_shadow_value, canvas->h, 1, fold_shadow); api->line((void *)api, which, canvas, temp, left_arm_x - fold_shadow_value, 0, right_x - fold_shadow_value,
canvas->h, 1, fold_shadow);
} }
else else
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value+=1) for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
api->line((void *)api, which, canvas, temp, left_arm_x-fold_shadow_value, 0, 0, right_arm_y-fold_shadow_value, 1, fold_shadow); api->line((void *)api, which, canvas, temp, left_arm_x - fold_shadow_value, 0, 0, right_arm_y - fold_shadow_value,
1, fold_shadow);
SDL_BlitSurface(canvas,0,temp,0); SDL_BlitSurface(canvas, 0, temp, 0);
for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value+=1) for (fold_shadow_value = 0; fold_shadow_value < 40; fold_shadow_value += 1)
{ {
if (fold_shadow_value*left_step_x > x || fold_shadow_value*right_step_y > y) break; if (fold_shadow_value * left_step_x > x || fold_shadow_value * right_step_y > y)
break;
dist_x=fold_shadow_value*(right_step_x+left_step_x); dist_x = fold_shadow_value * (right_step_x + left_step_x);
dist_y=fold_shadow_value*(right_step_y+left_step_y); dist_y = fold_shadow_value * (right_step_y + left_step_y);
api->line((void *)api, which, canvas, temp, left_arm_x+fold_shadow_value*right_step_x, fold_shadow_value*right_step_y, fold_shadow_value*left_step_x, right_arm_y+fold_shadow_value*left_step_y, 1, fold_shadow); api->line((void *)api, which, canvas, temp, left_arm_x + fold_shadow_value * right_step_x,
fold_shadow_value * right_step_y, fold_shadow_value * left_step_x,
right_arm_y + fold_shadow_value * left_step_y, 1, fold_shadow);
} }
api->line((void *)api, which, canvas, snapshot, x, y, right_arm_x, right_arm_y, 1, fold_print_line); api->line((void *)api, which, canvas, snapshot, x, y, right_arm_x, right_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line); api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1, fold_print_dark_line); api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1,
fold_print_dark_line);
} }
SDL_Surface * rotate(magic_api * api, SDL_Surface * canvas, int angle) SDL_Surface *rotate(magic_api * api, SDL_Surface * canvas, int angle)
{ {
SDL_Surface * temp; SDL_Surface *temp;
int x,y; int x, y;
int a,b; int a, b;
if (angle==180) if (angle == 180)
temp=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
else else
temp=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->h, canvas->w, canvas->format->BitsPerPixel, temp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->h, canvas->w, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
switch (angle) switch (angle)
{ {
case 90: case 90:
for (x=0; x<canvas->w; x++) for (x = 0; x < canvas->w; x++)
for (y=0; y<canvas->h; y++) for (y = 0; y < canvas->h; y++)
{ {
translate_xy(canvas,x,y,&a,&b,90); translate_xy(canvas, x, y, &a, &b, 90);
api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
} }
break; break;
case 180: case 180:
// printf("%i, %i\n",temp,canvas); // printf("%i, %i\n",temp,canvas);
for (x=0; x<canvas->w; x++) for (x = 0; x < canvas->w; x++)
for (y=0; y<canvas->h; y++) for (y = 0; y < canvas->h; y++)
{ {
translate_xy(canvas,x,y,&a,&b,180); translate_xy(canvas, x, y, &a, &b, 180);
api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
} }
break; break;
case 270: case 270:
for (x=0; x<canvas->w; x++) for (x = 0; x < canvas->w; x++)
for (y=0; y<canvas->h; y++) for (y = 0; y < canvas->h; y++)
{ {
translate_xy(canvas,x,y,&a,&b,270); translate_xy(canvas, x, y, &a, &b, 270);
api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); api->putpixel(temp, a, b, api->getpixel(canvas, x, y));
} }
break; break;
} }
return temp; return temp;
} }
void translate_coords(SDL_Surface * canvas,int angle) void translate_coords(SDL_Surface * canvas, int angle)
{ {
int a,b; int a, b;
switch (angle) switch (angle)
{ {
case 90: case 90:
translate_xy(canvas,right_arm_x,right_arm_y,&a,&b,90); translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 90);
right_arm_x=a; right_arm_x = a;
right_arm_y=b; right_arm_y = b;
translate_xy(canvas,left_arm_x,left_arm_y,&a,&b,90); translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 90);
left_arm_x=a; left_arm_x = a;
left_arm_y=b; left_arm_y = b;
break; break;
case 180: case 180:
right_arm_x=canvas->w-1-right_arm_x; right_arm_x = canvas->w - 1 - right_arm_x;
right_arm_y=canvas->h-1-right_arm_y; right_arm_y = canvas->h - 1 - right_arm_y;
left_arm_x=canvas->w-1-left_arm_x; left_arm_x = canvas->w - 1 - left_arm_x;
left_arm_y=canvas->h-1-left_arm_y; left_arm_y = canvas->h - 1 - left_arm_y;
break; break;
case 270: case 270:
translate_xy(canvas,right_arm_x,right_arm_y,&a,&b,270); translate_xy(canvas, right_arm_x, right_arm_y, &a, &b, 270);
right_arm_x=a; right_arm_x = a;
right_arm_y=b; right_arm_y = b;
translate_xy(canvas,left_arm_x, left_arm_y, &a, &b, 270); translate_xy(canvas, left_arm_x, left_arm_y, &a, &b, 270);
left_arm_x=a; left_arm_x = a;
left_arm_y=b; left_arm_y = b;
break; break;
} }
} }
void translate_xy(SDL_Surface * canvas, int x, int y, int * a, int * b, int rotation) void translate_xy(SDL_Surface * canvas, int x, int y, int *a, int *b, int rotation)
{ {
switch (rotation) switch (rotation)
{ {
case 90: case 90:
*a=y; *a = y;
*b=canvas->w -1 -x; *b = canvas->w - 1 - x;
break; break;
case 180: case 180:
*a=canvas->w -1 -x; *a = canvas->w - 1 - x;
*b=canvas->h -1 -y; *b = canvas->h - 1 - y;
break; break;
case 270: case 270:
*a=canvas->h -1 -y; *a = canvas->h - 1 - y;
*b=x; *b = x;
break; break;
} }
} }
void fold_release(magic_api * api, int which, void fold_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
int a,b; int a, b;
SDL_Surface * temp, *temp2; SDL_Surface *temp, *temp2;
x=fold_x; x = fold_x;
y=fold_y; y = fold_y;
fold_ox=fold_oy=0; fold_ox = fold_oy = 0;
SDL_BlitSurface(snapshot, 0, canvas, 0); SDL_BlitSurface(snapshot, 0, canvas, 0);
switch (corner) switch (corner)
{ {
case 1: case 1:
translate_xy(canvas,x,y,&a,&b,90); translate_xy(canvas, x, y, &a, &b, 90);
translate_coords(canvas,90); translate_coords(canvas, 90);
temp=rotate(api, canvas, 90); temp = rotate(api, canvas, 90);
fold_draw (api, which, temp, snapshot, a, b,update_rect); fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2=rotate(api,temp,270); temp2 = rotate(api, temp, 270);
SDL_BlitSurface(temp2,0,canvas,0); SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp); SDL_FreeSurface(temp);
SDL_FreeSurface(temp2); SDL_FreeSurface(temp2);
break; break;
case 2: case 2:
fold_draw (api, which, canvas, snapshot, x,y,update_rect); fold_draw(api, which, canvas, snapshot, x, y, update_rect);
break; break;
case 3: case 3:
translate_xy(canvas,x,y,&a,&b,270); translate_xy(canvas, x, y, &a, &b, 270);
translate_coords(canvas,270); translate_coords(canvas, 270);
temp=rotate(api, canvas, 270); temp = rotate(api, canvas, 270);
fold_draw (api, which, temp, snapshot, a, b,update_rect); fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2=rotate(api,temp,90); temp2 = rotate(api, temp, 90);
SDL_BlitSurface(temp2,0,canvas,0); SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface(temp); SDL_FreeSurface(temp);
SDL_FreeSurface(temp2); SDL_FreeSurface(temp2);
break; break;
case 4: case 4:
translate_xy(canvas,x,y,&a,&b,180); translate_xy(canvas, x, y, &a, &b, 180);
translate_coords(canvas,180); translate_coords(canvas, 180);
temp=rotate(api, canvas, 180); temp = rotate(api, canvas, 180);
fold_draw (api, which, temp, snapshot, a, b,update_rect); fold_draw(api, which, temp, snapshot, a, b, update_rect);
temp2=rotate(api,temp,180); temp2 = rotate(api, temp, 180);
SDL_BlitSurface(temp2,0,canvas,0); SDL_BlitSurface(temp2, 0, canvas, 0);
SDL_FreeSurface (temp); SDL_FreeSurface(temp);
SDL_FreeSurface (temp2); SDL_FreeSurface(temp2);
break; break;
} }
update_rect->x=update_rect->y=0; update_rect->x = update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
api->playsound(fold_snd, (x * 255) / canvas->w, 255); api->playsound(fold_snd, (x * 255) / canvas->w, 255);
} }
void fold_shutdown(magic_api * api ATTRIBUTE_UNUSED) void fold_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
Mix_FreeChunk(fold_snd); Mix_FreeChunk(fold_snd);
SDL_FreeSurface(fold_surface_dst); SDL_FreeSurface(fold_surface_dst);
SDL_FreeSurface(fold_surface_src); SDL_FreeSurface(fold_surface_src);
} }
// Interactivity functions // Interactivity functions
inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas) inline Uint8 fold_what_corner(int x, int y, SDL_Surface * canvas)
{ {
if (x>=canvas->w/2) if (x >= canvas->w / 2)
{ {
if (y>=canvas->h/2) return 4; if (y >= canvas->h / 2)
else return 1; return 4;
} else
else return 1;
{ }
if (y>=canvas->h/2) return 3; else
else return 2; {
} if (y >= canvas->h / 2)
return 3;
else
return 2;
}
} }
static void fold_print_line(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, static void fold_print_line(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last,
int x, int y) int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 222, 222, 222)); //Middle gray. Color have been set arbitrary.
} api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 222, 222, 222)); //Middle gray. Color have been set arbitrary.
static void fold_print_dark_line(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 90, 90, 90)); //It should not look too black nor too white with shadowed colors.
} }
static void fold_erase(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void fold_print_dark_line(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, fold_r, fold_g, fold_b));
api->putpixel(canvas, x, y, SDL_MapRGB(last->format, 90, 90, 90)); //It should not look too black nor too white with shadowed colors.
}
static void fold_erase(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y)
{
magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, fold_r, fold_g, fold_b));
} }
void fold_click(magic_api * ptr, int which, int mode ATTRIBUTE_UNUSED, void fold_click(magic_api * ptr, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
corner=fold_what_corner(x, y, snapshot);
corner = fold_what_corner(x, y, snapshot);
switch (corner) switch (corner)
{ {
case 1: case 1:
fold_ox=canvas->w-1; fold_ox = canvas->w - 1;
fold_oy=0; fold_oy = 0;
break; break;
case 2: case 2:
fold_ox=fold_oy=0; fold_ox = fold_oy = 0;
break; break;
case 3: case 3:
fold_ox=0; fold_ox = 0;
fold_oy=canvas->h-1; fold_oy = canvas->h - 1;
break; break;
case 4: case 4:
fold_ox=canvas->w-1; fold_ox = canvas->w - 1;
fold_oy=canvas->h-1; fold_oy = canvas->h - 1;
break; break;
} }
fold_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); fold_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
void fold_preview(magic_api * api, int which, SDL_Surface * canvas, void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Surface * snapshot, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
int middle_point_x; int middle_point_x;
int middle_point_y; int middle_point_y;
fold_x=x; fold_x = x;
fold_y=y; fold_y = y;
SDL_BlitSurface(snapshot,0,canvas,0); SDL_BlitSurface(snapshot, 0, canvas, 0);
middle_point_x=(fold_ox+x)/2; middle_point_x = (fold_ox + x) / 2;
middle_point_y=(fold_oy+y)/2; middle_point_y = (fold_oy + y) / 2;
switch(corner) switch (corner)
{ {
case 1: //Right Upper case 1: //Right Upper
right_arm_x=fold_ox- (fold_ox-middle_point_x)-middle_point_y*middle_point_y/(fold_ox-middle_point_x); right_arm_x = fold_ox - (fold_ox - middle_point_x) - middle_point_y * middle_point_y / (fold_ox - middle_point_x);
right_arm_y=fold_oy; right_arm_y = fold_oy;
left_arm_x=fold_ox; left_arm_x = fold_ox;
left_arm_y=fold_oy-(fold_oy-middle_point_y)-(fold_ox-middle_point_x)*(fold_ox-middle_point_x)/(fold_oy-middle_point_y); left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
break; break;
case 2: //LU case 2: //LU
right_arm_x=fold_ox; right_arm_x = fold_ox;
right_arm_y=middle_point_y+middle_point_x*middle_point_x/middle_point_y; right_arm_y = middle_point_y + middle_point_x * middle_point_x / middle_point_y;
left_arm_x=middle_point_x+middle_point_y*middle_point_y/middle_point_x; left_arm_x = middle_point_x + middle_point_y * middle_point_y / middle_point_x;
left_arm_y=fold_oy; left_arm_y = fold_oy;
break;
case 3: //LL
right_arm_x=middle_point_x+(fold_oy-middle_point_y)*(fold_oy-middle_point_y)/middle_point_x;
right_arm_y=fold_oy;
left_arm_x=fold_ox;
left_arm_y=fold_oy-(fold_oy-middle_point_y)-(fold_ox-middle_point_x)*(fold_ox-middle_point_x)/(fold_oy-middle_point_y);
break; break;
case 4: //RL case 3: //LL
right_arm_x=fold_ox; right_arm_x = middle_point_x + (fold_oy - middle_point_y) * (fold_oy - middle_point_y) / middle_point_x;
right_arm_y=fold_oy-(fold_oy-middle_point_y)-(fold_ox-middle_point_x)*(fold_ox-middle_point_x)/(fold_oy-middle_point_y); right_arm_y = fold_oy;
left_arm_x=fold_ox-(fold_ox-middle_point_x)-(fold_oy-middle_point_y)*(fold_oy-middle_point_y)/(fold_ox-middle_point_x); left_arm_x = fold_ox;
left_arm_y=fold_oy; left_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
break;
case 4: //RL
right_arm_x = fold_ox;
right_arm_y =
fold_oy - (fold_oy - middle_point_y) - (fold_ox - middle_point_x) * (fold_ox - middle_point_x) / (fold_oy -
middle_point_y);
left_arm_x =
fold_ox - (fold_ox - middle_point_x) - (fold_oy - middle_point_y) * (fold_oy - middle_point_y) / (fold_ox -
middle_point_x);
left_arm_y = fold_oy;
break; break;
} }
@ -479,30 +505,31 @@ void fold_preview(magic_api * api, int which, SDL_Surface * canvas,
api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line); api->line((void *)api, which, canvas, snapshot, x, y, left_arm_x, left_arm_y, 1, fold_print_line);
api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1, fold_print_line); api->line((void *)api, which, canvas, snapshot, left_arm_x, left_arm_y, right_arm_x, right_arm_y, 1, fold_print_line);
update_rect->x=update_rect->y=0; update_rect->x = update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
} }
void fold_drag(magic_api * api, int which, SDL_Surface * canvas, void fold_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
// Avoid division by zero when calculating the preview // Avoid division by zero when calculating the preview
x=clamp(2,x,canvas->w-2); x = clamp(2, x, canvas->w - 2);
y=clamp(2,y,canvas->h-2); y = clamp(2, y, canvas->h - 2);
fold_preview(api, which, canvas, snapshot, ox, oy, x, y, update_rect); fold_preview(api, which, canvas, snapshot, ox, oy, x, y, update_rect);
} }
void fold_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fold_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void fold_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void fold_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int fold_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int fold_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }

View file

@ -22,84 +22,80 @@
#define SEG_RIGHT_TOP_BOTTOM (SEG_RIGHT | SEG_TOP | SEG_BOTTOM) #define SEG_RIGHT_TOP_BOTTOM (SEG_RIGHT | SEG_TOP | SEG_BOTTOM)
#define SEG_LEFT_RIGHT_TOP_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_TOP | SEG_BOTTOM) #define SEG_LEFT_RIGHT_TOP_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_TOP | SEG_BOTTOM)
Mix_Chunk * fretwork_snd; Mix_Chunk *fretwork_snd;
unsigned int img_w, img_h; unsigned int img_w, img_h;
unsigned int fretwork_segments_x, fretwork_segments_y; //how many segments do we have? unsigned int fretwork_segments_x, fretwork_segments_y; //how many segments do we have?
static int fretwork_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one static int fretwork_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one
static Uint8 * fretwork_status_of_segments; //a place to store an info about bitmap used for selected segment static Uint8 *fretwork_status_of_segments; //a place to store an info about bitmap used for selected segment
static char ** fretwork_images; //the pathes to all the images needed static char **fretwork_images; //the pathes to all the images needed
static unsigned int fretwork_segment_modified; //which segment was modified this time? static unsigned int fretwork_segment_modified; //which segment was modified this time?
static unsigned int fretwork_segment_modified_last =0; //which segment was last modified static unsigned int fretwork_segment_modified_last = 0; //which segment was last modified
static unsigned int fretwork_segment_to_add =0; //a segment that should be added to solve corner joint static unsigned int fretwork_segment_to_add = 0; //a segment that should be added to solve corner joint
static unsigned int fretwork_segment_last_clicked; static unsigned int fretwork_segment_last_clicked;
static Uint8 fretwork_r, fretwork_g, fretwork_b; static Uint8 fretwork_r, fretwork_g, fretwork_b;
static unsigned int fretwork_full_runs; //The count of the clicks in full mode static unsigned int fretwork_full_runs; //The count of the clicks in full mode
static unsigned int fretwork_segment_start_rectangle; //the segment were the update_rectangle will start static unsigned int fretwork_segment_start_rectangle; //the segment were the update_rectangle will start
static unsigned int fretwork_update_rectangle_width; //the width of the update_rectangle static unsigned int fretwork_update_rectangle_width; //the width of the update_rectangle
static unsigned int fretwork_update_rectangle_height; //the height of the update_rectangle static unsigned int fretwork_update_rectangle_height; //the height of the update_rectangle
static SDL_Rect modification_rect; static SDL_Rect modification_rect;
static SDL_Surface * canvas_backup; static SDL_Surface *canvas_backup;
static SDL_Surface * fretwork_one_back, * fretwork_three_back, * fretwork_four_back, * fretwork_corner_back; static SDL_Surface *fretwork_one_back, *fretwork_three_back, *fretwork_four_back, *fretwork_corner_back;
// Housekeeping functions // Housekeeping functions
Uint32 fretwork_api_version(void); Uint32 fretwork_api_version(void);
int fretwork_modes(magic_api * api, int which); int fretwork_modes(magic_api * api, int which);
void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src ); static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src);
int fretwork_init(magic_api * api); int fretwork_init(magic_api * api);
int fretwork_get_tool_count(magic_api * api); int fretwork_get_tool_count(magic_api * api);
SDL_Surface * fretwork_get_icon(magic_api * api, int which); SDL_Surface *fretwork_get_icon(magic_api * api, int which);
char * fretwork_get_name(magic_api * api, int which); char *fretwork_get_name(magic_api * api, int which);
char * fretwork_get_description(magic_api * api, int which, int mode); char *fretwork_get_description(magic_api * api, int which, int mode);
int fretwork_requires_colors(magic_api * api, int which); int fretwork_requires_colors(magic_api * api, int which);
void fretwork_release(magic_api * api, int which, void fretwork_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fretwork_shutdown(magic_api * api); void fretwork_shutdown(magic_api * api);
void fretwork_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); void fretwork_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void fretwork_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); void fretwork_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
inline void fretwork_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y); inline void fretwork_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y);
void fretwork_click(magic_api * api, int which, int mode, void fretwork_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void fretwork_drag(magic_api * api, int which, SDL_Surface * canvas, void fretwork_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect); static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void fretwork_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
inline unsigned int fretwork_get_segment(int x, int y); inline unsigned int fretwork_get_segment(int x, int y);
SDL_Surface * fretwork_one, * fretwork_three, * fretwork_four, * fretwork_corner; SDL_Surface *fretwork_one, *fretwork_three, *fretwork_four, *fretwork_corner;
Uint32 fretwork_api_version(void) Uint32 fretwork_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
int fretwork_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int fretwork_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT|MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }
void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b) void fretwork_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{ {
fretwork_r=r; fretwork_r = r;
fretwork_g=g; fretwork_g = g;
fretwork_b=b; fretwork_b = b;
fretwork_colorize(api,fretwork_one, fretwork_one_back); fretwork_colorize(api, fretwork_one, fretwork_one_back);
fretwork_colorize(api, fretwork_three, fretwork_three_back); fretwork_colorize(api, fretwork_three, fretwork_three_back);
fretwork_colorize(api, fretwork_four, fretwork_four_back); fretwork_colorize(api, fretwork_four, fretwork_four_back);
fretwork_colorize(api, fretwork_corner, fretwork_corner_back); fretwork_colorize(api, fretwork_corner, fretwork_corner_back);
} }
/* Adapted from flower.c */ /* Adapted from flower.c */
static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src ) static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface * src)
{ {
int x, y; int x, y;
Uint8 r, g, b, a; Uint8 r, g, b, a;
@ -110,14 +106,11 @@ static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface *
for (y = 0; y < src->h; y++) for (y = 0; y < src->h; y++)
{ {
for (x = 0; x < src->w; x++) for (x = 0; x < src->w; x++)
{ {
SDL_GetRGBA(api->getpixel(src, x, y), SDL_GetRGBA(api->getpixel(src, x, y), src->format, &r, &g, &b, &a);
src->format, &r, &g, &b, &a);
api->putpixel(dest, x, y, api->putpixel(dest, x, y, SDL_MapRGBA(dest->format, fretwork_r, fretwork_g, fretwork_b, a));
SDL_MapRGBA(dest->format, }
fretwork_r, fretwork_g, fretwork_b, a));
}
} }
SDL_UnlockSurface(src); SDL_UnlockSurface(src);
@ -128,34 +121,34 @@ static void fretwork_colorize(magic_api * api, SDL_Surface * dest, SDL_Surface *
int fretwork_init(magic_api * api) int fretwork_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
Uint8 i; //is always < 4, so Uint8 seems to be a good idea Uint8 i; //is always < 4, so Uint8 seems to be a good idea
fretwork_images=(char **)malloc(sizeof(char *)*4);
for (i = 0; i < 4; i++)
fretwork_images[i]=(char *)malloc(sizeof(char)*1024);
snprintf(fretwork_images[0], 1024*sizeof(char), "%s/images/magic/fretwork_one.png", api->data_directory);
snprintf(fretwork_images[1], 1024*sizeof(char), "%s/images/magic/fretwork_three.png", api->data_directory);
snprintf(fretwork_images[2], 1024*sizeof(char), "%s/images/magic/fretwork_four.png", api->data_directory);
snprintf(fretwork_images[3], 1024*sizeof(char), "%s/images/magic/fretwork_corner.png", api->data_directory);
fretwork_one=IMG_Load(fretwork_images[0]); fretwork_images = (char **)malloc(sizeof(char *) * 4);
fretwork_three=IMG_Load(fretwork_images[1]);
fretwork_four=IMG_Load(fretwork_images[2]); for (i = 0; i < 4; i++)
fretwork_corner=IMG_Load(fretwork_images[3]); fretwork_images[i] = (char *)malloc(sizeof(char) * 1024);
fretwork_one_back=IMG_Load(fretwork_images[0]);
fretwork_three_back=IMG_Load(fretwork_images[1]); snprintf(fretwork_images[0], 1024 * sizeof(char), "%s/images/magic/fretwork_one.png", api->data_directory);
fretwork_four_back=IMG_Load(fretwork_images[2]); snprintf(fretwork_images[1], 1024 * sizeof(char), "%s/images/magic/fretwork_three.png", api->data_directory);
fretwork_corner_back=IMG_Load(fretwork_images[3]); snprintf(fretwork_images[2], 1024 * sizeof(char), "%s/images/magic/fretwork_four.png", api->data_directory);
snprintf(fretwork_images[3], 1024 * sizeof(char), "%s/images/magic/fretwork_corner.png", api->data_directory);
fretwork_one = IMG_Load(fretwork_images[0]);
fretwork_three = IMG_Load(fretwork_images[1]);
fretwork_four = IMG_Load(fretwork_images[2]);
fretwork_corner = IMG_Load(fretwork_images[3]);
fretwork_one_back = IMG_Load(fretwork_images[0]);
fretwork_three_back = IMG_Load(fretwork_images[1]);
fretwork_four_back = IMG_Load(fretwork_images[2]);
fretwork_corner_back = IMG_Load(fretwork_images[3]);
img_w = fretwork_one->w; img_w = fretwork_one->w;
img_h = fretwork_one->h; img_h = fretwork_one->h;
snprintf(fname, sizeof(fname), "%s/sounds/magic/fretwork.ogg", api->data_directory); snprintf(fname, sizeof(fname), "%s/sounds/magic/fretwork.ogg", api->data_directory);
fretwork_snd = Mix_LoadWAV(fname); fretwork_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int fretwork_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int fretwork_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -163,38 +156,44 @@ int fretwork_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * fretwork_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *fretwork_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/fretwork.png", snprintf(fname, sizeof(fname), "%s/images/magic/fretwork.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * fretwork_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Fretwork")); } char *fretwork_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Fretwork"));
}
char * fretwork_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) { char *fretwork_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
if (mode==MODE_PAINT) {
if (mode == MODE_PAINT)
return strdup(gettext_noop("Click and drag to draw repetitive patterns. ")); return strdup(gettext_noop("Click and drag to draw repetitive patterns. "));
else else
return strdup(gettext_noop("Click to surround your picture with repetitive patterns.")); return strdup(gettext_noop("Click to surround your picture with repetitive patterns."));
} }
int fretwork_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 1;} int fretwork_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 1;
}
void fretwork_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void fretwork_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void fretwork_shutdown(magic_api * api ATTRIBUTE_UNUSED) void fretwork_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
Uint8 i; Uint8 i;
if (fretwork_snd!=NULL) if (fretwork_snd != NULL)
Mix_FreeChunk(fretwork_snd); Mix_FreeChunk(fretwork_snd);
SDL_FreeSurface(fretwork_one); SDL_FreeSurface(fretwork_one);
SDL_FreeSurface(fretwork_three); SDL_FreeSurface(fretwork_three);
@ -205,7 +204,7 @@ void fretwork_shutdown(magic_api * api ATTRIBUTE_UNUSED)
SDL_FreeSurface(fretwork_four_back); SDL_FreeSurface(fretwork_four_back);
SDL_FreeSurface(fretwork_corner_back); SDL_FreeSurface(fretwork_corner_back);
SDL_FreeSurface(canvas_backup); SDL_FreeSurface(canvas_backup);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
free(fretwork_images[i]); free(fretwork_images[i]);
free(fretwork_images); free(fretwork_images);
@ -213,22 +212,25 @@ void fretwork_shutdown(magic_api * api ATTRIBUTE_UNUSED)
free(fretwork_status_of_segments); free(fretwork_status_of_segments);
} }
void fretwork_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED) void fretwork_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{ {
//we've to compute the quantity of segments in each direction //we've to compute the quantity of segments in each direction
canvas_backup=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
fretwork_segments_x=fretwork_math_ceil(canvas->w,img_w); fretwork_segments_x = fretwork_math_ceil(canvas->w, img_w);
fretwork_segments_y=fretwork_math_ceil(canvas->h,img_h); fretwork_segments_y = fretwork_math_ceil(canvas->h, img_h);
fretwork_status_of_segments=(Uint8 *)calloc(fretwork_segments_x*fretwork_segments_y + 1, sizeof(Uint8)); //segments starts at 1, while fretwork_status_of_segments[] starts at 0 fretwork_status_of_segments = (Uint8 *) calloc(fretwork_segments_x * fretwork_segments_y + 1, sizeof(Uint8)); //segments starts at 1, while fretwork_status_of_segments[] starts at 0
fretwork_full_runs=1; fretwork_full_runs = 1;
} }
void fretwork_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED) void fretwork_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED)
{ {
free(fretwork_status_of_segments); free(fretwork_status_of_segments);
fretwork_status_of_segments = NULL; fretwork_status_of_segments = NULL;
@ -238,29 +240,32 @@ void fretwork_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UN
static int fretwork_math_ceil(int x, int y) static int fretwork_math_ceil(int x, int y)
{ {
int temp; int temp;
temp=(int)x/y;
if (x%y) temp = (int)x / y;
return temp+1; if (x % y)
else return temp; return temp + 1;
else
return temp;
} }
inline unsigned int fretwork_get_segment(int x, int y) inline unsigned int fretwork_get_segment(int x, int y)
{ {
int xx; //segments are numerated just like pixels int xx; //segments are numerated just like pixels
int yy; //in computer graphics: left upper (=1), ... ,right upper, int yy; //in computer graphics: left upper (=1), ... ,right upper,
//left bottom, ... , right bottom
xx=fretwork_math_ceil(x, img_w);
yy=fretwork_math_ceil(y, img_h);
return (yy-1)*fretwork_segments_x+xx; //left bottom, ... , right bottom
xx = fretwork_math_ceil(x, img_w);
yy = fretwork_math_ceil(y, img_h);
return (yy - 1) * fretwork_segments_x + xx;
} }
inline void fretwork_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y) inline void fretwork_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y)
{ {
*x=((segment%fretwork_segments_x)-1)*img_w; //useful to set update_rect as small as possible *x = ((segment % fretwork_segments_x) - 1) * img_w; //useful to set update_rect as small as possible
*y=(int)(segment/fretwork_segments_x)*img_h; *y = (int)(segment / fretwork_segments_x) * img_h;
} }
/* static void fretwork_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src) */ /* static void fretwork_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src) */
@ -274,75 +279,80 @@ inline void fretwork_extract_coords_from_segment(unsigned int segment, Sint16 *
/* api->putpixel(dest, x, y, api->getpixel(src, x, src->h-y)); */ /* api->putpixel(dest, x, y, api->getpixel(src, x, src->h-y)); */
/* } */ /* } */
static void fretwork_flip_flop(void * ptr, SDL_Surface * dest, SDL_Surface * src) static void fretwork_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Sint16 x, y; Sint16 x, y;
for (x=0; x<dest->w; x++)
for (y=0; y<dest->h; y++) for (x = 0; x < dest->w; x++)
api->putpixel(dest, dest->w-1-x, dest->h-1-y, api->getpixel(src, x, y)); for (y = 0; y < dest->h; y++)
api->putpixel(dest, dest->w - 1 - x, dest->h - 1 - y, api->getpixel(src, x, y));
} }
static void fretwork_rotate (void * ptr, SDL_Surface * dest, SDL_Surface * src, _Bool direction) static void fretwork_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, _Bool direction)
//src and dest must have same size //src and dest must have same size
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Sint16 x,y; Sint16 x, y;
if (direction) //rotate -90 degs if (direction) //rotate -90 degs
{ {
for (x = 0; x<dest->w; x++) for (x = 0; x < dest->w; x++)
for (y =0; y<dest->h; y++) for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src,y,src->h-1-x)); api->putpixel(dest, x, y, api->getpixel(src, y, src->h - 1 - x));
} }
else //rotate +90 degs else //rotate +90 degs
{ {
for (x=0; x<dest->w; x++) for (x = 0; x < dest->w; x++)
for (y=0; y<dest->h; y++) for (y = 0; y < dest->h; y++)
api->putpixel(dest,x,y,api->getpixel(src,src->h-y-1,x)); api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
} }
} }
void fretwork_click(magic_api * api, int which, int mode, void fretwork_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
int left_x, right_x, top_y, bottom_y; int left_x, right_x, top_y, bottom_y;
fretwork_segment_modified_last = 0; fretwork_segment_modified_last = 0;
if (mode==MODE_PAINT) if (mode == MODE_PAINT)
{ {
fretwork_segment_last_clicked=fretwork_get_segment(x,y); fretwork_segment_last_clicked = fretwork_get_segment(x, y);
fretwork_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); fretwork_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
else else
{ {
if (fretwork_full_runs<=min(fretwork_segments_x,fretwork_segments_y)/2) if (fretwork_full_runs <= min(fretwork_segments_x, fretwork_segments_y) / 2)
{ {
left_x=img_w*fretwork_full_runs; left_x = img_w * fretwork_full_runs;
right_x=img_w*fretwork_segments_x-img_w*fretwork_full_runs; right_x = img_w * fretwork_segments_x - img_w * fretwork_full_runs;
top_y=img_h*fretwork_full_runs; top_y = img_h * fretwork_full_runs;
bottom_y=img_h*fretwork_segments_y-img_h*(fretwork_full_runs-1); bottom_y = img_h * fretwork_segments_y - img_h * (fretwork_full_runs - 1);
//left line //left line
api->line((void *) api, which, canvas, snapshot, left_x, top_y, left_x, bottom_y, img_w/2, fretwork_draw_wrapper); api->line((void *)api, which, canvas, snapshot, left_x, top_y, left_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
//top line //top line
api->line((void *) api, which, canvas, snapshot, left_x, top_y, right_x, top_y, img_w/2, fretwork_draw_wrapper); api->line((void *)api, which, canvas, snapshot, left_x, top_y, right_x, top_y, img_w / 2,
fretwork_draw_wrapper);
//bottom line //bottom line
api->line((void *) api, which, canvas, snapshot, left_x, bottom_y, right_x, bottom_y, img_w/2, fretwork_draw_wrapper); api->line((void *)api, which, canvas, snapshot, left_x, bottom_y, right_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
//right line //right line
api->line((void *) api, which, canvas, snapshot, right_x, top_y, right_x, bottom_y, img_w/2, fretwork_draw_wrapper); api->line((void *)api, which, canvas, snapshot, right_x, top_y, right_x, bottom_y, img_w / 2,
fretwork_draw_wrapper);
fretwork_full_runs +=1; fretwork_full_runs += 1;
update_rect->x=0; update_rect->x = 0;
update_rect->y=0; update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
} }
} }
} }
@ -355,64 +365,73 @@ static Uint8 fretwork_select_image(Uint16 segment)
int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0; int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0;
//Checking from were we come... //Checking from were we come...
if (fretwork_segment_modified_last>0) if (fretwork_segment_modified_last > 0)
{ {
if (segment == fretwork_segment_modified_last + 1) if (segment == fretwork_segment_modified_last + 1)
from_left = 1; from_left = 1;
else if (segment == fretwork_segment_modified_last - 1) else if (segment == fretwork_segment_modified_last - 1)
from_right = 1; from_right = 1;
else if (segment == fretwork_segment_modified_last - fretwork_segments_x) else if (segment == fretwork_segment_modified_last - fretwork_segments_x)
from_bottom = 1; from_bottom = 1;
else if (segment == fretwork_segment_modified_last + fretwork_segments_x) else if (segment == fretwork_segment_modified_last + fretwork_segments_x)
from_top = 1; from_top = 1;
// Very very few cases will reach this, segments are joining by the corner // Very very few cases will reach this, segments are joining by the corner
// We need to add a new segment to join by side, adding clockwise // We need to add a new segment to join by side, adding clockwise
else if (segment == fretwork_segment_modified_last + fretwork_segments_x + 1) else if (segment == fretwork_segment_modified_last + fretwork_segments_x + 1)
{ {
from_top_left = 1; from_top_left = 1;
fretwork_segment_to_add = segment - fretwork_segments_x; fretwork_segment_to_add = segment - fretwork_segments_x;
} }
else if (segment == fretwork_segment_modified_last + fretwork_segments_x - 1) else if (segment == fretwork_segment_modified_last + fretwork_segments_x - 1)
{ {
from_top_right = 1; from_top_right = 1;
fretwork_segment_to_add = segment + 1; fretwork_segment_to_add = segment + 1;
} }
else if (segment == fretwork_segment_modified_last - fretwork_segments_x - 1) else if (segment == fretwork_segment_modified_last - fretwork_segments_x - 1)
{ {
from_bottom_right = 1; from_bottom_right = 1;
fretwork_segment_to_add = segment + fretwork_segments_x; fretwork_segment_to_add = segment + fretwork_segments_x;
} }
else if (segment == fretwork_segment_modified_last - fretwork_segments_x + 1) else if (segment == fretwork_segment_modified_last - fretwork_segments_x + 1)
{ {
from_bottom_left = 1; from_bottom_left = 1;
fretwork_segment_to_add = segment -1; fretwork_segment_to_add = segment - 1;
} }
} }
take_up=segment-fretwork_segments_x; take_up = segment - fretwork_segments_x;
if (take_up<=0) val_up = SEG_NONE; if (take_up <= 0)
else val_up = fretwork_status_of_segments[take_up]; val_up = SEG_NONE;
else
val_up = fretwork_status_of_segments[take_up];
take_down=segment+fretwork_segments_x; take_down = segment + fretwork_segments_x;
if (take_down>(signed)(fretwork_segments_x*fretwork_segments_y)) val_down = SEG_NONE; if (take_down > (signed)(fretwork_segments_x * fretwork_segments_y))
else val_down = fretwork_status_of_segments[take_down]; val_down = SEG_NONE;
else
if ((segment%fretwork_segments_x)==1) val_left=SEG_NONE; val_down = fretwork_status_of_segments[take_down];
else val_left = fretwork_status_of_segments[segment-1];
if ((segment%fretwork_segments_x)==0) val_right=SEG_NONE;
else val_right = fretwork_status_of_segments[segment+1];
if ( from_left || (val_left & SEG_RIGHT) || from_bottom_left) if ((segment % fretwork_segments_x) == 1)
val_left = SEG_NONE;
else
val_left = fretwork_status_of_segments[segment - 1];
if ((segment % fretwork_segments_x) == 0)
val_right = SEG_NONE;
else
val_right = fretwork_status_of_segments[segment + 1];
if (from_left || (val_left & SEG_RIGHT) || from_bottom_left)
{ {
LEFT = 1;} LEFT = 1;
if ( from_right || (val_right & SEG_LEFT) || from_top_right) }
RIGHT=1; if (from_right || (val_right & SEG_LEFT) || from_top_right)
if ( from_top || (val_up & SEG_BOTTOM) || from_top_left) RIGHT = 1;
TOP=1; if (from_top || (val_up & SEG_BOTTOM) || from_top_left)
TOP = 1;
if (from_bottom || (val_down & SEG_TOP) || from_bottom_right) if (from_bottom || (val_down & SEG_TOP) || from_bottom_right)
BOTTOM=1; BOTTOM = 1;
if (TOP && BOTTOM && LEFT && RIGHT) if (TOP && BOTTOM && LEFT && RIGHT)
@ -425,91 +444,93 @@ static Uint8 fretwork_select_image(Uint16 segment)
return SEG_LEFT_TOP_BOTTOM; return SEG_LEFT_TOP_BOTTOM;
if (TOP && BOTTOM && RIGHT) if (TOP && BOTTOM && RIGHT)
return SEG_RIGHT_TOP_BOTTOM; return SEG_RIGHT_TOP_BOTTOM;
if (LEFT &&RIGHT) if (LEFT && RIGHT)
return SEG_LEFT_RIGHT; return SEG_LEFT_RIGHT;
if (TOP&&BOTTOM) if (TOP && BOTTOM)
return SEG_TOP_BOTTOM; return SEG_TOP_BOTTOM;
if (LEFT&&TOP) if (LEFT && TOP)
return SEG_LEFT_TOP; return SEG_LEFT_TOP;
if (LEFT&&BOTTOM) if (LEFT && BOTTOM)
return SEG_LEFT_BOTTOM; return SEG_LEFT_BOTTOM;
if (RIGHT&&TOP) if (RIGHT && TOP)
return SEG_RIGHT_TOP; return SEG_RIGHT_TOP;
if (RIGHT&&BOTTOM) if (RIGHT && BOTTOM)
return SEG_RIGHT_BOTTOM; return SEG_RIGHT_BOTTOM;
if (LEFT|RIGHT) if (LEFT | RIGHT)
return SEG_LEFT_RIGHT; return SEG_LEFT_RIGHT;
//if (TOP||BOTTOM) //if (TOP||BOTTOM)
return SEG_TOP_BOTTOM; return SEG_TOP_BOTTOM;
} }
static void fretwork_draw(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void fretwork_draw(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int x, int y ATTRIBUTE_UNUSED, unsigned int segment) SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y ATTRIBUTE_UNUSED, unsigned int segment)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
SDL_Surface * result, * temp; SDL_Surface *result, *temp;
Uint8 image; Uint8 image;
_Bool use_temp; _Bool use_temp;
use_temp=0; use_temp = 0;
if ((segment<1)|(segment>fretwork_segments_x*fretwork_segments_y)) if ((segment < 1) | (segment > fretwork_segments_x * fretwork_segments_y))
return; return;
fretwork_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y); fretwork_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y);
modification_rect.h=img_w; modification_rect.h = img_w;
modification_rect.w=img_h; modification_rect.w = img_h;
image=fretwork_select_image(segment); //select the image to display image = fretwork_select_image(segment); //select the image to display
if (fretwork_status_of_segments[segment] == image) if (fretwork_status_of_segments[segment] == image)
return; return;
fretwork_status_of_segments[segment]=image; //and write it to global table fretwork_status_of_segments[segment] = image; //and write it to global table
result=SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask, fretwork_one->format->Amask);
temp=SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel, result = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask, fretwork_one->format->Amask); fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask,
fretwork_one->format->Amask);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, fretwork_one->format->BitsPerPixel,
fretwork_one->format->Rmask, fretwork_one->format->Gmask, fretwork_one->format->Bmask,
fretwork_one->format->Amask);
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
switch(image) switch (image)
{ {
case 0: case 0:
case SEG_TOP_BOTTOM: case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_one, NULL, result, NULL); SDL_BlitSurface(fretwork_one, NULL, result, NULL);
break; break;
case SEG_LEFT_RIGHT: case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
fretwork_rotate(api, temp, fretwork_one, 1); fretwork_rotate(api, temp, fretwork_one, 1);
use_temp=1; use_temp = 1;
break; break;
case SEG_LEFT_RIGHT_TOP_BOTTOM: case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(fretwork_four, NULL, result, NULL); SDL_BlitSurface(fretwork_four, NULL, result, NULL);
break; break;
case SEG_LEFT_RIGHT_TOP: case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(fretwork_three, NULL, result, NULL); SDL_BlitSurface(fretwork_three, NULL, result, NULL);
break; break;
case SEG_LEFT_RIGHT_BOTTOM: case SEG_LEFT_RIGHT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_three); fretwork_flip_flop(api, temp, fretwork_three);
use_temp=1; use_temp = 1;
break; break;
case SEG_LEFT_TOP_BOTTOM: case SEG_LEFT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 0); fretwork_rotate(api, temp, fretwork_three, 0);
use_temp=1; use_temp = 1;
break; break;
case SEG_RIGHT_TOP_BOTTOM: case SEG_RIGHT_TOP_BOTTOM:
fretwork_rotate(api, temp, fretwork_three, 1); fretwork_rotate(api, temp, fretwork_three, 1);
use_temp=1; use_temp = 1;
break; break;
case SEG_RIGHT_TOP: case SEG_RIGHT_TOP:
@ -517,24 +538,24 @@ static void fretwork_draw(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface *
break; break;
case SEG_RIGHT_BOTTOM: case SEG_RIGHT_BOTTOM:
fretwork_rotate(api, temp, fretwork_corner,1); fretwork_rotate(api, temp, fretwork_corner, 1);
use_temp=1; use_temp = 1;
break; break;
case SEG_LEFT_TOP: case SEG_LEFT_TOP:
fretwork_rotate(api, temp, fretwork_corner, 0); fretwork_rotate(api, temp, fretwork_corner, 0);
use_temp=1; use_temp = 1;
break; break;
case SEG_LEFT_BOTTOM: case SEG_LEFT_BOTTOM:
fretwork_flip_flop(api, temp, fretwork_corner); fretwork_flip_flop(api, temp, fretwork_corner);
use_temp=1; use_temp = 1;
break; break;
} }
if (use_temp) if (use_temp)
SDL_BlitSurface(temp, NULL, result, NULL); SDL_BlitSurface(temp, NULL, result, NULL);
SDL_FreeSurface(temp); SDL_FreeSurface(temp);
SDL_BlitSurface(result, NULL, canvas, &modification_rect); SDL_BlitSurface(result, NULL, canvas, &modification_rect);
SDL_FreeSurface(result); SDL_FreeSurface(result);
@ -542,53 +563,58 @@ static void fretwork_draw(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface *
} }
static void fretwork_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void fretwork_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
fretwork_segment_modified=fretwork_get_segment(x,y); fretwork_segment_modified = fretwork_get_segment(x, y);
fretwork_draw((void *) ptr, which, canvas, last, x, y, fretwork_segment_modified); fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified);
if (fretwork_segment_modified_last>0) if (fretwork_segment_modified_last > 0)
{ {
fretwork_draw((void *) ptr, which, canvas, last, x, y, fretwork_segment_modified_last); fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified_last);
fretwork_extract_coords_from_segment(fretwork_segment_start_rectangle, &modification_rect.x, &modification_rect.y); fretwork_extract_coords_from_segment(fretwork_segment_start_rectangle, &modification_rect.x,
modification_rect.w=fretwork_update_rectangle_width*img_w; &modification_rect.y);
modification_rect.h=fretwork_update_rectangle_height*img_h; modification_rect.w = fretwork_update_rectangle_width * img_w;
modification_rect.h = fretwork_update_rectangle_height * img_h;
} }
if (fretwork_segment_to_add>0){ if (fretwork_segment_to_add > 0)
fretwork_draw((void *) ptr, which, canvas, last, x, y, fretwork_segment_to_add); {
fretwork_draw((void *) ptr, which, canvas, last, x, y, fretwork_segment_modified_last); fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_to_add);
fretwork_segment_to_add=0;} fretwork_draw((void *)ptr, which, canvas, last, x, y, fretwork_segment_modified_last);
fretwork_segment_to_add = 0;
}
fretwork_segment_modified_last=fretwork_segment_modified; fretwork_segment_modified_last = fretwork_segment_modified;
} }
void fretwork_drag(magic_api * api, int which, void fretwork_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect) {
{ int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h; int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h;
if ((x<canvas->w)&&(y<canvas->h)&&(ox<canvas->w)&&(oy<canvas->h)&&((signed)x>0)&&((signed)y>0)&&((signed)ox>0)&&((signed)oy>0))
{
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, img_w/2, fretwork_draw_wrapper);
// This should be improved, maybe passed to fretwork_draw()
start_x=min(ox,x);
end_x=max(ox,x);
start_y=min(oy,y);
end_y=max(oy,y);
segment_start=fretwork_get_segment(start_x-img_w, start_y-img_h);
segment_end=fretwork_get_segment(end_x+img_w,end_y+img_h);
x=((segment_start%fretwork_segments_x)-1)*img_w; if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
y=(int)(segment_start/fretwork_segments_x)*img_h; && ((signed)ox > 0) && ((signed)oy > 0))
w=((segment_end%fretwork_segments_x)-1)*img_w-x+img_w; {
h=(int)(segment_end/fretwork_segments_x)*img_h-y+img_h; api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, img_w / 2, fretwork_draw_wrapper);
// This should be improved, maybe passed to fretwork_draw()
start_x = min(ox, x);
end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
segment_start = fretwork_get_segment(start_x - img_w, start_y - img_h);
segment_end = fretwork_get_segment(end_x + img_w, end_y + img_h);
update_rect->x=x; x = ((segment_start % fretwork_segments_x) - 1) * img_w;
update_rect->y=y; y = (int)(segment_start / fretwork_segments_x) * img_h;
update_rect->w=w; w = ((segment_end % fretwork_segments_x) - 1) * img_w - x + img_w;
update_rect->h=h;} h = (int)(segment_end / fretwork_segments_x) * img_h - y + img_h;
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
} }

View file

@ -36,26 +36,22 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * glasstile_snd; static Mix_Chunk *glasstile_snd;
// Prototypes // Prototypes
Uint32 glasstile_api_version(void); Uint32 glasstile_api_version(void);
int glasstile_init(magic_api * api); int glasstile_init(magic_api * api);
int glasstile_get_tool_count(magic_api * api); int glasstile_get_tool_count(magic_api * api);
SDL_Surface * glasstile_get_icon(magic_api * api, int which); SDL_Surface *glasstile_get_icon(magic_api * api, int which);
char * glasstile_get_name(magic_api * api, int which); char *glasstile_get_name(magic_api * api, int which);
char * glasstile_get_description(magic_api * api, int which, int mode); char *glasstile_get_description(magic_api * api, int which, int mode);
static void do_glasstile(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_glasstile(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas, void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void glasstile_click(magic_api * api, int which, int mode, void glasstile_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void glasstile_release(magic_api * api, int which, void glasstile_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void glasstile_shutdown(magic_api * api); void glasstile_shutdown(magic_api * api);
void glasstile_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void glasstile_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int glasstile_requires_colors(magic_api * api, int which); int glasstile_requires_colors(magic_api * api, int which);
@ -63,9 +59,12 @@ void glasstile_switchin(magic_api * api, int which, int mode, SDL_Surface * canv
void glasstile_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void glasstile_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int glasstile_modes(magic_api * api, int which); int glasstile_modes(magic_api * api, int which);
Uint32 glasstile_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 glasstile_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
static int * * glasstile_hit; static int **glasstile_hit;
static int glasstile_hit_xsize; static int glasstile_hit_xsize;
static int glasstile_hit_ysize; static int glasstile_hit_ysize;
@ -74,60 +73,53 @@ int glasstile_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/glasstile.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/glasstile.ogg", api->data_directory);
api->data_directory);
glasstile_snd = Mix_LoadWAV(fname); glasstile_snd = Mix_LoadWAV(fname);
glasstile_hit = NULL; glasstile_hit = NULL;
glasstile_hit_ysize = 0; glasstile_hit_ysize = 0;
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int glasstile_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int glasstile_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * glasstile_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *glasstile_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/glasstile.png", snprintf(fname, sizeof(fname), "%s/images/magic/glasstile.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * glasstile_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *glasstile_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Glass Tile"))); return (strdup(gettext_noop("Glass Tile")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * glasstile_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) char *glasstile_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return(strdup(gettext_noop("Click and drag the mouse to put glass tile over your picture."))); return (strdup(gettext_noop("Click and drag the mouse to put glass tile over your picture.")));
else else
return(strdup(gettext_noop("Click to cover your entire picture in glass tiles."))); return (strdup(gettext_noop("Click to cover your entire picture in glass tiles.")));
} }
// Do the effect: // Do the effect:
static void do_glasstile(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, static void do_glasstile(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy, xl, xr, yt, yb; int xx, yy, xl, xr, yt, yb;
Uint8 r1, g1, b1, Uint8 r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4, r, g, b;
r2, g2, b2,
r3, g3, b3,
r4, g4, b4,
r, g, b;
Uint32 rgb; Uint32 rgb;
@ -154,66 +146,61 @@ static void do_glasstile(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * c
/* Apply the effect: */ /* Apply the effect: */
for (yy = -GT_SIZE; yy < GT_SIZE; yy = yy + 2) for (yy = -GT_SIZE; yy < GT_SIZE; yy = yy + 2)
{
for (xx = -GT_SIZE; xx < GT_SIZE; xx = xx + 2)
{ {
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, for (xx = -GT_SIZE; xx < GT_SIZE; xx = xx + 2)
&r1, &g1, &b1); {
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy), last->format, SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1, &b1);
&r2, &g2, &b2); SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy), last->format, &r2, &g2, &b2);
SDL_GetRGB(api->getpixel(last, x + xx, y + yy + 1), last->format, SDL_GetRGB(api->getpixel(last, x + xx, y + yy + 1), last->format, &r3, &g3, &b3);
&r3, &g3, &b3); SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy + 1), last->format, &r4, &g4, &b4);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy + 1), last->format,
&r4, &g4, &b4);
r = (r1 + r2 + r3 + r4) >> 2; r = (r1 + r2 + r3 + r4) >> 2;
g = (g1 + g2 + g3 + g4) >> 2; g = (g1 + g2 + g3 + g4) >> 2;
b = (b1 + b2 + b3 + b4) >> 2; b = (b1 + b2 + b3 + b4) >> 2;
if (xx <= -GT_SIZE + 2 || yy == -GT_SIZE + 2) if (xx <= -GT_SIZE + 2 || yy == -GT_SIZE + 2)
{ {
r = min(255, r + 64); r = min(255, r + 64);
g = min(255, g + 64); g = min(255, g + 64);
b = min(255, b + 64); b = min(255, b + 64);
} }
else if (xx >= GT_SIZE - 3|| yy >= GT_SIZE - 3) else if (xx >= GT_SIZE - 3 || yy >= GT_SIZE - 3)
{ {
r = max(0, r - 64); r = max(0, r - 64);
g = max(0, g - 64); g = max(0, g - 64);
b = max(0, b - 64); b = max(0, b - 64);
} }
rgb = SDL_MapRGB(canvas->format, r, g, b); rgb = SDL_MapRGB(canvas->format, r, g, b);
xl = (xx / 3) - GT_SIZE + (GT_SIZE / 3); xl = (xx / 3) - GT_SIZE + (GT_SIZE / 3);
xr = (xx / 3) + (GT_SIZE * 2) / 3; xr = (xx / 3) + (GT_SIZE * 2) / 3;
yt = (yy / 3) - GT_SIZE + (GT_SIZE / 3); yt = (yy / 3) - GT_SIZE + (GT_SIZE / 3);
yb = (yy / 3) + (GT_SIZE * 2) / 3; yb = (yy / 3) + (GT_SIZE * 2) / 3;
api->putpixel(canvas, x + xl, y + yt, rgb); api->putpixel(canvas, x + xl, y + yt, rgb);
api->putpixel(canvas, x + xx / 2, y + yt, rgb); api->putpixel(canvas, x + xx / 2, y + yt, rgb);
api->putpixel(canvas, x + xr, y + yt, rgb); api->putpixel(canvas, x + xr, y + yt, rgb);
api->putpixel(canvas, x + xl, y + yy / 2, rgb); api->putpixel(canvas, x + xl, y + yy / 2, rgb);
api->putpixel(canvas, x + xr, y + yy / 2, rgb); api->putpixel(canvas, x + xr, y + yy / 2, rgb);
api->putpixel(canvas, x + xl, y + yb, rgb); api->putpixel(canvas, x + xl, y + yb, rgb);
api->putpixel(canvas, x + xx / 2, y + yb, rgb); api->putpixel(canvas, x + xx / 2, y + yb, rgb);
api->putpixel(canvas, x + xr, y + yb, rgb); api->putpixel(canvas, x + xr, y + yb, rgb);
/* Center */ /* Center */
api->putpixel(canvas, x + xx / 2, y + yy / 2, rgb); api->putpixel(canvas, x + xx / 2, y + yy / 2, rgb);
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas, void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_glasstile); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_glasstile);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
@ -246,21 +233,20 @@ void glasstile_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void glasstile_click(magic_api * api, int which, int mode, void glasstile_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
int xx, yy; int xx, yy;
if (glasstile_hit == NULL) if (glasstile_hit == NULL)
{ {
glasstile_hit_ysize = (canvas->h / GT_SIZE) + 1; glasstile_hit_ysize = (canvas->h / GT_SIZE) + 1;
glasstile_hit_xsize = (canvas->w / GT_SIZE) + 1; glasstile_hit_xsize = (canvas->w / GT_SIZE) + 1;
glasstile_hit = (int * *) malloc(sizeof(int *) * glasstile_hit_ysize); glasstile_hit = (int * *)malloc(sizeof(int *) * glasstile_hit_ysize);
for (yy = 0; yy < glasstile_hit_ysize; yy++) for (yy = 0; yy < glasstile_hit_ysize; yy++)
glasstile_hit[yy] = (int *) malloc(sizeof(int) * glasstile_hit_xsize); glasstile_hit[yy] = (int *)malloc(sizeof(int) * glasstile_hit_xsize);
} }
for (yy = 0; yy < glasstile_hit_ysize; yy++) for (yy = 0; yy < glasstile_hit_ysize; yy++)
for (xx = 0; xx < glasstile_hit_xsize; xx++) for (xx = 0; xx < glasstile_hit_xsize; xx++)
@ -269,24 +255,24 @@ void glasstile_click(magic_api * api, int which, int mode,
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
glasstile_drag(api, which, canvas, last, x, y, x, y, update_rect); glasstile_drag(api, which, canvas, last, x, y, x, y, update_rect);
else if (mode == MODE_FULLSCREEN) else if (mode == MODE_FULLSCREEN)
{ {
for (y = 0; y < canvas->h; y = y + GT_SIZE) for (y = 0; y < canvas->h; y = y + GT_SIZE)
for (x = 0; x < canvas->w; x = x + GT_SIZE) for (x = 0; x < canvas->w; x = x + GT_SIZE)
do_glasstile(api, which, canvas, last, x, y); do_glasstile(api, which, canvas, last, x, y);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
/* FIXME: Play sfx */ /* FIXME: Play sfx */
} }
} }
// Affect the canvas on release: // Affect the canvas on release:
void glasstile_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void glasstile_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -297,20 +283,21 @@ void glasstile_shutdown(magic_api * api ATTRIBUTE_UNUSED)
if (glasstile_snd != NULL) if (glasstile_snd != NULL)
Mix_FreeChunk(glasstile_snd); Mix_FreeChunk(glasstile_snd);
if (glasstile_hit != NULL) if (glasstile_hit != NULL)
{
for (y = 0; y < glasstile_hit_ysize; y++)
{ {
if (glasstile_hit[y] != NULL) for (y = 0; y < glasstile_hit_ysize; y++)
free(glasstile_hit[y]); {
if (glasstile_hit[y] != NULL)
free(glasstile_hit[y]);
}
free(glasstile_hit);
} }
free(glasstile_hit);
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void glasstile_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void glasstile_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -320,15 +307,17 @@ int glasstile_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIB
return 0; return 0;
} }
void glasstile_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void glasstile_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void glasstile_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void glasstile_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int glasstile_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int glasstile_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT | MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }

View file

@ -30,39 +30,34 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* for RAND_MAX */ #include <stdlib.h> /* for RAND_MAX */
#include "tp_magic_api.h" #include "tp_magic_api.h"
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
/* Our globals: */ /* Our globals: */
static Mix_Chunk * grass_snd; static Mix_Chunk *grass_snd;
static Uint8 grass_r, grass_g, grass_b; static Uint8 grass_r, grass_g, grass_b;
static SDL_Surface * img_grass; static SDL_Surface *img_grass;
// Prototypes // Prototypes
int grass_init(magic_api * api); int grass_init(magic_api * api);
Uint32 grass_api_version(void); Uint32 grass_api_version(void);
int grass_get_tool_count(magic_api * api); int grass_get_tool_count(magic_api * api);
SDL_Surface * grass_get_icon(magic_api * api, int which); SDL_Surface *grass_get_icon(magic_api * api, int which);
char * grass_get_name(magic_api * api, int which); char *grass_get_name(magic_api * api, int which);
char * grass_get_description(magic_api * api, int which, int mode); char *grass_get_description(magic_api * api, int which, int mode);
void grass_drag(magic_api * api, int which, SDL_Surface * canvas, void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void grass_click(magic_api * api, int which, int mode, void grass_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void grass_release(magic_api * api, int which, void grass_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void grass_shutdown(magic_api * api); void grass_shutdown(magic_api * api);
void grass_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void grass_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int grass_requires_colors(magic_api * api, int which); int grass_requires_colors(magic_api * api, int which);
static void do_grass(void * ptr, int which, static void do_grass(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
static int log2int(int x); static int log2int(int x);
void grass_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void grass_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void grass_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void grass_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
@ -74,81 +69,90 @@ int grass_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/grass.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/grass.wav", api->data_directory);
api->data_directory);
grass_snd = Mix_LoadWAV(fname); grass_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/grass_data.png", snprintf(fname, sizeof(fname), "%s/images/magic/grass_data.png", api->data_directory);
api->data_directory);
img_grass = IMG_Load(fname); img_grass = IMG_Load(fname);
return(1); return (1);
} }
Uint32 grass_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 grass_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int grass_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int grass_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * grass_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *grass_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/grass.png", snprintf(fname, sizeof(fname), "%s/images/magic/grass.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * grass_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *grass_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Grass"))); return (strdup(gettext_noop("Grass")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * grass_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *grass_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag to draw grass. Dont forget the dirt!"))); return (strdup(gettext_noop("Click and drag to draw grass. Dont forget the dirt!")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void grass_drag(magic_api * api, int which, SDL_Surface * canvas, void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 4, do_grass); api->line((void *)api, which, canvas, last, ox, oy, x, y, 4, do_grass);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 64; update_rect->x = ox - 64;
update_rect->y = oy - 64; update_rect->y = oy - 64;
update_rect->w = 128; update_rect->w = 128;
update_rect->h = 192; update_rect->h = 192;
api->playsound(grass_snd, api->playsound(grass_snd, (x * 255) / canvas->w, (y * 255) / canvas->h);
(x * 255) / canvas->w, (y * 255) / canvas->h);
} }
// Affect the canvas on click: // Affect the canvas on click:
void grass_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void grass_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
grass_drag(api, which, canvas, last, x, y, x, y, update_rect); grass_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void grass_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void grass_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -173,12 +177,12 @@ int grass_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 1; return 1;
} }
static void do_grass(void * ptr, int which ATTRIBUTE_UNUSED, static void do_grass(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
// grass color: 82,180,17 // grass color: 82,180,17
static int bucket; static int bucket;
double tmp_red, tmp_green, tmp_blue; double tmp_red, tmp_green, tmp_blue;
@ -187,92 +191,79 @@ static void do_grass(void * ptr, int which ATTRIBUTE_UNUSED,
if (!api->button_down()) if (!api->button_down())
bucket = 0; bucket = 0;
bucket += (3.5 + (rand() / (double) RAND_MAX)) * 7.0; bucket += (3.5 + (rand() / (double)RAND_MAX)) * 7.0;
while (bucket >= 0) while (bucket >= 0)
{
int rank =
log2int(((double) y / canvas->h) *
(0.99 + (rand() / (double) RAND_MAX)) * 64);
int ah = 1 << rank;
bucket -= ah;
src.x = (rand() % 4) * 64;
src.y = ah;
src.w = 64;
src.h = ah;
dest.x = x - 32;
dest.y = y - 30 + (int) ((rand() / (double) RAND_MAX) * 30);
tmp_red =
api->sRGB_to_linear(grass_r) * 2.0 +
(rand() / (double) RAND_MAX);
tmp_green =
api->sRGB_to_linear(grass_g) * 2.0 +
(rand() / (double) RAND_MAX);
tmp_blue =
api->sRGB_to_linear(grass_b) * 2.0 +
api->sRGB_to_linear(17);
for (yy = 0; yy < ah; yy++)
{ {
for (xx = 0; xx < 64; xx++) int rank = log2int(((double)y / canvas->h) * (0.99 + (rand() / (double)RAND_MAX)) * 64);
{ int ah = 1 << rank;
double rd, gd, bd;
SDL_GetRGBA(api->getpixel(img_grass, xx + src.x, yy + src.y), bucket -= ah;
img_grass->format, &r, &g, &b, &a); src.x = (rand() % 4) * 64;
src.y = ah;
src.w = 64;
src.h = ah;
rd = api->sRGB_to_linear(r) * 8.0 + tmp_red; dest.x = x - 32;
rd = rd * (a / 255.0) / 11.0; dest.y = y - 30 + (int)((rand() / (double)RAND_MAX) * 30);
gd = api->sRGB_to_linear(g) * 8.0 + tmp_green;
gd = gd * (a / 255.0) / 11.0;
bd = api->sRGB_to_linear(b) * 8.0 + tmp_blue;
bd = bd * (a / 255.0) / 11.0;
SDL_GetRGB(api->getpixel(canvas, xx + dest.x, yy + dest.y), tmp_red = api->sRGB_to_linear(grass_r) * 2.0 + (rand() / (double)RAND_MAX);
canvas->format, &r, &g, &b); tmp_green = api->sRGB_to_linear(grass_g) * 2.0 + (rand() / (double)RAND_MAX);
tmp_blue = api->sRGB_to_linear(grass_b) * 2.0 + api->sRGB_to_linear(17);
r = for (yy = 0; yy < ah; yy++)
api->linear_to_sRGB(api->sRGB_to_linear(r) * (1.0 - a / 255.0) + {
rd); for (xx = 0; xx < 64; xx++)
g = {
api->linear_to_sRGB(api->sRGB_to_linear(g) * (1.0 - a / 255.0) + double rd, gd, bd;
gd);
b =
api->linear_to_sRGB(api->sRGB_to_linear(b) * (1.0 - a / 255.0) +
bd);
api->putpixel(canvas, xx + dest.x, yy + dest.y, SDL_GetRGBA(api->getpixel(img_grass, xx + src.x, yy + src.y), img_grass->format, &r, &g, &b, &a);
SDL_MapRGB(canvas->format, r, g, b));
} rd = api->sRGB_to_linear(r) * 8.0 + tmp_red;
rd = rd * (a / 255.0) / 11.0;
gd = api->sRGB_to_linear(g) * 8.0 + tmp_green;
gd = gd * (a / 255.0) / 11.0;
bd = api->sRGB_to_linear(b) * 8.0 + tmp_blue;
bd = bd * (a / 255.0) / 11.0;
SDL_GetRGB(api->getpixel(canvas, xx + dest.x, yy + dest.y), canvas->format, &r, &g, &b);
r = api->linear_to_sRGB(api->sRGB_to_linear(r) * (1.0 - a / 255.0) + rd);
g = api->linear_to_sRGB(api->sRGB_to_linear(g) * (1.0 - a / 255.0) + gd);
b = api->linear_to_sRGB(api->sRGB_to_linear(b) * (1.0 - a / 255.0) + bd);
api->putpixel(canvas, xx + dest.x, yy + dest.y, SDL_MapRGB(canvas->format, r, g, b));
}
}
} }
}
} }
// this one rounds down // this one rounds down
static int log2int(int x) static int log2int(int x)
{ {
int y = 0; int y = 0;
if (x <= 1) if (x <= 1)
return 0; return 0;
x >>= 1; x >>= 1;
while (x) while (x)
{ {
x >>= 1; x >>= 1;
y++; y++;
} }
return y; return y;
} }
void grass_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void grass_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void grass_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void grass_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int grass_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int grass_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -16,55 +16,51 @@
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
enum { enum
{
TOOL_HALFTONE, TOOL_HALFTONE,
NUM_TOOLS NUM_TOOLS
}; };
const char * snd_filenames[NUM_TOOLS] = { const char *snd_filenames[NUM_TOOLS] = {
"halftone.wav", "halftone.wav",
}; };
const char * icon_filenames[NUM_TOOLS] = { const char *icon_filenames[NUM_TOOLS] = {
"halftone.png", "halftone.png",
}; };
const char * names[NUM_TOOLS] = { const char *names[NUM_TOOLS] = {
gettext_noop("Halftone"), gettext_noop("Halftone"),
}; };
const char * descs[NUM_TOOLS] = { const char *descs[NUM_TOOLS] = {
gettext_noop("Click and drag to turn your drawing into a newspaper."), gettext_noop("Click and drag to turn your drawing into a newspaper."),
}; };
Mix_Chunk * snd_effect[NUM_TOOLS]; Mix_Chunk *snd_effect[NUM_TOOLS];
static SDL_Surface * canvas_backup, * square; static SDL_Surface *canvas_backup, *square;
/* Function Prototypes: */ /* Function Prototypes: */
void halftone_drag(magic_api * api, int which, SDL_Surface * canvas, void halftone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect); void halftone_line_callback(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void halftone_line_callback(void * ptr, int which,
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y);
Uint32 halftone_api_version(void); Uint32 halftone_api_version(void);
int halftone_init(magic_api * api); int halftone_init(magic_api * api);
int halftone_get_tool_count(magic_api * api); int halftone_get_tool_count(magic_api * api);
SDL_Surface * halftone_get_icon(magic_api * api, int which); SDL_Surface *halftone_get_icon(magic_api * api, int which);
char * halftone_get_name(magic_api * api, int which); char *halftone_get_name(magic_api * api, int which);
char * halftone_get_description(magic_api * api, int which, int mode); char *halftone_get_description(magic_api * api, int which, int mode);
int halftone_requires_colors(magic_api * api, int which); int halftone_requires_colors(magic_api * api, int which);
int halftone_modes(magic_api * api, int which); int halftone_modes(magic_api * api, int which);
void halftone_shutdown(magic_api * api); void halftone_shutdown(magic_api * api);
void halftone_click(magic_api * api, int which, int mode, void halftone_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void halftone_release(magic_api * api, int which, void halftone_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void halftone_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void halftone_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void halftone_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void halftone_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void halftone_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void halftone_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
@ -72,7 +68,7 @@ void halftone_rgb2cmyk(Uint8 r, Uint8 g, Uint8 b, float cmyk[]);
Uint32 halftone_api_version(void) Uint32 halftone_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
int halftone_init(magic_api * api) int halftone_init(magic_api * api)
@ -84,58 +80,56 @@ int halftone_init(magic_api * api)
square = NULL; square = NULL;
for (i = 0; i < NUM_TOOLS; i++) for (i = 0; i < NUM_TOOLS; i++)
{ {
snprintf(fname, sizeof(fname), snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, snd_filenames[i]);
"%s/sounds/magic/%s",
api->data_directory, snd_filenames[i]);
snd_effect[i] = Mix_LoadWAV(fname); snd_effect[i] = Mix_LoadWAV(fname);
if (snd_effect[i] == NULL) { if (snd_effect[i] == NULL)
SDL_FreeSurface(canvas_backup); {
SDL_FreeSurface(square); SDL_FreeSurface(canvas_backup);
return(0); SDL_FreeSurface(square);
return (0);
}
} }
}
return(1); return (1);
} }
int halftone_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int halftone_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
SDL_Surface * halftone_get_icon(magic_api * api, int which) SDL_Surface *halftone_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/%s", snprintf(fname, sizeof(fname), "%s/images/magic/%s", api->data_directory, icon_filenames[which]);
api->data_directory, icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * halftone_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *halftone_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
const char * our_name_english; const char *our_name_english;
const char * our_name_localized; const char *our_name_localized;
our_name_english = names[which]; our_name_english = names[which];
our_name_localized = gettext_noop(our_name_english); our_name_localized = gettext_noop(our_name_english);
return(strdup(our_name_localized)); return (strdup(our_name_localized));
} }
char * halftone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *halftone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
const char * our_desc_english; const char *our_desc_english;
const char * our_desc_localized; const char *our_desc_localized;
our_desc_english = descs[which]; our_desc_english = descs[which];
our_desc_localized = gettext_noop(our_desc_english); our_desc_localized = gettext_noop(our_desc_english);
return(strdup(our_desc_localized)); return (strdup(our_desc_localized));
} }
int halftone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int halftone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
@ -160,33 +154,42 @@ void halftone_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
void halftone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void halftone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
halftone_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); halftone_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
void halftone_drag(magic_api * api, int which, SDL_Surface * canvas, void halftone_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, snapshot, api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 4, halftone_line_callback);
ox, oy, x, y, 4, halftone_line_callback);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
update_rect->w = (x + 16) - update_rect->x; update_rect->w = (x + 16) - update_rect->x;
update_rect->h = (y + 16) - update_rect->h; update_rect->h = (y + 16) - update_rect->h;
api->playsound(snd_effect[which], api->playsound(snd_effect[which], (x * 255) / canvas->w, // pan
(x * 255) / canvas->w, // pan 255); // distance
255); // distance
} }
enum { enum
{
CHAN_CYAN, CHAN_CYAN,
CHAN_MAGENTA, CHAN_MAGENTA,
CHAN_YELLOW, CHAN_YELLOW,
@ -195,10 +198,10 @@ enum {
}; };
Uint8 chan_colors[NUM_CHANS][3] = { Uint8 chan_colors[NUM_CHANS][3] = {
{ 0, 255, 255 }, {0, 255, 255},
{ 255, 0, 255 }, {255, 0, 255},
{ 255, 255, 0 }, {255, 255, 0},
{ 0, 0, 0 } {0, 0, 0}
}; };
int chan_angles[NUM_CHANS] = { int chan_angles[NUM_CHANS] = {
@ -209,28 +212,25 @@ int chan_angles[NUM_CHANS] = {
}; };
void halftone_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void halftone_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void halftone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, void halftone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED,
Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
void halftone_line_callback(void * ptr, int which ATTRIBUTE_UNUSED, void halftone_line_callback(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
Uint8 r, g, b, or, og, ob; Uint8 r, g, b, or, og, ob;
Uint32 total_r, total_g, total_b; Uint32 total_r, total_g, total_b;
Uint32 pixel; Uint32 pixel;
int xx, yy, xxx, yyy, channel, ox, oy, sqx, sqy; int xx, yy, xxx, yyy, channel, ox, oy, sqx, sqy;
SDL_Rect dest; SDL_Rect dest;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
float cmyk[4]; float cmyk[4];
pixel = SDL_MapRGB(square->format, 255, 255, 255); pixel = SDL_MapRGB(square->format, 255, 255, 255);
@ -240,62 +240,77 @@ void halftone_line_callback(void * ptr, int which ATTRIBUTE_UNUSED,
x = ((x / 8) - 1) * 8; x = ((x / 8) - 1) * 8;
y = ((y / 8) - 1) * 8; y = ((y / 8) - 1) * 8;
if (api->touched(x, y)) { return; } if (api->touched(x, y))
{
for (xx = 0; xx < 16; xx = xx + 4) { return;
for (yy = 0; yy < 16; yy = yy + 4) { }
/* Get avg color around the mouse */
total_r = total_g = total_b = 0; for (xx = 0; xx < 16; xx = xx + 4)
for (xxx = 0; xxx < 4; xxx++) { {
for (yyy = 0; yyy < 4; yyy++) { for (yy = 0; yy < 16; yy = yy + 4)
SDL_GetRGB(api->getpixel(canvas_backup, x + xx + xxx, y + yy + yyy), canvas_backup->format, &r, &g, &b); {
total_r += r; /* Get avg color around the mouse */
total_g += g; total_r = total_g = total_b = 0;
total_b += b; for (xxx = 0; xxx < 4; xxx++)
} {
} for (yyy = 0; yyy < 4; yyy++)
total_r /= 16; {
total_g /= 16; SDL_GetRGB(api->getpixel(canvas_backup, x + xx + xxx, y + yy + yyy), canvas_backup->format, &r, &g,
total_b /= 16; &b);
total_r += r;
/* Convert to CMYK values */ total_g += g;
halftone_rgb2cmyk(total_r, total_g, total_b, cmyk); total_b += b;
}
/* Draw C, M, Y and K blobs into our 'square' surface */ }
for (channel = 0; channel < NUM_CHANS; channel++) { total_r /= 16;
r = chan_colors[channel][0]; total_g /= 16;
g = chan_colors[channel][1]; total_b /= 16;
b = chan_colors[channel][2];
/* Convert to CMYK values */
for (xxx = 0; xxx < 8; xxx++) { halftone_rgb2cmyk(total_r, total_g, total_b, cmyk);
for (yyy = 0; yyy < 8; yyy++) {
/* A circle blob, radius based upon channel (C, M, Y or K) strength for this color */ /* Draw C, M, Y and K blobs into our 'square' surface */
for (channel = 0; channel < NUM_CHANS; channel++)
/* FIXME: Base it upon this channel's angle! -bjk 2011.07.17 */ {
ox = xxx; r = chan_colors[channel][0];
oy = yyy; g = chan_colors[channel][1];
b = chan_colors[channel][2];
sqx = (xx + ox) % 16;
sqy = (yy + oy) % 16; for (xxx = 0; xxx < 8; xxx++)
{
if (api->in_circle(xxx - 4, yyy - 4, cmyk[channel] * 6.0)) { for (yyy = 0; yyy < 8; yyy++)
SDL_GetRGB(api->getpixel(square, sqx, sqy), square->format, &or, &og, &ob); {
/* A circle blob, radius based upon channel (C, M, Y or K) strength for this color */
if (or == 255 && og == 255 && ob == 255) {
/* If it's just white, put full color down */ /* FIXME: Base it upon this channel's angle! -bjk 2011.07.17 */
pixel = SDL_MapRGB(square->format, r, g, b); ox = xxx;
} else { oy = yyy;
/* Otherwise, blend a little */
pixel = SDL_MapRGB(square->format, (r + or) / 2, (g + og) / 2, (b + ob) / 2); sqx = (xx + ox) % 16;
} sqy = (yy + oy) % 16;
api->putpixel(square, sqx, sqy, pixel); if (api->in_circle(xxx - 4, yyy - 4, cmyk[channel] * 6.0))
} {
} SDL_GetRGB(api->getpixel(square, sqx, sqy), square->format, &or, &og, &ob);
}
} if (or == 255 && og == 255 && ob == 255)
{
/* If it's just white, put full color down */
pixel = SDL_MapRGB(square->format, r, g, b);
}
else
{
/* Otherwise, blend a little */
pixel = SDL_MapRGB(square->format, (r + or) / 2, (g + og) / 2, (b + ob) / 2);
}
api->putpixel(square, sqx, sqy, pixel);
}
}
}
}
}
} }
}
dest.x = x; dest.x = x;
dest.y = y; dest.y = y;
@ -303,22 +318,25 @@ void halftone_line_callback(void * ptr, int which ATTRIBUTE_UNUSED,
SDL_BlitSurface(square, NULL, canvas, &dest); SDL_BlitSurface(square, NULL, canvas, &dest);
} }
void halftone_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, void halftone_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{ {
if (canvas_backup == NULL) if (canvas_backup == NULL)
canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, api->canvas_w, api->canvas_h, canvas->format->BitsPerPixel, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, api->canvas_w, api->canvas_h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
if (square == NULL) if (square == NULL)
square = SDL_CreateRGBSurface(SDL_SWSURFACE, 16, 16, canvas->format->BitsPerPixel, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); square =
SDL_CreateRGBSurface(SDL_SWSURFACE, 16, 16, canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
/* FIXME: What to do if they come back NULL!? :( */ /* FIXME: What to do if they come back NULL!? :( */
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
} }
void halftone_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void halftone_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
@ -331,25 +349,25 @@ void halftone_rgb2cmyk(Uint8 r, Uint8 g, Uint8 b, float cmyk[])
by Alexei Kourbatov <alexei@kourbatov.com> */ by Alexei Kourbatov <alexei@kourbatov.com> */
if (r == 0 && g == 0 && b == 0) if (r == 0 && g == 0 && b == 0)
{ {
/* Black */ /* Black */
c = 0.0; c = 0.0;
m = 0.0; m = 0.0;
y = 0.0; y = 0.0;
k = 1.0; k = 1.0;
} }
else else
{ {
c = 1.0 - (((float) r) / 255.0); c = 1.0 - (((float)r) / 255.0);
m = 1.0 - (((float) g) / 255.0); m = 1.0 - (((float)g) / 255.0);
y = 1.0 - (((float) b) / 255.0); y = 1.0 - (((float)b) / 255.0);
mincmy = min(c, min(m, y)); mincmy = min(c, min(m, y));
c = (c - mincmy) / (1.0 - mincmy); c = (c - mincmy) / (1.0 - mincmy);
m = (m - mincmy) / (1.0 - mincmy); m = (m - mincmy) / (1.0 - mincmy);
y = (y - mincmy) / (1.0 - mincmy); y = (y - mincmy) / (1.0 - mincmy);
k = mincmy; k = mincmy;
} }
cmyk[0] = c; cmyk[0] = c;
cmyk[1] = m; cmyk[1] = m;

View file

@ -35,12 +35,13 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * kalidescope_snd; static Mix_Chunk *kalidescope_snd;
static Uint8 kalidescope_r, kalidescope_g, kalidescope_b; static Uint8 kalidescope_r, kalidescope_g, kalidescope_b;
static int square_size = 128; static int square_size = 128;
enum { enum
{
KAL_UD, KAL_UD,
KAL_LR, KAL_LR,
KAL_BOTH, KAL_BOTH,
@ -49,7 +50,7 @@ enum {
KAL_COUNT KAL_COUNT
}; };
char * kal_icon_names[KAL_COUNT] = { char *kal_icon_names[KAL_COUNT] = {
"symmetric_updown.png", "symmetric_updown.png",
"symmetric_leftright.png", "symmetric_leftright.png",
"kalidescope.png", "kalidescope.png",
@ -62,20 +63,16 @@ char * kal_icon_names[KAL_COUNT] = {
Uint32 kalidescope_api_version(void); Uint32 kalidescope_api_version(void);
int kalidescope_init(magic_api * api); int kalidescope_init(magic_api * api);
int kalidescope_get_tool_count(magic_api * api); int kalidescope_get_tool_count(magic_api * api);
SDL_Surface * kalidescope_get_icon(magic_api * api, int which); SDL_Surface *kalidescope_get_icon(magic_api * api, int which);
char * kalidescope_get_name(magic_api * api, int which); char *kalidescope_get_name(magic_api * api, int which);
char * kalidescope_get_description(magic_api * api, int which, int mode); char *kalidescope_get_description(magic_api * api, int which, int mode);
static void do_kalidescope(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_kalidescope(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas, void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void kalidescope_click(magic_api * api, int which, int mode, void kalidescope_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void kalidescope_release(magic_api * api, int which, void kalidescope_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void kalidescope_shutdown(magic_api * api); void kalidescope_shutdown(magic_api * api);
int kalidescope_requires_colors(magic_api * api, int which); int kalidescope_requires_colors(magic_api * api, int which);
void kalidescope_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void kalidescope_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -83,120 +80,144 @@ void kalidescope_switchin(magic_api * api, int which, int mode, SDL_Surface * ca
void kalidescope_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void kalidescope_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int kalidescope_modes(magic_api * api, int which); int kalidescope_modes(magic_api * api, int which);
Uint32 kalidescope_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 kalidescope_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
int kalidescope_init(magic_api * api) int kalidescope_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/kaleidoscope.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/kaleidoscope.ogg", api->data_directory);
api->data_directory);
kalidescope_snd = Mix_LoadWAV(fname); kalidescope_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int kalidescope_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int kalidescope_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(KAL_COUNT); return (KAL_COUNT);
} }
// Load our icons: // Load our icons:
SDL_Surface * kalidescope_get_icon(magic_api * api, int which) SDL_Surface *kalidescope_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/%s", snprintf(fname, sizeof(fname), "%s/images/magic/%s", api->data_directory, kal_icon_names[which]);
api->data_directory, kal_icon_names[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * kalidescope_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *kalidescope_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == KAL_LR) { if (which == KAL_LR)
return(strdup(gettext_noop("Symmetric Left/Right"))); {
} else if (which == KAL_UD) { return (strdup(gettext_noop("Symmetric Left/Right")));
return(strdup(gettext_noop("Symmetric Up/Down"))); }
} else if (which == KAL_PATTERN) { else if (which == KAL_UD)
return(strdup(gettext_noop("Pattern"))); {
} else if (which == KAL_TILES) { return (strdup(gettext_noop("Symmetric Up/Down")));
return(strdup(gettext_noop("Tiles"))); }
} else { /* KAL_BOTH */ else if (which == KAL_PATTERN)
return(strdup(gettext_noop("Kaleidoscope"))); {
} return (strdup(gettext_noop("Pattern")));
}
else if (which == KAL_TILES)
{
return (strdup(gettext_noop("Tiles")));
}
else
{ /* KAL_BOTH */
return (strdup(gettext_noop("Kaleidoscope")));
}
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * kalidescope_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *kalidescope_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (which == KAL_LR) { if (which == KAL_LR)
return(strdup(gettext_noop("Click and drag the mouse to draw with two brushes that are symmetric across the left and right of your picture."))); {
} else if (which == KAL_UD) { return (strdup
return(strdup(gettext_noop("Click and drag the mouse to draw with two brushes that are symmetric across the top and bottom of your picture."))); (gettext_noop
} else if (which == KAL_PATTERN) { ("Click and drag the mouse to draw with two brushes that are symmetric across the left and right of your picture.")));
return(strdup(gettext_noop("Click and drag the mouse to draw a pattern across the picture."))); }
} else if (which == KAL_TILES) { else if (which == KAL_UD)
return(strdup(gettext_noop("Click and drag the mouse to draw a pattern that is symmetric across the picture."))); {
} else { /* KAL_BOTH */ return (strdup
return(strdup(gettext_noop("Click and drag the mouse to draw with symmetric brushes (a kaleidoscope)."))); (gettext_noop
} ("Click and drag the mouse to draw with two brushes that are symmetric across the top and bottom of your picture.")));
}
else if (which == KAL_PATTERN)
{
return (strdup(gettext_noop("Click and drag the mouse to draw a pattern across the picture.")));
}
else if (which == KAL_TILES)
{
return (strdup(gettext_noop("Click and drag the mouse to draw a pattern that is symmetric across the picture.")));
}
else
{ /* KAL_BOTH */
return (strdup(gettext_noop("Click and drag the mouse to draw with symmetric brushes (a kaleidoscope).")));
}
} }
// Do the effect: // Do the effect:
static void do_kalidescope(void * ptr, int which, SDL_Surface * canvas, static void do_kalidescope(void *ptr, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
int i, j; int i, j;
Uint32 colr; Uint32 colr;
colr = SDL_MapRGB(canvas->format, colr = SDL_MapRGB(canvas->format, kalidescope_r, kalidescope_g, kalidescope_b);
kalidescope_r,
kalidescope_g,
kalidescope_b);
for (yy = -8; yy < 8; yy++) for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{ {
if (api->in_circle(xx, yy, 8)) for (xx = -8; xx < 8; xx++)
{ {
api->putpixel(canvas, x + xx, y + yy, colr); if (api->in_circle(xx, yy, 8))
{
api->putpixel(canvas, x + xx, y + yy, colr);
if (which == KAL_LR || which == KAL_BOTH) { if (which == KAL_LR || which == KAL_BOTH)
api->putpixel(canvas, canvas->w - 1 - x + xx, y + yy, colr); {
api->putpixel(canvas, canvas->w - 1 - x + xx, y + yy, colr);
if (which == KAL_BOTH) { if (which == KAL_BOTH)
api->putpixel(canvas, canvas->w - 1 - x + xx, canvas->h - 1 - y + yy, colr); {
} api->putpixel(canvas, canvas->w - 1 - x + xx, canvas->h - 1 - y + yy, colr);
}
}
if (which == KAL_UD || which == KAL_BOTH)
{
api->putpixel(canvas, x + xx, canvas->h - 1 - y + yy, colr);
}
if (which == KAL_PATTERN || which == KAL_TILES)
{
for (i = 0; i <= canvas->w; i += square_size)
for (j = 0; j <= canvas->h; j += square_size)
{
api->putpixel(canvas, i + xx + x % square_size, j + yy + y % square_size, colr);
if (which == KAL_TILES)
api->putpixel(canvas, i + yy + y % square_size, j + xx + x % square_size, colr);
}
}
}
} }
if (which == KAL_UD || which == KAL_BOTH) {
api->putpixel(canvas, x + xx, canvas->h - 1 - y + yy, colr);
}
if (which == KAL_PATTERN || which == KAL_TILES) {
for (i = 0; i <= canvas->w; i += square_size)
for (j = 0; j <= canvas->h; j += square_size){
api->putpixel(canvas, i + xx + x % square_size, j + yy + y % square_size, colr);
if (which == KAL_TILES)
api->putpixel(canvas, i + yy + y % square_size, j + xx + x % square_size, colr);
}
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas, void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_kalidescope); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_kalidescope);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
@ -208,17 +229,15 @@ void kalidescope_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void kalidescope_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void kalidescope_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
kalidescope_drag(api, which, canvas, last, x, y, x, y, update_rect); kalidescope_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void kalidescope_release(magic_api * api, int which ATTRIBUTE_UNUSED, void kalidescope_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
api->stopsound(); api->stopsound();
} }
@ -244,17 +263,17 @@ int kalidescope_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTR
return 1; return 1;
} }
void kalidescope_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void kalidescope_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void kalidescope_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void kalidescope_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int kalidescope_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int kalidescope_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -38,25 +38,21 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * light1_snd, * light2_snd; static Mix_Chunk *light1_snd, *light2_snd;
static float light_h, light_s, light_v; static float light_h, light_s, light_v;
Uint32 light_api_version(void); Uint32 light_api_version(void);
int light_init(magic_api * api); int light_init(magic_api * api);
int light_get_tool_count(magic_api * api); int light_get_tool_count(magic_api * api);
SDL_Surface * light_get_icon(magic_api * api, int which); SDL_Surface *light_get_icon(magic_api * api, int which);
char * light_get_name(magic_api * api, int which); char *light_get_name(magic_api * api, int which);
char * light_get_description(magic_api * api, int which, int mode); char *light_get_description(magic_api * api, int which, int mode);
static void do_light(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_light(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void light_drag(magic_api * api, int which, SDL_Surface * canvas, void light_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void light_click(magic_api * api, int which, int mode, void light_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void light_release(magic_api * api, int which, void light_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void light_shutdown(magic_api * api); void light_shutdown(magic_api * api);
void light_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void light_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int light_requires_colors(magic_api * api, int which); int light_requires_colors(magic_api * api, int which);
@ -65,7 +61,10 @@ void light_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas)
int light_modes(magic_api * api, int which); int light_modes(magic_api * api, int which);
Uint32 light_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 light_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -73,52 +72,49 @@ int light_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/light1.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/light1.ogg", api->data_directory);
api->data_directory);
light1_snd = Mix_LoadWAV(fname); light1_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/light2.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/light2.ogg", api->data_directory);
api->data_directory);
light2_snd = Mix_LoadWAV(fname); light2_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int light_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int light_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * light_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *light_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/light.png", snprintf(fname, sizeof(fname), "%s/images/magic/light.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * light_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *light_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Light"))); return (strdup(gettext_noop("Light")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * light_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *light_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag to draw a beam of light on your picture."))); return (strdup(gettext_noop("Click and drag to draw a beam of light on your picture.")));
} }
// Do the effect: // Do the effect:
static void do_light(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void do_light(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y) int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
Uint32 pix; Uint32 pix;
Uint8 r, g, b; Uint8 r, g, b;
@ -126,64 +122,74 @@ static void do_light(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canva
float adj; float adj;
for (yy = -8; yy < 8; yy++) for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{ {
if (api->in_circle(xx, yy, 8)) for (xx = -8; xx < 8; xx++)
{
pix = api->getpixel(canvas, x + xx, y + yy);
SDL_GetRGB(pix, canvas->format, &r, &g, &b);
adj = (7.99 - sqrt(abs(xx * yy))) / 128.0;
api->rgbtohsv(r, g, b, &h, &s, &v);
v = min((float) 1.0, v + adj);
if (light_h == -1 && h == -1)
{ {
new_h = -1; if (api->in_circle(xx, yy, 8))
new_s = 0; {
new_v = v; pix = api->getpixel(canvas, x + xx, y + yy);
}
else if (light_h == -1)
{
new_h = h;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
else if (h == -1)
{
new_h = light_h;
new_s = max(0.0, light_s - adj / 2.0);
new_v = v;
}
else
{
new_h = (light_h + h) / 2;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b); SDL_GetRGB(pix, canvas->format, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy, adj = (7.99 - sqrt(abs(xx * yy))) / 128.0;
SDL_MapRGB(canvas->format, r, g, b));
} api->rgbtohsv(r, g, b, &h, &s, &v);
v = min((float)1.0, v + adj);
if (light_h == -1 && h == -1)
{
new_h = -1;
new_s = 0;
new_v = v;
}
else if (light_h == -1)
{
new_h = h;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
else if (h == -1)
{
new_h = light_h;
new_s = max(0.0, light_s - adj / 2.0);
new_v = v;
}
else
{
new_h = (light_h + h) / 2;
new_s = max(0.0, s - adj / 2.0);
new_v = v;
}
api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void light_drag(magic_api * api, int which, SDL_Surface * canvas, void light_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_light); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_light);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 8; update_rect->x = ox - 8;
update_rect->y = oy - 8; update_rect->y = oy - 8;
@ -195,16 +201,15 @@ void light_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void light_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void light_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
light_drag(api, which, canvas, last, x, y, x, y, update_rect); light_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void light_release(magic_api * api, int which ATTRIBUTE_UNUSED, void light_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
api->playsound(light2_snd, (x * 255) / canvas->w, 255); api->playsound(light2_snd, (x * 255) / canvas->w, 255);
} }
@ -230,15 +235,17 @@ int light_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 1; return 1;
} }
void light_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void light_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
{ SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
} }
void light_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void light_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int light_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int light_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -35,26 +35,22 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * metalpaint_snd; static Mix_Chunk *metalpaint_snd;
static Uint8 metalpaint_r, metalpaint_g, metalpaint_b; static Uint8 metalpaint_r, metalpaint_g, metalpaint_b;
Uint32 metalpaint_api_version(void); Uint32 metalpaint_api_version(void);
int metalpaint_init(magic_api * api); int metalpaint_init(magic_api * api);
int metalpaint_get_tool_count(magic_api * api); int metalpaint_get_tool_count(magic_api * api);
SDL_Surface * metalpaint_get_icon(magic_api * api, int which); SDL_Surface *metalpaint_get_icon(magic_api * api, int which);
char * metalpaint_get_name(magic_api * api, int which); char *metalpaint_get_name(magic_api * api, int which);
char * metalpaint_get_description(magic_api * api, int which, int mode); char *metalpaint_get_description(magic_api * api, int which, int mode);
static void do_metalpaint(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_metalpaint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas, void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void metalpaint_click(magic_api * api, int which, int mode, void metalpaint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void metalpaint_release(magic_api * api, int which, void metalpaint_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void metalpaint_shutdown(magic_api * api); void metalpaint_shutdown(magic_api * api);
void metalpaint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void metalpaint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int metalpaint_requires_colors(magic_api * api, int which); int metalpaint_requires_colors(magic_api * api, int which);
@ -63,7 +59,10 @@ void metalpaint_switchout(magic_api * api, int which, int mode, SDL_Surface * ca
int metalpaint_modes(magic_api * api, int which); int metalpaint_modes(magic_api * api, int which);
Uint32 metalpaint_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 metalpaint_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -71,40 +70,39 @@ int metalpaint_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/metalpaint.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/metalpaint.wav", api->data_directory);
api->data_directory);
metalpaint_snd = Mix_LoadWAV(fname); metalpaint_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int metalpaint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int metalpaint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * metalpaint_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *metalpaint_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/metalpaint.png", snprintf(fname, sizeof(fname), "%s/images/magic/metalpaint.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Metal Paint"))); return (strdup(gettext_noop("Metal Paint")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag the mouse to paint with a metallic color."))); return (strdup(gettext_noop("Click and drag the mouse to paint with a metallic color.")));
} }
#define METALPAINT_CYCLE 32 #define METALPAINT_CYCLE 32
@ -112,7 +110,7 @@ char * metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which AT
/* Based on 'Golden' gradient in The GIMP: */ /* Based on 'Golden' gradient in The GIMP: */
static int metalpaint_gradient[METALPAINT_CYCLE] = { static int metalpaint_gradient[METALPAINT_CYCLE] = {
56, 64, 73, 83, 93, 102, 113, 123, 56, 64, 73, 83, 93, 102, 113, 123,
139, 154, 168, 180, 185, 189, 183, 174, 139, 154, 168, 180, 185, 189, 183, 174,
164, 152, 142, 135, 129, 138, 149, 158, 164, 152, 142, 135, 129, 138, 149, 158,
166, 163, 158, 149, 140, 122, 103, 82 166, 163, 158, 149, 140, 122, 103, 82
@ -120,38 +118,49 @@ static int metalpaint_gradient[METALPAINT_CYCLE] = {
// Do the effect: // Do the effect:
static void do_metalpaint(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void do_metalpaint(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
int n; int n;
Uint8 r, g, b; Uint8 r, g, b;
for (yy = -8; yy < 8; yy++) for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{ {
n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE]; for (xx = -8; xx < 8; xx++)
{
n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE];
r = (metalpaint_r * n) / 255; r = (metalpaint_r * n) / 255;
g = (metalpaint_g * n) / 255; g = (metalpaint_g * n) / 255;
b = (metalpaint_b * n) / 255; b = (metalpaint_b * n) / 255;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b)); api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas, void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_metalpaint); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_metalpaint);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 8; update_rect->x = ox - 8;
update_rect->y = oy - 8; update_rect->y = oy - 8;
@ -162,17 +171,16 @@ void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
} }
// Affect the canvas on click: // Affect the canvas on click:
void metalpaint_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void metalpaint_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
metalpaint_drag(api, which, canvas, last, x, y, x, y, update_rect); metalpaint_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void metalpaint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void metalpaint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -197,15 +205,17 @@ int metalpaint_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRI
return 1; return 1;
} }
void metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -35,31 +35,25 @@
/* What tools we contain: */ /* What tools we contain: */
enum { enum
{
TOOL_MIRROR, TOOL_MIRROR,
TOOL_FLIP, TOOL_FLIP,
NUM_TOOLS NUM_TOOLS
}; };
static Mix_Chunk * snd_effects[NUM_TOOLS]; static Mix_Chunk *snd_effects[NUM_TOOLS];
/* Prototypes */ /* Prototypes */
int mirror_flip_init(magic_api *); int mirror_flip_init(magic_api *);
Uint32 mirror_flip_api_version(void); Uint32 mirror_flip_api_version(void);
int mirror_flip_get_tool_count(magic_api *); int mirror_flip_get_tool_count(magic_api *);
SDL_Surface * mirror_flip_get_icon(magic_api *, int); SDL_Surface *mirror_flip_get_icon(magic_api *, int);
char * mirror_flip_get_name(magic_api *, int); char *mirror_flip_get_name(magic_api *, int);
char * mirror_flip_get_description(magic_api *, int, int); char *mirror_flip_get_description(magic_api *, int, int);
void mirror_flip_drag(magic_api *, int, SDL_Surface *, void mirror_flip_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
SDL_Surface *, int, int, int, int, void mirror_flip_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
SDL_Rect *); void mirror_flip_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
void mirror_flip_release(magic_api *, int, SDL_Surface *,
SDL_Surface *, int, int, int, int,
SDL_Rect *);
void mirror_flip_click(magic_api *, int, int,
SDL_Surface *, SDL_Surface *,
int, int,
SDL_Rect *);
void mirror_flip_shutdown(magic_api *); void mirror_flip_shutdown(magic_api *);
void mirror_flip_set_color(magic_api *, Uint8, Uint8, Uint8); void mirror_flip_set_color(magic_api *, Uint8, Uint8, Uint8);
int mirror_flip_requires_colors(magic_api *, int); int mirror_flip_requires_colors(magic_api *, int);
@ -72,134 +66,127 @@ int mirror_flip_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/mirror.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/mirror.wav", api->data_directory);
api->data_directory);
snd_effects[TOOL_MIRROR] = Mix_LoadWAV(fname); snd_effects[TOOL_MIRROR] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/flip.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/flip.wav", api->data_directory);
api->data_directory);
snd_effects[TOOL_FLIP] = Mix_LoadWAV(fname); snd_effects[TOOL_FLIP] = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 mirror_flip_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 mirror_flip_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int mirror_flip_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int mirror_flip_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(NUM_TOOLS); return (NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * mirror_flip_get_icon(magic_api * api, int which) SDL_Surface *mirror_flip_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == TOOL_MIRROR) if (which == TOOL_MIRROR)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/mirror.png", snprintf(fname, sizeof(fname), "%s/images/magic/mirror.png", api->data_directory);
api->data_directory); }
}
else if (which == TOOL_FLIP) else if (which == TOOL_FLIP)
{ {
snprintf(fname, sizeof(fname), "%s/images/magic/flip.png", snprintf(fname, sizeof(fname), "%s/images/magic/flip.png", api->data_directory);
api->data_directory); }
}
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * mirror_flip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *mirror_flip_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == TOOL_MIRROR) if (which == TOOL_MIRROR)
return(strdup(gettext_noop("Mirror"))); return (strdup(gettext_noop("Mirror")));
else if (which == TOOL_FLIP) else if (which == TOOL_FLIP)
return(strdup(gettext_noop("Flip"))); return (strdup(gettext_noop("Flip")));
return(NULL); return (NULL);
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * mirror_flip_get_description(magic_api * api ATTRIBUTE_UNUSED, char *mirror_flip_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
int which, int mode ATTRIBUTE_UNUSED)
{ {
if (which == TOOL_MIRROR) if (which == TOOL_MIRROR)
return(strdup( return (strdup(gettext_noop("Click to make a mirror image.")));
gettext_noop("Click to make a mirror image.")));
else else
return(strdup( return (strdup(gettext_noop("Click to flip the picture upside-down.")));
gettext_noop("Click to flip the picture upside-down.")));
return(NULL); return (NULL);
} }
// We affect the whole canvas, so only do things on click, not drag: // We affect the whole canvas, so only do things on click, not drag:
void mirror_flip_drag(magic_api * api ATTRIBUTE_UNUSED, void mirror_flip_drag(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
// No-op // No-op
} }
void mirror_flip_release(magic_api * api ATTRIBUTE_UNUSED, void mirror_flip_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
// No-op // No-op
} }
// Affect the canvas on click: // Affect the canvas on click:
void mirror_flip_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void mirror_flip_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
int xx, yy; int xx, yy;
SDL_Rect src, dest; SDL_Rect src, dest;
if (which == TOOL_MIRROR) if (which == TOOL_MIRROR)
{
for (xx = 0; xx < canvas->w; xx++)
{ {
src.x = xx; for (xx = 0; xx < canvas->w; xx++)
src.y = 0; {
src.w = 1; src.x = xx;
src.h = canvas->h; src.y = 0;
src.w = 1;
src.h = canvas->h;
dest.x = canvas->w - xx - 1; dest.x = canvas->w - xx - 1;
dest.y = 0; dest.y = 0;
SDL_BlitSurface(last, &src, canvas, &dest); SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_MIRROR);
} }
api->special_notify(SPECIAL_MIRROR);
}
else if (which == TOOL_FLIP) else if (which == TOOL_FLIP)
{
for (yy = 0; yy < canvas->h; yy++)
{ {
src.x = 0; for (yy = 0; yy < canvas->h; yy++)
src.y = yy; {
src.w = canvas->w; src.x = 0;
src.h = 1; src.y = yy;
src.w = canvas->w;
src.h = 1;
dest.x = 0; dest.x = 0;
dest.y = canvas->h - yy - 1; dest.y = canvas->h - yy - 1;
SDL_BlitSurface(last, &src, canvas, &dest); SDL_BlitSurface(last, &src, canvas, &dest);
}
api->special_notify(SPECIAL_FLIP);
} }
api->special_notify(SPECIAL_FLIP);
}
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -218,33 +205,28 @@ void mirror_flip_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// We don't use colors: // We don't use colors:
void mirror_flip_set_color(magic_api * api ATTRIBUTE_UNUSED, void mirror_flip_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
// We don't use colors: // We don't use colors:
int mirror_flip_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int mirror_flip_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED)
{ {
return 0; return 0;
} }
void mirror_flip_switchin(magic_api * api ATTRIBUTE_UNUSED, void mirror_flip_switchin(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void mirror_flip_switchout(magic_api * api ATTRIBUTE_UNUSED, void mirror_flip_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int mirror_flip_modes(magic_api * api ATTRIBUTE_UNUSED, int mirror_flip_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN); return (MODE_FULLSCREEN);
} }

View file

@ -45,29 +45,22 @@
#define gettext_noop(String) String #define gettext_noop(String) String
#endif #endif
static void mosaic_noise_pixel(void * ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y); static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y);
static void mosaic_blur_pixel(void * ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y); static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void mosaic_sharpen_pixel(void * ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y); static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void reset_mosaic_blured(SDL_Surface * canvas); static void reset_mosaic_blured(SDL_Surface * canvas);
/* Prototypes */ /* Prototypes */
Uint32 mosaic_api_version(void); Uint32 mosaic_api_version(void);
int mosaic_init(magic_api *); int mosaic_init(magic_api *);
int mosaic_get_tool_count(magic_api *); int mosaic_get_tool_count(magic_api *);
SDL_Surface * mosaic_get_icon(magic_api *, int); SDL_Surface *mosaic_get_icon(magic_api *, int);
char * mosaic_get_name(magic_api *, int); char *mosaic_get_name(magic_api *, int);
char * mosaic_get_description(magic_api *, int, int); char *mosaic_get_description(magic_api *, int, int);
void mosaic_paint(void *, int, SDL_Surface *, void mosaic_paint(void *, int, SDL_Surface *, SDL_Surface *, int, int);
SDL_Surface *, int, int); void mosaic_drag(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, SDL_Rect *);
void mosaic_drag(magic_api *, int, SDL_Surface *, void mosaic_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
SDL_Surface *, int, int, int, int, void mosaic_release(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *);
SDL_Rect *);
void mosaic_click(magic_api *, int, int,
SDL_Surface *, SDL_Surface *,
int, int, SDL_Rect *);
void mosaic_release(magic_api *, int,
SDL_Surface *, SDL_Surface *,
int, int, SDL_Rect *);
void mosaic_shutdown(magic_api *); void mosaic_shutdown(magic_api *);
void mosaic_set_color(magic_api *, Uint8, Uint8, Uint8); void mosaic_set_color(magic_api *, Uint8, Uint8, Uint8);
int mosaic_requires_colors(magic_api *, int); int mosaic_requires_colors(magic_api *, int);
@ -75,155 +68,169 @@ void mosaic_switchin(magic_api *, int, int, SDL_Surface *);
void mosaic_switchout(magic_api *, int, int, SDL_Surface *); void mosaic_switchout(magic_api *, int, int, SDL_Surface *);
int mosaic_modes(magic_api *, int); int mosaic_modes(magic_api *, int);
static const int mosaic_AMOUNT= 300; static const int mosaic_AMOUNT = 300;
static const int mosaic_RADIUS = 16; static const int mosaic_RADIUS = 16;
static const double mosaic_SHARPEN = 1.0; static const double mosaic_SHARPEN = 1.0;
static int randnoise ATTRIBUTE_UNUSED; static int randnoise ATTRIBUTE_UNUSED;
Uint8 * mosaic_blured; Uint8 *mosaic_blured;
enum { enum
TOOL_MOSAIC, {
mosaic_NUM_TOOLS TOOL_MOSAIC,
mosaic_NUM_TOOLS
}; };
static Mix_Chunk * mosaic_snd_effect[mosaic_NUM_TOOLS]; static Mix_Chunk *mosaic_snd_effect[mosaic_NUM_TOOLS];
static SDL_Surface * canvas_noise; static SDL_Surface *canvas_noise;
static SDL_Surface * canvas_blur; static SDL_Surface *canvas_blur;
static SDL_Surface * canvas_sharp; static SDL_Surface *canvas_sharp;
const char * mosaic_snd_filenames[mosaic_NUM_TOOLS] = { const char *mosaic_snd_filenames[mosaic_NUM_TOOLS] = {
"mosaic.ogg", /* FIXME */ "mosaic.ogg", /* FIXME */
}; };
const char * mosaic_icon_filenames[mosaic_NUM_TOOLS] = {
const char *mosaic_icon_filenames[mosaic_NUM_TOOLS] = {
"mosaic.png", "mosaic.png",
}; };
const char * mosaic_names[mosaic_NUM_TOOLS] = {
const char *mosaic_names[mosaic_NUM_TOOLS] = {
gettext_noop("Mosaic"), gettext_noop("Mosaic"),
}; };
const char * mosaic_descs[mosaic_NUM_TOOLS][2] = {
const char *mosaic_descs[mosaic_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to add a mosaic effect to parts of your picture."), {gettext_noop("Click and drag the mouse to add a mosaic effect to parts of your picture."),
gettext_noop("Click to add a mosaic effect to your entire picture."),}, gettext_noop("Click to add a mosaic effect to your entire picture."),},
}; };
Uint32 mosaic_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 mosaic_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int mosaic_init(magic_api * api){ int mosaic_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
for (i = 0; i < mosaic_NUM_TOOLS; i++){ for (i = 0; i < mosaic_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, mosaic_snd_filenames[i]); {
mosaic_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, mosaic_snd_filenames[i]);
} mosaic_snd_effect[i] = Mix_LoadWAV(fname);
}
return(1); return (1);
} }
int mosaic_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int mosaic_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(mosaic_NUM_TOOLS); {
return (mosaic_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * mosaic_get_icon(magic_api * api, int which){ SDL_Surface *mosaic_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, mosaic_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, mosaic_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * mosaic_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *mosaic_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(mosaic_names[which]))); {
return (strdup(gettext_noop(mosaic_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * mosaic_get_description(magic_api * api ATTRIBUTE_UNUSED, char *mosaic_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
int which, int mode){ {
return(strdup(gettext_noop(mosaic_descs[which][mode-1]))); return (strdup(gettext_noop(mosaic_descs[which][mode - 1])));
} }
//Calculates the grey scale value for a rgb pixel //Calculates the grey scale value for a rgb pixel
static int mosaic_grey(Uint8 r1,Uint8 g1,Uint8 b1){ static int mosaic_grey(Uint8 r1, Uint8 g1, Uint8 b1)
return 0.3*r1+.59*g1+0.11*b1; {
return 0.3 * r1 + .59 * g1 + 0.11 * b1;
} }
// Do the effect for the full image // Do the effect for the full image
static void do_mosaic_full(void * ptr, SDL_Surface * canvas, static void do_mosaic_full(void *ptr, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED){ SDL_Surface * last ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int x, y;
Uint32 amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
SDL_Surface *mosaic_temp = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
int x,y;
Uint32 amask = ~(canvas->format->Rmask |
canvas->format->Gmask |
canvas->format->Bmask);
SDL_Surface * mosaic_temp =
SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
api->update_progress_bar(); api->update_progress_bar();
for (y = 0; y < canvas->h; y++){ for (y = 0; y < canvas->h; y++)
{
for (x=0; x < canvas->w; x++){ for (x = 0; x < canvas->w; x++)
mosaic_blur_pixel(api, mosaic_temp, canvas_noise, x, y); {
mosaic_blur_pixel(api, mosaic_temp, canvas_noise, x, y);
}
} }
}
api->update_progress_bar(); api->update_progress_bar();
for (y = 0; y < canvas->h; y++){ for (y = 0; y < canvas->h; y++)
for (x=0; x < canvas->w; x++){ {
mosaic_sharpen_pixel(api, canvas, mosaic_temp, x, y); for (x = 0; x < canvas->w; x++)
{
mosaic_sharpen_pixel(api, canvas, mosaic_temp, x, y);
}
} }
}
SDL_FreeSurface(mosaic_temp); SDL_FreeSurface(mosaic_temp);
} }
/* Paint the brush, noise is yet done at switchin, /* Paint the brush, noise is yet done at switchin,
blurs 2 pixels around the brush in order to get sharpen well done.*/ blurs 2 pixels around the brush in order to get sharpen well done.*/
void mosaic_paint(void * ptr_to_api, int which ATTRIBUTE_UNUSED, void mosaic_paint(void *ptr_to_api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
int i, j, pix_row_pos; int i, j, pix_row_pos;
magic_api * api = (magic_api *) ptr_to_api; magic_api *api = (magic_api *) ptr_to_api;
for (j = max(0, y - mosaic_RADIUS - 2); j < min(canvas->h, y + mosaic_RADIUS + 2); j++) for (j = max(0, y - mosaic_RADIUS - 2); j < min(canvas->h, y + mosaic_RADIUS + 2); j++)
{ {
pix_row_pos = j * canvas->w; pix_row_pos = j * canvas->w;
for (i = max(0, x - mosaic_RADIUS - 2); i < min(canvas->w, x + mosaic_RADIUS + 2); i++) for (i = max(0, x - mosaic_RADIUS - 2); i < min(canvas->w, x + mosaic_RADIUS + 2); i++)
if( !mosaic_blured[pix_row_pos + i] && if (!mosaic_blured[pix_row_pos + i] && api->in_circle(i - x, j - y, mosaic_RADIUS + 2))
api->in_circle(i - x,j - y, mosaic_RADIUS + 2)) {
{ mosaic_blur_pixel(api, canvas_blur, canvas_noise, i, j);
mosaic_blur_pixel(api, canvas_blur, canvas_noise, i, j); mosaic_blured[pix_row_pos + i] = 1; /* Track what are yet blured */
mosaic_blured[pix_row_pos + i] = 1; /* Track what are yet blured */ }
}
} }
for (i = x - mosaic_RADIUS; i < x + mosaic_RADIUS; i++) for (i = x - mosaic_RADIUS; i < x + mosaic_RADIUS; i++)
for (j=y - mosaic_RADIUS; j < y + mosaic_RADIUS; j++) for (j = y - mosaic_RADIUS; j < y + mosaic_RADIUS; j++)
if (api->in_circle(i - x, j - y, mosaic_RADIUS)) if (api->in_circle(i - x, j - y, mosaic_RADIUS))
if( !api->touched(i, j)) if (!api->touched(i, j))
{ {
mosaic_sharpen_pixel(api, canvas_sharp, canvas_blur, i, j); mosaic_sharpen_pixel(api, canvas_sharp, canvas_blur, i, j);
api->putpixel(canvas, i, j, api->getpixel(canvas_sharp, i, j)); api->putpixel(canvas, i, j, api->getpixel(canvas_sharp, i, j));
} }
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void mosaic_drag(magic_api * api, int which, SDL_Surface * canvas, void mosaic_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line(api, which, canvas, last, ox, oy, x, y, 1, mosaic_paint); api->line(api, which, canvas, last, ox, oy, x, y, 1, mosaic_paint);
update_rect->x = min(ox, x) - mosaic_RADIUS; update_rect->x = min(ox, x) - mosaic_RADIUS;
@ -236,8 +243,8 @@ void mosaic_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void mosaic_click(magic_api * api, int which, int mode, void mosaic_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_FULLSCREEN) if (mode == MODE_FULLSCREEN)
{ {
@ -246,7 +253,7 @@ void mosaic_click(magic_api * api, int which, int mode,
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
do_mosaic_full(api, canvas_noise, last, which); do_mosaic_full(api, canvas_noise, last, which);
SDL_BlitSurface(canvas_noise, NULL, canvas, NULL); SDL_BlitSurface(canvas_noise, NULL, canvas, NULL);
api->playsound(mosaic_snd_effect[which], 128, 255); api->playsound(mosaic_snd_effect[which], 128, 255);
} }
@ -256,195 +263,200 @@ void mosaic_click(magic_api * api, int which, int mode,
} }
// Affect the canvas on release: // Affect the canvas on release:
void mosaic_release(magic_api * api ATTRIBUTE_UNUSED, void mosaic_release(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void mosaic_shutdown(magic_api * api ATTRIBUTE_UNUSED) void mosaic_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<mosaic_NUM_TOOLS; i++){
if(mosaic_snd_effect[i] != NULL){ for (i = 0; i < mosaic_NUM_TOOLS; i++)
Mix_FreeChunk(mosaic_snd_effect[i]); {
} if (mosaic_snd_effect[i] != NULL)
} {
Mix_FreeChunk(mosaic_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void mosaic_set_color(magic_api * api ATTRIBUTE_UNUSED, void mosaic_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
// Use colors: // Use colors:
int mosaic_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int mosaic_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
int which ATTRIBUTE_UNUSED)
{ {
return 0; return 0;
} }
//Add noise to a pixel //Add noise to a pixel
static void mosaic_noise_pixel(void * ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y){ static void mosaic_noise_pixel(void *ptr, SDL_Surface * canvas, int noise_AMOUNT, int x, int y)
magic_api * api = (magic_api *) ptr; {
magic_api *api = (magic_api *) ptr;
Uint8 temp[3]; Uint8 temp[3];
double temp2[3]; double temp2[3];
int k; int k;
SDL_GetRGB(api->getpixel(canvas,x, y), canvas->format, &temp[0], &temp[1], &temp[2]); SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
for (k =0;k<3;k++){ for (k = 0; k < 3; k++)
temp2[k] = clamp(0.0, (int)temp[k] - (rand()%noise_AMOUNT) + noise_AMOUNT/2.0, 255.0); {
} temp2[k] = clamp(0.0, (int)temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0, 255.0);
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2])); api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
} }
//Blur a pixel //Blur a pixel
static void mosaic_blur_pixel(void * ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ static void mosaic_blur_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
magic_api * api = (magic_api *) ptr; {
int i,j,k; magic_api *api = (magic_api *) ptr;
Uint8 temp[3]; int i, j, k;
Uint8 temp[3];
double blurValue[3]; double blurValue[3];
//5x5 gaussiann weighting window //5x5 gaussiann weighting window
const int weight[5][5] = { {1,4,7,4,1}, const int weight[5][5] = { {1, 4, 7, 4, 1},
{4,16,26,16,4}, {4, 16, 26, 16, 4},
{7,26,41,26,7}, {7, 26, 41, 26, 7},
{4,16,26,16,4}, {4, 16, 26, 16, 4},
{1,4,7,4,1}}; {1, 4, 7, 4, 1}
};
for (k =0;k<3;k++){ for (k = 0; k < 3; k++)
blurValue[k] = 0; {
} blurValue[k] = 0;
for (i=-2;i<3;i++){
for (j=-2;j<3;j++){
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k =0;k<3;k++){
blurValue[k] += temp[k]* weight[i+2][j+2];
}
} }
}
for (k =0;k<3;k++){ for (i = -2; i < 3; i++)
blurValue[k] /= 273; {
} for (j = -2; j < 3; j++)
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2])); {
//Add the pixels around the current one wieghted
SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &temp[0], &temp[1], &temp[2]);
for (k = 0; k < 3; k++)
{
blurValue[k] += temp[k] * weight[i + 2][j + 2];
}
}
}
for (k = 0; k < 3; k++)
{
blurValue[k] /= 273;
}
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, blurValue[0], blurValue[1], blurValue[2]));
} }
//Sharpen a pixel //Sharpen a pixel
static void mosaic_sharpen_pixel(void * ptr, static void mosaic_sharpen_pixel(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last, {
int x, int y){
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r1, g1, b1; Uint8 r1, g1, b1;
int grey; int grey;
int i,j; int i, j;
double sobel_1=0,sobel_2=0; double sobel_1 = 0, sobel_2 = 0;
double temp; double temp;
//Sobel weighting masks //Sobel weighting masks
const int sobel_weights_1[3][3] = { {1,2,1}, const int sobel_weights_1[3][3] = { {1, 2, 1},
{0,0,0}, {0, 0, 0},
{-1,-2,-1}}; {-1, -2, -1}
const int sobel_weights_2[3][3] = { {-1,0,1}, };
{-2,0,2}, const int sobel_weights_2[3][3] = { {-1, 0, 1},
{-1,0,1}}; {-2, 0, 2},
{-1, 0, 1}
};
sobel_1=0; sobel_1 = 0;
sobel_2=0; sobel_2 = 0;
for (i=-1;i<2;i++){ for (i = -1; i < 2; i++)
for(j=-1; j<2; j++){ {
//No need to check if inside canvas, getpixel does it for us. for (j = -1; j < 2; j++)
SDL_GetRGB(api->getpixel(last, x+i, y+j), last->format, &r1, &g1, &b1); {
grey = mosaic_grey(r1,g1,b1); //No need to check if inside canvas, getpixel does it for us.
sobel_1 += grey * sobel_weights_1[i+1][j+1]; SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1, &b1);
sobel_2 += grey * sobel_weights_2[i+1][j+1]; grey = mosaic_grey(r1, g1, b1);
} sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
} sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
temp = sqrt(sobel_1*sobel_1 + sobel_2*sobel_2); }
temp = (temp/1443)*255.0;
temp = sqrt(sobel_1 * sobel_1 + sobel_2 * sobel_2);
temp = (temp / 1443) * 255.0;
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1); SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + mosaic_SHARPEN * temp, 255.0), api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, g1 + mosaic_SHARPEN * temp, 255.0), clamp(0.0, g1 + mosaic_SHARPEN * temp, 255.0),
clamp(0.0, b1 + mosaic_SHARPEN * temp, 255.0))); clamp(0.0, b1 + mosaic_SHARPEN * temp, 255.0)));
} }
void mosaic_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, void mosaic_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{ {
int y, x; int y, x;
Uint32 amask; Uint32 amask;
mosaic_blured = (Uint8 *) malloc(sizeof(Uint8) * (canvas->w * canvas->h)); mosaic_blured = (Uint8 *) malloc(sizeof(Uint8) * (canvas->w * canvas->h));
if (mosaic_blured == NULL) if (mosaic_blured == NULL)
{ {
fprintf(stderr, "\nError: Can't build drawing touch mask!\n"); fprintf(stderr, "\nError: Can't build drawing touch mask!\n");
exit(1); exit(1);
}
amask = ~(canvas->format->Rmask |
canvas->format->Gmask |
canvas->format->Bmask);
canvas_noise = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
SDL_BlitSurface(canvas, NULL, canvas_noise, NULL);
for (y = 0; y < canvas->h; y++){
for (x=0; x < canvas->w; x++){
mosaic_noise_pixel(api, canvas_noise, mosaic_AMOUNT, x, y);
} }
}
canvas_blur = SDL_CreateRGBSurface(SDL_SWSURFACE, amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, amask);
canvas_sharp = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas_noise = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w, canvas->w,
canvas->h, canvas->h,
canvas->format->BitsPerPixel, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Gmask,
canvas->format->Bmask, amask); SDL_BlitSurface(canvas, NULL, canvas_noise, NULL);
reset_mosaic_blured(canvas);
for (y = 0; y < canvas->h; y++)
{
for (x = 0; x < canvas->w; x++)
{
mosaic_noise_pixel(api, canvas_noise, mosaic_AMOUNT, x, y);
}
}
canvas_blur = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas_sharp = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w,
canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
reset_mosaic_blured(canvas);
} }
void mosaic_switchout(magic_api * api ATTRIBUTE_UNUSED, void mosaic_switchout(magic_api * api ATTRIBUTE_UNUSED,
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED)
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
SDL_FreeSurface(canvas_noise); SDL_FreeSurface(canvas_noise);
SDL_FreeSurface(canvas_blur); SDL_FreeSurface(canvas_blur);
SDL_FreeSurface(canvas_sharp); SDL_FreeSurface(canvas_sharp);
free (mosaic_blured); free(mosaic_blured);
} }
int mosaic_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int mosaic_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT|MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }
void reset_mosaic_blured(SDL_Surface * canvas) void reset_mosaic_blured(SDL_Surface * canvas)

File diff suppressed because it is too large Load diff

View file

@ -33,27 +33,22 @@
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
static Mix_Chunk * negative_snd; static Mix_Chunk *negative_snd;
int negative_init(magic_api * api); int negative_init(magic_api * api);
Uint32 negative_api_version(void); Uint32 negative_api_version(void);
int negative_get_tool_count(magic_api * api); int negative_get_tool_count(magic_api * api);
SDL_Surface * negative_get_icon(magic_api * api, int which); SDL_Surface *negative_get_icon(magic_api * api, int which);
char * negative_get_name(magic_api * api, int which); char *negative_get_name(magic_api * api, int which);
char * negative_get_description(magic_api * api, int which, int mode); char *negative_get_description(magic_api * api, int which, int mode);
static void do_negative(void * ptr, int which, static void do_negative(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void negative_drag(magic_api * api, int which, SDL_Surface * canvas, void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void negative_click(magic_api * api, int which, int mode, void negative_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void negative_release(magic_api * api, int which, void negative_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void negative_shutdown(magic_api * api); void negative_shutdown(magic_api * api);
void negative_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void negative_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int negative_requires_colors(magic_api * api, int which); int negative_requires_colors(magic_api * api, int which);
@ -66,90 +61,98 @@ int negative_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/negative.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/negative.wav", api->data_directory);
api->data_directory);
negative_snd = Mix_LoadWAV(fname); negative_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 negative_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 negative_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// Only one tool: // Only one tool:
int negative_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int negative_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icon: // Load our icon:
SDL_Surface * negative_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *negative_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/negative.png", snprintf(fname, sizeof(fname), "%s/images/magic/negative.png", api->data_directory);
api->data_directory); return (IMG_Load(fname));
return(IMG_Load(fname));
} }
// Return our name, localized: // Return our name, localized:
char * negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Negative"))); return (strdup(gettext_noop("Negative")));
} }
// Return our description, localized: // Return our description, localized:
char * negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return(strdup( return (strdup(gettext_noop("Click and drag the mouse around to make your painting negative."))); /* Does this make more sense? */
gettext_noop("Click and drag the mouse around to make your painting negative."))); /* Does this make more sense? */
else if (mode == MODE_FULLSCREEN) else if (mode == MODE_FULLSCREEN)
return(strdup( return (strdup(gettext_noop("Click to turn your painting into its negative.")));
gettext_noop("Click to turn your painting into its negative.")));
else else
return(NULL); return (NULL);
} }
// Callback that does the negative color effect on a circle centered around x,y // Callback that does the negative color effect on a circle centered around x,y
static void do_negative(void * ptr, int which ATTRIBUTE_UNUSED, static void do_negative(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{ {
int xx, yy; int xx, yy;
Uint8 r, g, b; Uint8 r, g, b;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - 16; yy < y + 16; yy++) for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{ {
if (api->in_circle(xx - x, yy - y, 16)) for (xx = x - 16; xx < x + 16; xx++)
{ {
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b); if (api->in_circle(xx - x, yy - y, 16))
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
r = 0xFF - r; r = 0xFF - r;
g = 0xFF - g; g = 0xFF - g;
b = 0xFF - b; b = 0xFF - b;
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
} }
}
} }
}
} }
// Ask Tux Paint to call our 'do_negative()' callback over a line // Ask Tux Paint to call our 'do_negative()' callback over a line
void negative_drag(magic_api * api, int which, SDL_Surface * canvas, void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
SDL_LockSurface(last); SDL_LockSurface(last);
SDL_LockSurface(canvas); SDL_LockSurface(canvas);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_negative); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_negative);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -165,41 +168,40 @@ void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
// Ask Tux Paint to call our 'do_negative()' callback at a single point // Ask Tux Paint to call our 'do_negative()' callback at a single point
void negative_click(magic_api * api, int which, int mode, void negative_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
negative_drag(api, which, canvas, last, x, y, x, y, update_rect); negative_drag(api, which, canvas, last, x, y, x, y, update_rect);
else else
{
int xx, yy;
Uint8 r, g, b;
for (yy = 0; yy < canvas->h; yy++)
{ {
for (xx = 0; xx < canvas->w; xx++) int xx, yy;
{ Uint8 r, g, b;
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
r = 0xFF - r; for (yy = 0; yy < canvas->h; yy++)
g = 0xFF - g; {
b = 0xFF - b; for (xx = 0; xx < canvas->w; xx++)
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); r = 0xFF - r;
} g = 0xFF - g;
b = 0xFF - b;
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
} }
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
} }
void negative_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void negative_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -211,7 +213,8 @@ void negative_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// We don't use colors // We don't use colors
void negative_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void negative_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -221,15 +224,17 @@ int negative_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBU
return 0; return 0;
} }
void negative_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void negative_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void negative_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void negative_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int negative_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int negative_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT | MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }

View file

@ -46,46 +46,45 @@
static const int noise_AMOUNT = 100.0; static const int noise_AMOUNT = 100.0;
static const int noise_RADIUS = 16; static const int noise_RADIUS = 16;
enum { enum
TOOL_NOISE, {
noise_NUM_TOOLS TOOL_NOISE,
noise_NUM_TOOLS
}; };
static Mix_Chunk * noise_snd_effect[noise_NUM_TOOLS]; static Mix_Chunk *noise_snd_effect[noise_NUM_TOOLS];
const char * noise_snd_filenames[noise_NUM_TOOLS] = { const char *noise_snd_filenames[noise_NUM_TOOLS] = {
"noise.ogg", "noise.ogg",
}; };
const char * noise_icon_filenames[noise_NUM_TOOLS] = {
const char *noise_icon_filenames[noise_NUM_TOOLS] = {
"noise.png", "noise.png",
}; };
const char * noise_names[noise_NUM_TOOLS] = {
const char *noise_names[noise_NUM_TOOLS] = {
gettext_noop("Noise"), gettext_noop("Noise"),
}; };
const char * noise_descs[noise_NUM_TOOLS][2] = {
const char *noise_descs[noise_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to add noise to parts of your picture."), {gettext_noop("Click and drag the mouse to add noise to parts of your picture."),
gettext_noop("Click to add noise to your entire picture."),}, gettext_noop("Click to add noise to your entire picture."),},
}; };
Uint32 noise_api_version(void); Uint32 noise_api_version(void);
int noise_init(magic_api * api); int noise_init(magic_api * api);
SDL_Surface * noise_get_icon(magic_api * api, int which); SDL_Surface *noise_get_icon(magic_api * api, int which);
char * noise_get_name(magic_api * api, int which); char *noise_get_name(magic_api * api, int which);
char * noise_get_description(magic_api * api, int which, int mode); char *noise_get_description(magic_api * api, int which, int mode);
static void do_noise_pixel(void * ptr, int which, static void do_noise_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last, static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
int x, int y); static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_noise_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_noise_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void noise_drag(magic_api * api, int which, SDL_Surface * canvas, void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void noise_click(magic_api * api, int which, int mode, void noise_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void noise_release(magic_api * api, int which, void noise_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void noise_shutdown(magic_api * api); void noise_shutdown(magic_api * api);
void noise_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void noise_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int noise_requires_colors(magic_api * api, int which); int noise_requires_colors(magic_api * api, int which);
@ -94,101 +93,127 @@ void noise_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas)
int noise_modes(magic_api * api, int which); int noise_modes(magic_api * api, int which);
int noise_get_tool_count(magic_api * api ATTRIBUTE_UNUSED); int noise_get_tool_count(magic_api * api ATTRIBUTE_UNUSED);
Uint32 noise_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 noise_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int noise_init(magic_api * api){ int noise_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
srand(time(0)); srand(time(0));
for (i = 0; i < noise_NUM_TOOLS; i++){ for (i = 0; i < noise_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, noise_snd_filenames[i]); {
noise_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, noise_snd_filenames[i]);
} noise_snd_effect[i] = Mix_LoadWAV(fname);
return(1); }
return (1);
} }
int noise_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int noise_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(noise_NUM_TOOLS); {
return (noise_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * noise_get_icon(magic_api * api, int which){ SDL_Surface *noise_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, noise_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, noise_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * noise_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *noise_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(noise_names[which]))); {
return (strdup(gettext_noop(noise_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * noise_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *noise_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(noise_descs[which][mode-1]))); {
return (strdup(gettext_noop(noise_descs[which][mode - 1])));
} }
//Do the effect for one pixel //Do the effect for one pixel
static void do_noise_pixel(void * ptr, int which ATTRIBUTE_UNUSED, static void do_noise_pixel(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y){ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 temp[3]; Uint8 temp[3];
double temp2[3]; double temp2[3];
int k; int k;
SDL_GetRGB(api->getpixel(canvas,x, y), canvas->format, &temp[0], &temp[1], &temp[2]); SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &temp[0], &temp[1], &temp[2]);
for (k =0;k<3;k++){ for (k = 0; k < 3; k++)
temp2[k] = clamp(0.0, (int)temp[k] - (rand()%noise_AMOUNT) + noise_AMOUNT/2.0, 255.0); {
} temp2[k] = clamp(0.0, (int)temp[k] - (rand() % noise_AMOUNT) + noise_AMOUNT / 2.0, 255.0);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2])); }
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp2[0], temp2[1], temp2[2]));
} }
// Do the effect for the full image // Do the effect for the full image
static void do_noise_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ static void do_noise_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
int x,y; {
int x, y;
for (y = 0; y < last->h; y++){ for (y = 0; y < last->h; y++)
for (x=0; x < last->w; x++){ {
do_noise_pixel(ptr, which, canvas, last, x, y); for (x = 0; x < last->w; x++)
} {
} do_noise_pixel(ptr, which, canvas, last, x, y);
}
}
} }
//do the effect for the brush //do the effect for the brush
static void do_noise_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ static void do_noise_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
int xx, yy; int xx, yy;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - noise_RADIUS; yy < y + noise_RADIUS; yy++) for (yy = y - noise_RADIUS; yy < y + noise_RADIUS; yy++)
{
for (xx = x - noise_RADIUS; xx < x + noise_RADIUS; xx++)
{ {
if (api->in_circle(xx - x, yy - y, noise_RADIUS) && for (xx = x - noise_RADIUS; xx < x + noise_RADIUS; xx++)
!api->touched(xx, yy)) {
{ if (api->in_circle(xx - x, yy - y, noise_RADIUS) && !api->touched(xx, yy))
do_noise_pixel(api, which, canvas, last, xx, yy); {
} do_noise_pixel(api, which, canvas, last, xx, yy);
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void noise_drag(magic_api * api, int which, SDL_Surface * canvas, void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_noise_brush); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_noise_brush);
api->playsound(noise_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(noise_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - noise_RADIUS; update_rect->x = ox - noise_RADIUS;
update_rect->y = oy - noise_RADIUS; update_rect->y = oy - noise_RADIUS;
@ -198,41 +223,46 @@ void noise_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void noise_click(magic_api * api, int which, int mode, void noise_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
noise_drag(api, which, canvas, last, x, y, x, y, update_rect); noise_drag(api, which, canvas, last, x, y, x, y, update_rect);
else{ else
update_rect->x = 0; {
update_rect->y = 0; update_rect->x = 0;
update_rect->w = canvas->w; update_rect->y = 0;
update_rect->h = canvas->h; update_rect->w = canvas->w;
do_noise_full(api, canvas, last, which); update_rect->h = canvas->h;
api->playsound(noise_snd_effect[which], 128, 255); do_noise_full(api, canvas, last, which);
} api->playsound(noise_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void noise_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void noise_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void noise_shutdown(magic_api * api ATTRIBUTE_UNUSED) void noise_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<noise_NUM_TOOLS; i++){
if(noise_snd_effect[i] != NULL){ for (i = 0; i < noise_NUM_TOOLS; i++)
Mix_FreeChunk(noise_snd_effect[i]); {
} if (noise_snd_effect[i] != NULL)
} {
Mix_FreeChunk(noise_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void noise_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void noise_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -242,16 +272,17 @@ int noise_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 0; return 0;
} }
void noise_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void noise_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void noise_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void noise_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int noise_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int noise_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -47,27 +47,24 @@
#endif #endif
static void perspective_preview(magic_api * api, int which, static void perspective_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect, float step); int x, int y, SDL_Rect * update_rect, float step);
Uint32 perspective_api_version(void); Uint32 perspective_api_version(void);
int perspective_init(magic_api * api); int perspective_init(magic_api * api);
int perspective_get_tool_count(magic_api * api); int perspective_get_tool_count(magic_api * api);
SDL_Surface * perspective_get_icon(magic_api * api, int which); SDL_Surface *perspective_get_icon(magic_api * api, int which);
char * perspective_get_name(magic_api * api, int which); char *perspective_get_name(magic_api * api, int which);
char * perspective_get_description(magic_api * api, int which, int mode); char *perspective_get_description(magic_api * api, int which, int mode);
void perspective_drag(magic_api * api, int which, SDL_Surface * canvas, void perspective_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void perspective_click(magic_api * api, int which, int mode, void perspective_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void perspective_release(magic_api * api, int which, void perspective_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void perspective_shutdown(magic_api * api); void perspective_shutdown(magic_api * api);
@ -81,14 +78,15 @@ void perspective_switchout(magic_api * api, int which, int mode, SDL_Surface * c
int perspective_modes(magic_api * api, int which); int perspective_modes(magic_api * api, int which);
int scan_fill(magic_api * api, SDL_Surface * canvas, SDL_Surface * srfc,int x,int y, int fill_edge, int fill_tile, int size, Uint32 color); int scan_fill(magic_api * api, SDL_Surface * canvas, SDL_Surface * srfc, int x, int y, int fill_edge, int fill_tile,
int size, Uint32 color);
void perspective_line(void * ptr_to_api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); void perspective_line(void *ptr_to_api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
static const int perspective_AMOUNT= 300; static const int perspective_AMOUNT = 300;
static const int perspective_RADIUS = 16; static const int perspective_RADIUS = 16;
static const double perspective_SHARPEN = 1.0; static const double perspective_SHARPEN = 1.0;
Uint8 perspective_r, perspective_g, perspective_b; Uint8 perspective_r, perspective_g, perspective_b;
@ -111,13 +109,15 @@ float top_advc_x, right_advc_x, bottom_advc_x, left_advc_x;
float top_advc_y, right_advc_y, bottom_advc_y, left_advc_y; float top_advc_y, right_advc_y, bottom_advc_y, left_advc_y;
enum { enum
{
TOOL_PERSPECTIVE, TOOL_PERSPECTIVE,
TOOL_ZOOM, TOOL_ZOOM,
perspective_NUM_TOOLS perspective_NUM_TOOLS
}; };
enum { enum
{
TOP_LEFT, TOP_LEFT,
TOP_RIGHT, TOP_RIGHT,
BOTTOM_RIGHT, BOTTOM_RIGHT,
@ -126,168 +126,181 @@ enum {
/* A copy of canvas at switchin, will be used to draw from it as snapshot changes at each click */ /* A copy of canvas at switchin, will be used to draw from it as snapshot changes at each click */
static SDL_Surface * canvas_back; static SDL_Surface *canvas_back;
static Mix_Chunk * perspective_snd_effect[perspective_NUM_TOOLS + 1]; static Mix_Chunk *perspective_snd_effect[perspective_NUM_TOOLS + 1];
const char * perspective_snd_filenames[perspective_NUM_TOOLS + 1] = { const char *perspective_snd_filenames[perspective_NUM_TOOLS + 1] = {
"perspective.ogg", "perspective.ogg",
"zoom_up.ogg", "zoom_up.ogg",
"zoom_down.ogg", "zoom_down.ogg",
}; };
const char * perspective_icon_filenames[perspective_NUM_TOOLS] = { const char *perspective_icon_filenames[perspective_NUM_TOOLS] = {
"perspective.png", "perspective.png",
"zoom.png", "zoom.png",
}; };
const char * perspective_names[perspective_NUM_TOOLS] = { const char *perspective_names[perspective_NUM_TOOLS] = {
gettext_noop("Perspective"), gettext_noop("Perspective"),
gettext_noop("Zoom"), gettext_noop("Zoom"),
}; };
const char * perspective_descs[perspective_NUM_TOOLS] = { const char *perspective_descs[perspective_NUM_TOOLS] = {
gettext_noop("Click on the corners and drag where you want to stretch the picture."), gettext_noop("Click on the corners and drag where you want to stretch the picture."),
gettext_noop("Click and drag up to zoom in or drag down to zoom out the picture."), gettext_noop("Click and drag up to zoom in or drag down to zoom out the picture."),
}; };
Uint32 perspective_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 perspective_api_version(void)
{
//Load sounds return (TP_MAGIC_API_VERSION);
int perspective_init(magic_api * api){
int i;
char fname[1024];
for (i = 0; i <= perspective_NUM_TOOLS; i++){
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, perspective_snd_filenames[i]);
perspective_snd_effect[i] = Mix_LoadWAV(fname);
}
return(1);
} }
int perspective_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ //Load sounds
return(perspective_NUM_TOOLS); int perspective_init(magic_api * api)
{
int i;
char fname[1024];
for (i = 0; i <= perspective_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, perspective_snd_filenames[i]);
perspective_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
}
int perspective_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{
return (perspective_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * perspective_get_icon(magic_api * api, int which){ SDL_Surface *perspective_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, perspective_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, perspective_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * perspective_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *perspective_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(perspective_names[which]))); {
return (strdup(gettext_noop(perspective_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * perspective_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED){ char *perspective_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
return(strdup(gettext_noop(perspective_descs[which]))); {
return (strdup(gettext_noop(perspective_descs[which])));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void perspective_drag(magic_api * api, int which, SDL_Surface * canvas, void perspective_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect){ SDL_Rect * update_rect)
{
switch (which) switch (which)
{ {
case TOOL_PERSPECTIVE: case TOOL_PERSPECTIVE:
{ {
switch (corner) switch (corner)
{ {
case TOP_LEFT: case TOP_LEFT:
{ {
top_left_x = x; top_left_x = x;
top_left_y = y; top_left_y = y;
} }
break; break;
case TOP_RIGHT: case TOP_RIGHT:
{ {
top_right_x = x; top_right_x = x;
top_right_y = y; top_right_y = y;
} }
break; break;
case BOTTOM_LEFT: case BOTTOM_LEFT:
{ {
bottom_left_x = x; bottom_left_x = x;
bottom_left_y = y; bottom_left_y = y;
} }
break; break;
case BOTTOM_RIGHT: case BOTTOM_RIGHT:
{ {
bottom_right_x = x; bottom_right_x = x;
bottom_right_y = y; bottom_right_y = y;
} }
break; break;
} }
SDL_BlitSurface(canvas_back, NULL, canvas, NULL); SDL_BlitSurface(canvas_back, NULL, canvas, NULL);
perspective_preview( api, which, perspective_preview(api, which, canvas, last, x, y, update_rect, 2.0);
canvas , last,
x, y , update_rect , 2.0);
/* Draw a square and the current shape relative to it as a visual reference */ /* Draw a square and the current shape relative to it as a visual reference */
/* square */ /* square */
api->line(api, which, canvas, last, otop_left_x, otop_left_y, otop_right_x, otop_right_y, 1, perspective_line); api->line(api, which, canvas, last, otop_left_x, otop_left_y, otop_right_x, otop_right_y, 1, perspective_line);
api->line(api, which, canvas, last, otop_left_x, otop_left_y, obottom_left_x, obottom_left_y, 1, perspective_line); api->line(api, which, canvas, last, otop_left_x, otop_left_y, obottom_left_x, obottom_left_y, 1,
api->line(api, which, canvas, last, obottom_left_x, obottom_left_y, obottom_right_x, obottom_right_y, 1, perspective_line); perspective_line);
api->line(api, which, canvas, last, obottom_right_x, obottom_right_y, otop_right_x, otop_right_y, 1, perspective_line); api->line(api, which, canvas, last, obottom_left_x, obottom_left_y, obottom_right_x, obottom_right_y, 1,
perspective_line);
api->line(api, which, canvas, last, obottom_right_x, obottom_right_y, otop_right_x, otop_right_y, 1,
perspective_line);
/* shape */ /* shape */
api->line(api, which, canvas, last, top_left_x, top_left_y, top_right_x, top_right_y, 1, perspective_line); api->line(api, which, canvas, last, top_left_x, top_left_y, top_right_x, top_right_y, 1, perspective_line);
api->line(api, which, canvas, last, top_left_x, top_left_y, bottom_left_x, bottom_left_y, 1, perspective_line); api->line(api, which, canvas, last, top_left_x, top_left_y, bottom_left_x, bottom_left_y, 1, perspective_line);
api->line(api, which, canvas, last, bottom_left_x, bottom_left_y, bottom_right_x, bottom_right_y, 1, perspective_line); api->line(api, which, canvas, last, bottom_left_x, bottom_left_y, bottom_right_x, bottom_right_y, 1,
api->line(api, which, canvas, last, bottom_right_x, bottom_right_y, top_right_x, top_right_y, 1, perspective_line); perspective_line);
api->line(api, which, canvas, last, bottom_right_x, bottom_right_y, top_right_x, top_right_y, 1,
perspective_line);
api->playsound(perspective_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(perspective_snd_effect[which], (x * 255) / canvas->w, 255);
} }
break; break;
case TOOL_ZOOM: case TOOL_ZOOM:
{ {
int x_distance, y_distance; int x_distance, y_distance;
update_rect->x = update_rect->y = 0; update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b));
new_h = max(1, old_h + click_y - y); new_h = max(1, old_h + click_y - y);
new_w = canvas->w * new_h / canvas->h; new_w = canvas->w * new_h / canvas->h;
if (new_h >= sound_h) if (new_h >= sound_h)
api->playsound(perspective_snd_effect[which], 127, 255); api->playsound(perspective_snd_effect[which], 127, 255);
else else
api->playsound(perspective_snd_effect[which + 1], 127, 255); api->playsound(perspective_snd_effect[which + 1], 127, 255);
sound_h = new_h; sound_h = new_h;
x_distance = (otop_right_x - otop_left_x) * new_w / canvas->w; x_distance = (otop_right_x - otop_left_x) * new_w / canvas->w;
top_left_x = bottom_left_x = canvas->w / 2 - x_distance / 2; top_left_x = bottom_left_x = canvas->w / 2 - x_distance / 2;
top_right_x = bottom_right_x = canvas->w / 2 + x_distance / 2; top_right_x = bottom_right_x = canvas->w / 2 + x_distance / 2;
y_distance = (obottom_left_y - otop_left_y) * new_w / canvas->w; y_distance = (obottom_left_y - otop_left_y) * new_w / canvas->w;
top_left_y = top_right_y = canvas->h / 2 - y_distance / 2; top_left_y = top_right_y = canvas->h / 2 - y_distance / 2;
bottom_left_y = bottom_right_y = canvas->h / 2 + y_distance / 2; bottom_left_y = bottom_right_y = canvas->h / 2 + y_distance / 2;
perspective_preview( api, which, perspective_preview(api, which, canvas, last, x, y, update_rect, 2.0);
canvas , last,
x, y , update_rect , 2.0);
update_rect->x = update_rect->y =0; update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
} }
break; break;
@ -303,43 +316,44 @@ void perspective_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void perspective_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void perspective_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
switch(which) switch (which)
{case TOOL_PERSPECTIVE: {
{ case TOOL_PERSPECTIVE:
{
if (x < canvas->w / 2) if (x < canvas->w / 2)
{ {
if (y < canvas->h / 2) if (y < canvas->h / 2)
{ {
corner = TOP_LEFT; corner = TOP_LEFT;
} }
else else
{ {
corner = BOTTOM_LEFT; corner = BOTTOM_LEFT;
} }
} }
else else
{ {
if (y < canvas->h / 2) if (y < canvas->h / 2)
{ {
corner = TOP_RIGHT; corner = TOP_RIGHT;
} }
else else
{ {
corner = BOTTOM_RIGHT; corner = BOTTOM_RIGHT;
} }
} }
} }
break; break;
case TOOL_ZOOM: case TOOL_ZOOM:
{ {
click_x = x; click_x = x;
click_y = y; click_y = y;
old_h = new_h; old_h = new_h;
} }
break; break;
} }
@ -349,70 +363,67 @@ void perspective_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release: // Affect the canvas on release:
void perspective_release(magic_api * api, int which, void perspective_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
switch (which) switch (which)
{ {
case TOOL_PERSPECTIVE:{ case TOOL_PERSPECTIVE:
perspective_preview( api, which, {
canvas , last, perspective_preview(api, which, canvas, last, x, y, update_rect, 0.5);
x, y , update_rect , 0.5); }
}
break; break;
case TOOL_ZOOM: case TOOL_ZOOM:
{ {
SDL_Surface * aux_surf; SDL_Surface *aux_surf;
SDL_Surface * scaled_surf; SDL_Surface *scaled_surf;
update_rect->x = update_rect->y = 0; update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b));
if(new_h < canvas->h) if (new_h < canvas->h)
{ {
scaled_surf = api->scale(canvas_back, new_w, new_h, 0); scaled_surf = api->scale(canvas_back, new_w, new_h, 0);
update_rect->x = (canvas->w - new_w) / 2; update_rect->x = (canvas->w - new_w) / 2;
update_rect->y = (canvas->h - new_h) / 2; update_rect->y = (canvas->h - new_h) / 2;
update_rect->w = new_w; update_rect->w = new_w;
update_rect->h = new_h; update_rect->h = new_h;
SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect); SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect);
} }
else else
{ {
int aux_x, aux_y, aux_h, aux_w; int aux_x, aux_y, aux_h, aux_w;
aux_h = canvas->h * canvas->h / new_h;
aux_w = canvas->w * aux_h / canvas->h;
aux_x = canvas->w / 2 - aux_w / 2;
aux_y = canvas->h / 2 - aux_h / 2;
update_rect->x = canvas->w / 2 - aux_w / 2; aux_h = canvas->h * canvas->h / new_h;
update_rect->y = canvas->h / 2 - aux_h / 2; aux_w = canvas->w * aux_h / canvas->h;
update_rect->w = aux_w; aux_x = canvas->w / 2 - aux_w / 2;
update_rect->h = aux_h; aux_y = canvas->h / 2 - aux_h / 2;
aux_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, update_rect->x = canvas->w / 2 - aux_w / 2;
aux_w, update_rect->y = canvas->h / 2 - aux_h / 2;
aux_h, update_rect->w = aux_w;
canvas->format->BitsPerPixel, update_rect->h = aux_h;
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask, 0);
SDL_BlitSurface(canvas_back, update_rect, aux_surf, NULL); aux_surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
scaled_surf = api->scale(aux_surf, canvas->w, canvas->h, 0); aux_w,
SDL_BlitSurface(scaled_surf, NULL, canvas, NULL); aux_h,
SDL_FreeSurface(aux_surf); canvas->format->BitsPerPixel,
} canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, 0);
SDL_FreeSurface(scaled_surf);
update_rect->x = update_rect->y = 0; SDL_BlitSurface(canvas_back, update_rect, aux_surf, NULL);
update_rect->w = canvas->w; scaled_surf = api->scale(aux_surf, canvas->w, canvas->h, 0);
update_rect->h = canvas->h; SDL_BlitSurface(scaled_surf, NULL, canvas, NULL);
SDL_FreeSurface(aux_surf);
}
SDL_FreeSurface(scaled_surf);
update_rect->x = update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
} }
break; break;
@ -420,8 +431,8 @@ void perspective_release(magic_api * api, int which,
} }
void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED, void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect, float step) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect, float step)
{ {
float i, j; float i, j;
float ax, ay, bx, by, dx, dy; float ax, ay, bx, by, dx, dy;
@ -437,7 +448,7 @@ void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED,
ox_distance = otop_right_x - otop_left_x; ox_distance = otop_right_x - otop_left_x;
oy_distance = obottom_left_y - otop_left_y; oy_distance = obottom_left_y - otop_left_y;
top_advc_x = (float)(top_right_x - top_left_x) / ox_distance; top_advc_x = (float)(top_right_x - top_left_x) / ox_distance;
top_advc_y = (float)(top_right_y - top_left_y) / ox_distance; top_advc_y = (float)(top_right_y - top_left_y) / ox_distance;
@ -454,21 +465,21 @@ void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED,
center_ofset_x = (otop_left_x - top_left_x) * 2; center_ofset_x = (otop_left_x - top_left_x) * 2;
center_ofset_y = (otop_left_y - top_left_y) * 2; center_ofset_y = (otop_left_y - top_left_y) * 2;
for(i = 0; i < canvas->w; i += step) for (i = 0; i < canvas->w; i += step)
{ {
ax = (float)top_advc_x * i; ax = (float)top_advc_x *i;
ay = (float)top_advc_y * i; ay = (float)top_advc_y *i;
bx = (float)bottom_advc_x * i + (bottom_left_x - top_left_x) * 2 ; bx = (float)bottom_advc_x *i + (bottom_left_x - top_left_x) * 2;
by = (float)bottom_advc_y * i + (bottom_left_y - top_left_y) * 2; by = (float)bottom_advc_y *i + (bottom_left_y - top_left_y) * 2;
for(j = 0; j < canvas->h; j += step) for (j = 0; j < canvas->h; j += step)
{ {
dx = (float)(bx - ax) / canvas->h * j; dx = (float)(bx - ax) / canvas->h * j;
dy = (float)(by - ay)/ canvas->h * j; dy = (float)(by - ay) / canvas->h * j;
api->putpixel(canvas, ax + dx - center_ofset_x, ay + dy - center_ofset_y, api->getpixel(canvas_back, i, j)); api->putpixel(canvas, ax + dx - center_ofset_x, ay + dy - center_ofset_y, api->getpixel(canvas_back, i, j));
} }
} }
} }
// No setup happened: // No setup happened:
@ -476,11 +487,14 @@ void perspective_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<perspective_NUM_TOOLS + 1; i++){
if(perspective_snd_effect[i] != NULL){ for (i = 0; i < perspective_NUM_TOOLS + 1; i++)
Mix_FreeChunk(perspective_snd_effect[i]); {
if (perspective_snd_effect[i] != NULL)
{
Mix_FreeChunk(perspective_snd_effect[i]);
}
} }
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
@ -497,9 +511,11 @@ int perspective_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTR
return 1; return 1;
} }
void perspective_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) void perspective_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{ {
Uint32 amask; Uint32 amask;
new_w = canvas->w; new_w = canvas->w;
new_h = canvas->h; new_h = canvas->h;
@ -513,36 +529,36 @@ void perspective_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
black = SDL_MapRGBA(canvas->format, 0, 0, 0, 0); black = SDL_MapRGBA(canvas->format, 0, 0, 0, 0);
white = SDL_MapRGBA(canvas->format, 255, 255, 255, 0); white = SDL_MapRGBA(canvas->format, 255, 255, 255, 0);
amask = ~(canvas->format->Rmask | amask = ~(canvas->format->Rmask | canvas->format->Gmask | canvas->format->Bmask);
canvas->format->Gmask |
canvas->format->Bmask);
canvas_back = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas_back = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w, canvas->w,
canvas->h, canvas->h,
canvas->format->BitsPerPixel, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, amask);
canvas->format->Gmask,
canvas->format->Bmask, amask);
SDL_BlitSurface(canvas, NULL, canvas_back, NULL); SDL_BlitSurface(canvas, NULL, canvas_back, NULL);
} }
void perspective_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void perspective_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
SDL_FreeSurface(canvas_back); SDL_FreeSurface(canvas_back);
} }
int perspective_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int perspective_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }
void perspective_line(void * ptr_to_api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) void perspective_line(void *ptr_to_api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr_to_api; magic_api *api = (magic_api *) ptr_to_api;
dash += 1; dash += 1;
if (dash > 8) dash = 0; if (dash > 8)
dash = 0;
if (dash > 3) if (dash > 3)
api->putpixel(canvas, x, y, black); api->putpixel(canvas, x, y, black);
else else

View file

@ -27,12 +27,12 @@
*/ */
#include <time.h> //for time() #include <time.h> //for time()
#include "tp_magic_api.h" #include "tp_magic_api.h"
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
#define RATIO 5 //change this value to get bigger puzzle #define RATIO 5 //change this value to get bigger puzzle
//TODO: Fullscreen mode //TODO: Fullscreen mode
//In fullscreen mode RATIO _should_ be 1 //In fullscreen mode RATIO _should_ be 1
@ -40,49 +40,48 @@
//else not whole the screen will be affected //else not whole the screen will be affected
static Mix_Chunk * puzzle_snd; static Mix_Chunk *puzzle_snd;
static int puzzle_gcd=0; //length of side of each rectangle; 0 is temporary value. static int puzzle_gcd = 0; //length of side of each rectangle; 0 is temporary value.
// static int puzzle_rect_q=4; //quantity of rectangles when using paint mode. Must be an odd value - but it's even!
static int rects_w, rects_h;
SDL_Surface * canvas_backup;
Uint32 puzzle_api_version(void) ; // static int puzzle_rect_q=4; //quantity of rectangles when using paint mode. Must be an odd value - but it's even!
static int rects_w, rects_h;
SDL_Surface *canvas_backup;
Uint32 puzzle_api_version(void);
int puzzle_init(magic_api * api); int puzzle_init(magic_api * api);
int puzzle_get_tool_count(magic_api * api); int puzzle_get_tool_count(magic_api * api);
SDL_Surface * puzzle_get_icon(magic_api * api, int which); SDL_Surface *puzzle_get_icon(magic_api * api, int which);
char * puzzle_get_name(magic_api * api, int which); char *puzzle_get_name(magic_api * api, int which);
char * puzzle_get_description(magic_api * api, int which, int mode); char *puzzle_get_description(magic_api * api, int which, int mode);
void puzzle_release(magic_api * api, int which, void puzzle_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void puzzle_shutdown(magic_api * api); void puzzle_shutdown(magic_api * api);
void puzzle_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void puzzle_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int puzzle_requires_colors(magic_api * api, int which); int puzzle_requires_colors(magic_api * api, int which);
void puzzle_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void puzzle_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void puzzle_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void puzzle_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int puzzle_modes(magic_api * api, int which); int puzzle_modes(magic_api * api, int which);
static void puzzle_draw(void * ptr, int which_tool, static void puzzle_draw(void *ptr, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas, void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void puzzle_click(magic_api * api, int which, int mode, void puzzle_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
int gcd(int a, int b); int gcd(int a, int b);
Uint32 puzzle_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 puzzle_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
int puzzle_init(magic_api * api) int puzzle_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/puzzle.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/puzzle.wav", api->data_directory);
api->data_directory);
puzzle_snd = Mix_LoadWAV(fname); puzzle_snd = Mix_LoadWAV(fname);
return 1 ; return 1;
} }
int puzzle_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int puzzle_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -90,32 +89,31 @@ int puzzle_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * puzzle_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *puzzle_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/puzzle.png", snprintf(fname, sizeof(fname), "%s/images/magic/puzzle.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * puzzle_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *puzzle_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Puzzle"))); return (strdup(gettext_noop("Puzzle")));
} }
char * puzzle_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) char *puzzle_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
{ {
if (mode==MODE_PAINT) if (mode == MODE_PAINT)
return strdup(gettext_noop("Click the part of your picture where would you like a puzzle.")); return strdup(gettext_noop("Click the part of your picture where would you like a puzzle."));
return strdup(gettext_noop("Click to make a puzzle in fullscreen mode.")); return strdup(gettext_noop("Click to make a puzzle in fullscreen mode."));
} }
void puzzle_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void puzzle_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -125,7 +123,8 @@ void puzzle_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(puzzle_snd); Mix_FreeChunk(puzzle_snd);
} }
void puzzle_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void puzzle_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -134,21 +133,26 @@ int puzzle_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
return 0; return 0;
} }
int gcd(int a, int b) //greatest common divisor int gcd(int a, int b) //greatest common divisor
{ {
if (b==0) return a; if (b == 0)
return gcd(b, a%b); return a;
return gcd(b, a % b);
} }
void puzzle_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) void puzzle_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{ {
puzzle_gcd=RATIO*gcd(canvas->w, canvas->h); puzzle_gcd = RATIO * gcd(canvas->w, canvas->h);
rects_w=(unsigned int)canvas->w/puzzle_gcd; rects_w = (unsigned int)canvas->w / puzzle_gcd;
rects_h=(unsigned int)canvas->h/puzzle_gcd; rects_h = (unsigned int)canvas->h / puzzle_gcd;
canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE,canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas_backup =
SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas->format->Rmask,
canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask);
} }
void puzzle_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void puzzle_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
SDL_FreeSurface(canvas_backup); SDL_FreeSurface(canvas_backup);
canvas_backup = NULL; canvas_backup = NULL;
@ -156,17 +160,17 @@ void puzzle_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUS
int puzzle_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int puzzle_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }
static void puzzle_draw(void * ptr, int which_tool ATTRIBUTE_UNUSED, static void puzzle_draw(void *ptr, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r; //r - random value Uint8 r; //r - random value
SDL_Rect rect_this, rect_that; SDL_Rect rect_this, rect_that;
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
@ -175,70 +179,68 @@ static void puzzle_draw(void * ptr, int which_tool ATTRIBUTE_UNUSED,
y = (y / puzzle_gcd) * puzzle_gcd; y = (y / puzzle_gcd) * puzzle_gcd;
if (!api->touched(x, y)) if (!api->touched(x, y))
{ {
srand(rand()); srand(rand());
r=rand()%4;
rect_that.x=x;
rect_that.y=y;
switch(r)
{
case 0: //upper
if (y>puzzle_gcd)
rect_that.y=y-puzzle_gcd;
break;
case 1: //right
if (x<canvas->w-puzzle_gcd)
rect_that.x=x-puzzle_gcd;
break;
case 2: //lower
if (y<canvas->h-puzzle_gcd)
rect_that.y=y-puzzle_gcd;
break;
case 3: //left
if (x>puzzle_gcd)
rect_that.x=x-puzzle_gcd;
break;
}
rect_this.x=x;
rect_this.y=y;
rect_this.h=rect_this.w=puzzle_gcd;
rect_that.h=rect_that.w=puzzle_gcd;
r = rand() % 4;
SDL_BlitSurface(canvas, &rect_this, canvas, &rect_that);
SDL_BlitSurface(canvas_backup, &rect_that, canvas, &rect_this); rect_that.x = x;
api->playsound(puzzle_snd, (x * 255) / canvas->w, 255); rect_that.y = y;
}
switch (r)
{
case 0: //upper
if (y > puzzle_gcd)
rect_that.y = y - puzzle_gcd;
break;
case 1: //right
if (x < canvas->w - puzzle_gcd)
rect_that.x = x - puzzle_gcd;
break;
case 2: //lower
if (y < canvas->h - puzzle_gcd)
rect_that.y = y - puzzle_gcd;
break;
case 3: //left
if (x > puzzle_gcd)
rect_that.x = x - puzzle_gcd;
break;
}
rect_this.x = x;
rect_this.y = y;
rect_this.h = rect_this.w = puzzle_gcd;
rect_that.h = rect_that.w = puzzle_gcd;
SDL_BlitSurface(canvas, &rect_this, canvas, &rect_that);
SDL_BlitSurface(canvas_backup, &rect_that, canvas, &rect_this);
api->playsound(puzzle_snd, (x * 255) / canvas->w, 255);
}
} }
void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas, void puzzle_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
puzzle_draw(api, which, canvas, last, x-puzzle_gcd/2, y-puzzle_gcd/2); puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x-1.5*puzzle_gcd/2, y-puzzle_gcd/2); puzzle_draw(api, which, canvas, last, x - 1.5 * puzzle_gcd / 2, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x+0.5*puzzle_gcd, y-puzzle_gcd/2); puzzle_draw(api, which, canvas, last, x + 0.5 * puzzle_gcd, y - puzzle_gcd / 2);
puzzle_draw(api, which, canvas, last, x-puzzle_gcd/2, y-1.5*puzzle_gcd); puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y - 1.5 * puzzle_gcd);
puzzle_draw(api, which, canvas, last, x-puzzle_gcd/2, y+0.5*puzzle_gcd); puzzle_draw(api, which, canvas, last, x - puzzle_gcd / 2, y + 0.5 * puzzle_gcd);
update_rect->x=0; update_rect->x = 0;
update_rect->y=0; update_rect->y = 0;
update_rect->h=canvas->h; update_rect->h = canvas->h;
update_rect->w=canvas->w; update_rect->w = canvas->w;
} }
void puzzle_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void puzzle_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
puzzle_drag(api, which, canvas, last, x, y, x, y, update_rect); puzzle_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }

View file

@ -21,96 +21,94 @@
#define SEG_RIGHT_TOP_BOTTOM (SEG_RIGHT | SEG_TOP | SEG_BOTTOM) #define SEG_RIGHT_TOP_BOTTOM (SEG_RIGHT | SEG_TOP | SEG_BOTTOM)
#define SEG_LEFT_RIGHT_TOP_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_TOP | SEG_BOTTOM) #define SEG_LEFT_RIGHT_TOP_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_TOP | SEG_BOTTOM)
Mix_Chunk * rails_snd; Mix_Chunk *rails_snd;
unsigned int img_w, img_h; unsigned int img_w, img_h;
unsigned int rails_segments_x, rails_segments_y; //how many segments do we have? unsigned int rails_segments_x, rails_segments_y; //how many segments do we have?
static int rails_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one static int rails_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one
static Uint8 * rails_status_of_segments; //a place to store an info about bitmap used for selected segment static Uint8 *rails_status_of_segments; //a place to store an info about bitmap used for selected segment
static char ** rails_images; //the pathes to all the images needed static char **rails_images; //the pathes to all the images needed
static unsigned int rails_segment_modified; //which segment was modified this time? static unsigned int rails_segment_modified; //which segment was modified this time?
static unsigned int rails_segment_modified_last =0; //which segment was last modified static unsigned int rails_segment_modified_last = 0; //which segment was last modified
static unsigned int rails_segment_to_add =0; //a segment that should be added to solve corner joints static unsigned int rails_segment_to_add = 0; //a segment that should be added to solve corner joints
static SDL_Rect modification_rect; static SDL_Rect modification_rect;
static SDL_Surface * canvas_backup; static SDL_Surface *canvas_backup;
// Housekeeping functions
SDL_Surface * rails_one, * rails_three, * rails_four, * rails_corner; // Housekeeping functions
SDL_Surface *rails_one, *rails_three, *rails_four, *rails_corner;
Uint32 rails_api_version(void); Uint32 rails_api_version(void);
int rails_modes(magic_api * api, int which); int rails_modes(magic_api * api, int which);
void rails_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void rails_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int rails_init(magic_api * api); int rails_init(magic_api * api);
int rails_get_tool_count(magic_api * api); int rails_get_tool_count(magic_api * api);
SDL_Surface * rails_get_icon(magic_api * api, int which); SDL_Surface *rails_get_icon(magic_api * api, int which);
char * rails_get_name(magic_api * api, int which); char *rails_get_name(magic_api * api, int which);
char * rails_get_description(magic_api * api, int which, int mode); char *rails_get_description(magic_api * api, int which, int mode);
int rails_requires_colors(magic_api * api, int which); int rails_requires_colors(magic_api * api, int which);
void rails_release(magic_api * api, int which, void rails_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void rails_shutdown(magic_api * api); void rails_shutdown(magic_api * api);
void rails_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void rails_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rails_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void rails_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
static int rails_math_ceil(int x, int y); static int rails_math_ceil(int x, int y);
inline unsigned int rails_get_segment(int x, int y); inline unsigned int rails_get_segment(int x, int y);
inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y); inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y);
static void rails_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src); static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src);
static void rails_flip_flop(void * ptr, SDL_Surface * dest, SDL_Surface * src); static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src);
static void rails_rotate (void * ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction); static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction);
void rails_click(magic_api * api, int which, int mode, void rails_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
static Uint8 rails_select_image(Uint16 segment); static Uint8 rails_select_image(Uint16 segment);
static void rails_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void rails_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y, unsigned int segment); int x, int y, unsigned int segment);
static void rails_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void rails_drag(magic_api * api, int which, SDL_Surface * canvas, void rails_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
Uint32 rails_api_version(void) Uint32 rails_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
int rails_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int rails_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }
void rails_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void rails_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
int rails_init(magic_api * api) int rails_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
Uint8 i; //is always < 3, so Uint8 seems to be a good idea Uint8 i; //is always < 3, so Uint8 seems to be a good idea
rails_images=(char **)malloc(sizeof(char *)*4);
for (i = 0; i < 4; i++)
rails_images[i]=(char *)malloc(sizeof(char)*1024);
snprintf(rails_images[0], 1024*sizeof(char), "%s/images/magic/rails_one.png", api->data_directory);
snprintf(rails_images[1], 1024*sizeof(char), "%s/images/magic/rails_three.png", api->data_directory);
snprintf(rails_images[2], 1024*sizeof(char), "%s/images/magic/rails_four.png", api->data_directory);
snprintf(rails_images[3], 1024*sizeof(char), "%s/images/magic/rails_corner.png", api->data_directory);
rails_one=IMG_Load(rails_images[0]); rails_images = (char **)malloc(sizeof(char *) * 4);
rails_three=IMG_Load(rails_images[1]);
rails_four=IMG_Load(rails_images[2]);
rails_corner=IMG_Load(rails_images[3]);
img_w = rails_one->w; for (i = 0; i < 4; i++)
img_h = rails_one->h; rails_images[i] = (char *)malloc(sizeof(char) * 1024);
snprintf(fname, sizeof(fname), "%s/sounds/magic/rails.wav", api->data_directory);
rails_snd = Mix_LoadWAV(fname);
return(1); snprintf(rails_images[0], 1024 * sizeof(char), "%s/images/magic/rails_one.png", api->data_directory);
snprintf(rails_images[1], 1024 * sizeof(char), "%s/images/magic/rails_three.png", api->data_directory);
snprintf(rails_images[2], 1024 * sizeof(char), "%s/images/magic/rails_four.png", api->data_directory);
snprintf(rails_images[3], 1024 * sizeof(char), "%s/images/magic/rails_corner.png", api->data_directory);
rails_one = IMG_Load(rails_images[0]);
rails_three = IMG_Load(rails_images[1]);
rails_four = IMG_Load(rails_images[2]);
rails_corner = IMG_Load(rails_images[3]);
img_w = rails_one->w;
img_h = rails_one->h;
snprintf(fname, sizeof(fname), "%s/sounds/magic/rails.wav", api->data_directory);
rails_snd = Mix_LoadWAV(fname);
return (1);
} }
int rails_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int rails_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -118,407 +116,434 @@ int rails_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 1; return 1;
} }
SDL_Surface * rails_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *rails_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/rails.png", snprintf(fname, sizeof(fname), "%s/images/magic/rails.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * rails_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Rails")); } char *rails_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Rails"));
}
char * rails_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Click and drag to draw train track rails on your picture.")); } char *rails_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("Click and drag to draw train track rails on your picture."));
}
int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 0;} int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 0;
}
void rails_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void rails_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void rails_shutdown(magic_api * api ATTRIBUTE_UNUSED) void rails_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
Uint8 i; Uint8 i;
if (rails_snd!=NULL) if (rails_snd != NULL)
Mix_FreeChunk(rails_snd); Mix_FreeChunk(rails_snd);
SDL_FreeSurface(rails_one); SDL_FreeSurface(rails_one);
SDL_FreeSurface(rails_three); SDL_FreeSurface(rails_three);
SDL_FreeSurface(rails_four); SDL_FreeSurface(rails_four);
SDL_FreeSurface(rails_corner); SDL_FreeSurface(rails_corner);
SDL_FreeSurface(canvas_backup); SDL_FreeSurface(canvas_backup);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
free(rails_images[i]); free(rails_images[i]);
free(rails_images); free(rails_images);
if (rails_status_of_segments != NULL) if (rails_status_of_segments != NULL)
free(rails_status_of_segments); free(rails_status_of_segments);
} }
void rails_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) void rails_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas)
{ {
//we've to compute the quantity of segments in each direction //we've to compute the quantity of segments in each direction
canvas_backup=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
rails_segments_x=rails_math_ceil(canvas->w,img_w); rails_segments_x = rails_math_ceil(canvas->w, img_w);
rails_segments_y=rails_math_ceil(canvas->h,img_h); rails_segments_y = rails_math_ceil(canvas->h, img_h);
//status_of_segments[0] will not be used, we write in rails_status_of_segments[1 to segments_x*segments_y] //status_of_segments[0] will not be used, we write in rails_status_of_segments[1 to segments_x*segments_y]
rails_status_of_segments=(Uint8 *)calloc(rails_segments_x*rails_segments_y + 1, sizeof(Uint8)); rails_status_of_segments = (Uint8 *) calloc(rails_segments_x * rails_segments_y + 1, sizeof(Uint8));
} }
void rails_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rails_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
if (rails_status_of_segments != NULL) if (rails_status_of_segments != NULL)
{ {
free(rails_status_of_segments); free(rails_status_of_segments);
rails_status_of_segments = NULL; rails_status_of_segments = NULL;
} }
} }
// Interactivity functions // Interactivity functions
static int rails_math_ceil(int x, int y) static int rails_math_ceil(int x, int y)
{
int temp;
temp=(int)x/y;
if (x%y)
return temp+1;
else return temp;
}
inline unsigned int rails_get_segment(int x, int y)
{ {
int xx; //segments are numerated just like pixels int temp;
int yy; //in computer graphics: left upper (=1), ... ,right upper,
//left bottom, ... , right bottom temp = (int)x / y;
xx=rails_math_ceil(x, img_w);
yy=rails_math_ceil(y, img_h); if (x % y)
return temp + 1;
return (yy-1)*rails_segments_x+xx; else
return temp;
}
inline unsigned int rails_get_segment(int x, int y)
{
int xx; //segments are numerated just like pixels
int yy; //in computer graphics: left upper (=1), ... ,right upper,
//left bottom, ... , right bottom
xx = rails_math_ceil(x, img_w);
yy = rails_math_ceil(y, img_h);
return (yy - 1) * rails_segments_x + xx;
} }
inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y) inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y)
{ //extracts the coords of the beginning and the segment { //extracts the coords of the beginning and the segment
*x=((segment%rails_segments_x)-1)*img_w; //useful to set update_rect as small as possible *x = ((segment % rails_segments_x) - 1) * img_w; //useful to set update_rect as small as possible
*y=(int)(segment/rails_segments_x)*img_h; *y = (int)(segment / rails_segments_x) * img_h;
} }
static void rails_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src) static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Sint16 x, y;
for (x=0; x<dest->w; x++)
for (y=0; y<dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, x, src->h-y-1));
}
static void rails_flip_flop(void * ptr, SDL_Surface * dest, SDL_Surface * src)
{
magic_api * api = (magic_api *) ptr;
Sint16 x, y; Sint16 x, y;
for (x=0; x<dest->w; x++)
for (y=0; y<dest->h; y++) for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, x, src->h - y - 1));
}
static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src)
{
magic_api *api = (magic_api *) ptr;
Sint16 x, y;
for (x = 0; x < dest->w; x++)
for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, x)); api->putpixel(dest, x, y, api->getpixel(src, y, x));
} }
static void rails_rotate (void * ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction) static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction)
//src and dest must have same size //src and dest must have same size
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Sint16 x,y; Sint16 x, y;
if (direction) //rotate -90 degs if (direction) //rotate -90 degs
{ {
for (x = 0; x<dest->w; x++) for (x = 0; x < dest->w; x++)
for (y =0; y<dest->h; y++) for (y = 0; y < dest->h; y++)
api->putpixel(dest, x, y, api->getpixel(src, y, src->w-x-1)); api->putpixel(dest, x, y, api->getpixel(src, y, src->w - x - 1));
} }
else //rotate +90 degs else //rotate +90 degs
{ {
for (x=0; x<dest->w; x++) for (x = 0; x < dest->w; x++)
for (y=0; y<dest->h; y++) for (y = 0; y < dest->h; y++)
api->putpixel(dest,x,y,api->getpixel(src,src->h-y-1,x)); api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x));
} }
} }
void rails_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void rails_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
rails_segment_modified_last = 0; rails_segment_modified_last = 0;
rails_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); rails_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
static Uint8 rails_select_image(Uint16 segment) static Uint8 rails_select_image(Uint16 segment)
{ {
int take_up, take_down; int take_up, take_down;
int val_up, val_down, val_left, val_right; int val_up, val_down, val_left, val_right;
int from_top=0, from_bottom=0, from_left = 0, from_right = 0; int from_top = 0, from_bottom = 0, from_left = 0, from_right = 0;
int from_top_right=0, from_top_left=0, from_bottom_right=0, from_bottom_left = 0; int from_top_right = 0, from_top_left = 0, from_bottom_right = 0, from_bottom_left = 0;
int TOP=0, BOTTOM=0, LEFT=0, RIGHT = 0; int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0;
//Checking from were we come...
if (rails_segment_modified_last>0)
{
if (segment == rails_segment_modified_last + 1)
from_left = 1;
if (segment == rails_segment_modified_last - 1) //Checking from were we come...
from_right = 1; if (rails_segment_modified_last > 0)
{
if (segment == rails_segment_modified_last + 1)
from_left = 1;
if (segment == rails_segment_modified_last - rails_segments_x) if (segment == rails_segment_modified_last - 1)
from_bottom = 1; from_right = 1;
if (segment == rails_segment_modified_last + rails_segments_x) if (segment == rails_segment_modified_last - rails_segments_x)
from_top = 1; from_bottom = 1;
// Segments are joining by the corner if (segment == rails_segment_modified_last + rails_segments_x)
// We need to add a new segment to join by side, adding clockwise from_top = 1;
if (segment == rails_segment_modified_last + rails_segments_x + 1)
{
from_top_left = 1;
rails_segment_to_add = segment - rails_segments_x;
}
if (segment == rails_segment_modified_last + rails_segments_x - 1) // Segments are joining by the corner
{ // We need to add a new segment to join by side, adding clockwise
from_top_right = 1; if (segment == rails_segment_modified_last + rails_segments_x + 1)
rails_segment_to_add = segment + 1; {
} from_top_left = 1;
rails_segment_to_add = segment - rails_segments_x;
}
if (segment == rails_segment_modified_last - rails_segments_x - 1) if (segment == rails_segment_modified_last + rails_segments_x - 1)
{ {
from_bottom_right = 1; from_top_right = 1;
rails_segment_to_add = segment + rails_segments_x; rails_segment_to_add = segment + 1;
} }
if (segment == rails_segment_modified_last - rails_segments_x + 1)
{
from_bottom_left = 1;
rails_segment_to_add = segment -1;
}
}
if (segment == rails_segment_modified_last - rails_segments_x - 1)
{
from_bottom_right = 1;
rails_segment_to_add = segment + rails_segments_x;
take_up=segment-rails_segments_x; }
if (take_up<=0) val_up = SEG_NONE; if (segment == rails_segment_modified_last - rails_segments_x + 1)
else val_up = rails_status_of_segments[take_up]; {
from_bottom_left = 1;
take_down=segment+rails_segments_x; rails_segment_to_add = segment - 1;
if (take_down>(signed)(rails_segments_x*rails_segments_y)) val_down = SEG_NONE; }
else val_down = rails_status_of_segments[take_down];
if ((segment%rails_segments_x)==1) val_left=SEG_NONE;
else val_left = rails_status_of_segments[segment-1];
if ((segment%rails_segments_x)==0) val_right=SEG_NONE;
else val_right = rails_status_of_segments[segment+1];
if ( from_left || (val_left & SEG_RIGHT) || from_bottom_left)
{
LEFT = 1;}
if ( from_right || (val_right & SEG_LEFT) || from_top_right)
RIGHT=1;
if ( from_top || (val_up & SEG_BOTTOM) || from_top_left)
TOP=1;
if (from_bottom || (val_down & SEG_TOP) || from_bottom_right)
BOTTOM=1;
if (TOP && BOTTOM && LEFT && RIGHT)
return SEG_LEFT_RIGHT_TOP_BOTTOM;
if (LEFT && RIGHT && TOP)
return SEG_LEFT_RIGHT_TOP;
if (LEFT && RIGHT && BOTTOM)
return SEG_LEFT_RIGHT_BOTTOM;
if (TOP && BOTTOM && LEFT)
return SEG_LEFT_TOP_BOTTOM;
if (TOP && BOTTOM && RIGHT)
return SEG_RIGHT_TOP_BOTTOM;
if (LEFT &&RIGHT)
return SEG_LEFT_RIGHT;
if (TOP&&BOTTOM)
return SEG_TOP_BOTTOM;
if (LEFT&&TOP)
return SEG_LEFT_TOP;
if (LEFT&&BOTTOM)
return SEG_LEFT_BOTTOM;
if (RIGHT&&TOP)
return SEG_RIGHT_TOP;
if (RIGHT&&BOTTOM)
return SEG_RIGHT_BOTTOM;
if (LEFT|RIGHT)
return SEG_LEFT_RIGHT;
return SEG_TOP_BOTTOM;
}
static void rails_draw(void * ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y ATTRIBUTE_UNUSED, unsigned int segment)
{
magic_api * api = (magic_api *) ptr;
SDL_Surface * result, * temp;
Uint8 image;
unsigned int use_temp;
use_temp=0;
if (segment>rails_segments_x*rails_segments_y)
return;
//modification_rect.x and modification_rect.y are set by function
rails_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y);
modification_rect.h=img_w;
modification_rect.w=img_h;
image=rails_select_image(segment); //select the image to display
if (rails_status_of_segments[segment] == image)
return;
rails_status_of_segments[segment]=image; //and write it to global table
result=SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, rails_one->format->Amask);
temp=SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, rails_one->format->Amask);
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
switch(image)
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_one, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
rails_rotate(api, temp, rails_one, 1);
use_temp=1;
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(rails_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_BOTTOM:
rails_flip(api, temp, rails_three);
use_temp=1;
break;
case SEG_LEFT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 0);
use_temp=1;
break;
case SEG_RIGHT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 1);
use_temp=1;
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(rails_corner, NULL, result, NULL);
break;
case SEG_RIGHT_BOTTOM:
rails_flip(api, temp, rails_corner);
use_temp=1;
break;
case SEG_LEFT_TOP:
rails_rotate(api, temp, rails_corner, 0);
use_temp=1;
break;
case SEG_LEFT_BOTTOM:
rails_flip_flop(api, temp, rails_corner);
use_temp=1;
break;
}
if (use_temp)
SDL_BlitSurface(temp, NULL, result, NULL);
SDL_FreeSurface(temp);
SDL_BlitSurface(result, NULL, canvas, &modification_rect);
SDL_FreeSurface(result);
api->playsound(rails_snd, (x * 255) / canvas->w, 255);
}
static void rails_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
rails_segment_modified=rails_get_segment(x,y);
if ( (rails_segment_modified == rails_segment_modified_last))
return;
if (rails_segment_modified>0)
{
rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified);
}
if (rails_segment_modified_last>0)
rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified_last);
if (rails_segment_to_add>0)
{
rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_to_add);
rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified_last);
rails_segment_to_add=0;
} }
if (rails_segment_modified>0)
rails_segment_modified_last=rails_segment_modified;
take_up = segment - rails_segments_x;
if (take_up <= 0)
val_up = SEG_NONE;
else
val_up = rails_status_of_segments[take_up];
take_down = segment + rails_segments_x;
if (take_down > (signed)(rails_segments_x * rails_segments_y))
val_down = SEG_NONE;
else
val_down = rails_status_of_segments[take_down];
if ((segment % rails_segments_x) == 1)
val_left = SEG_NONE;
else
val_left = rails_status_of_segments[segment - 1];
if ((segment % rails_segments_x) == 0)
val_right = SEG_NONE;
else
val_right = rails_status_of_segments[segment + 1];
if (from_left || (val_left & SEG_RIGHT) || from_bottom_left)
{
LEFT = 1;
}
if (from_right || (val_right & SEG_LEFT) || from_top_right)
RIGHT = 1;
if (from_top || (val_up & SEG_BOTTOM) || from_top_left)
TOP = 1;
if (from_bottom || (val_down & SEG_TOP) || from_bottom_right)
BOTTOM = 1;
if (TOP && BOTTOM && LEFT && RIGHT)
return SEG_LEFT_RIGHT_TOP_BOTTOM;
if (LEFT && RIGHT && TOP)
return SEG_LEFT_RIGHT_TOP;
if (LEFT && RIGHT && BOTTOM)
return SEG_LEFT_RIGHT_BOTTOM;
if (TOP && BOTTOM && LEFT)
return SEG_LEFT_TOP_BOTTOM;
if (TOP && BOTTOM && RIGHT)
return SEG_RIGHT_TOP_BOTTOM;
if (LEFT && RIGHT)
return SEG_LEFT_RIGHT;
if (TOP && BOTTOM)
return SEG_TOP_BOTTOM;
if (LEFT && TOP)
return SEG_LEFT_TOP;
if (LEFT && BOTTOM)
return SEG_LEFT_BOTTOM;
if (RIGHT && TOP)
return SEG_RIGHT_TOP;
if (RIGHT && BOTTOM)
return SEG_RIGHT_BOTTOM;
if (LEFT | RIGHT)
return SEG_LEFT_RIGHT;
return SEG_TOP_BOTTOM;
}
static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y ATTRIBUTE_UNUSED, unsigned int segment)
{
magic_api *api = (magic_api *) ptr;
SDL_Surface *result, *temp;
Uint8 image;
unsigned int use_temp;
use_temp = 0;
if (segment > rails_segments_x * rails_segments_y)
return;
//modification_rect.x and modification_rect.y are set by function
rails_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y);
modification_rect.h = img_w;
modification_rect.w = img_h;
image = rails_select_image(segment); //select the image to display
if (rails_status_of_segments[segment] == image)
return;
rails_status_of_segments[segment] = image; //and write it to global table
result = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask,
rails_one->format->Amask);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img_w, img_h, rails_one->format->BitsPerPixel,
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask,
rails_one->format->Amask);
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
switch (image)
{
case 0:
case SEG_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_one, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
rails_rotate(api, temp, rails_one, 1);
use_temp = 1;
break;
case SEG_LEFT_RIGHT_TOP_BOTTOM:
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
SDL_BlitSurface(rails_four, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_TOP:
SDL_BlitSurface(rails_three, NULL, result, NULL);
break;
case SEG_LEFT_RIGHT_BOTTOM:
rails_flip(api, temp, rails_three);
use_temp = 1;
break;
case SEG_LEFT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 0);
use_temp = 1;
break;
case SEG_RIGHT_TOP_BOTTOM:
rails_rotate(api, temp, rails_three, 1);
use_temp = 1;
break;
case SEG_RIGHT_TOP:
SDL_BlitSurface(rails_corner, NULL, result, NULL);
break;
case SEG_RIGHT_BOTTOM:
rails_flip(api, temp, rails_corner);
use_temp = 1;
break;
case SEG_LEFT_TOP:
rails_rotate(api, temp, rails_corner, 0);
use_temp = 1;
break;
case SEG_LEFT_BOTTOM:
rails_flip_flop(api, temp, rails_corner);
use_temp = 1;
break;
}
if (use_temp)
SDL_BlitSurface(temp, NULL, result, NULL);
SDL_FreeSurface(temp);
SDL_BlitSurface(result, NULL, canvas, &modification_rect);
SDL_FreeSurface(result);
api->playsound(rails_snd, (x * 255) / canvas->w, 255);
}
static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
rails_segment_modified = rails_get_segment(x, y);
if ((rails_segment_modified == rails_segment_modified_last))
return;
if (rails_segment_modified > 0)
{
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified);
}
if (rails_segment_modified_last > 0)
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last);
if (rails_segment_to_add > 0)
{
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_to_add);
rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last);
rails_segment_to_add = 0;
}
if (rails_segment_modified > 0)
rails_segment_modified_last = rails_segment_modified;
} }
void rails_drag(magic_api * api, int which, SDL_Surface * canvas, void rails_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect) {
{
int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h; int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h;
// avoiding to write out of the canvas // avoiding to write out of the canvas
if ((x<canvas->w)&&(y<canvas->h)&&(ox<canvas->w)&&(oy<canvas->h)&&((signed)x>0)&&((signed)y>0)&&((signed)ox>0)&&((signed)oy>0)) if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
&& ((signed)ox > 0) && ((signed)oy > 0))
{ {
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, img_w/2, rails_draw_wrapper); api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, img_w / 2, rails_draw_wrapper);
start_x=min(ox,x);
end_x=max(ox,x);
start_y=min(oy,y);
end_y=max(oy,y);
segment_start=rails_get_segment(start_x-img_w, start_y-img_h); start_x = min(ox, x);
segment_end=rails_get_segment(end_x+img_w,end_y+img_h); end_x = max(ox, x);
start_y = min(oy, y);
end_y = max(oy, y);
x=((segment_start%rails_segments_x)-1)*img_w; segment_start = rails_get_segment(start_x - img_w, start_y - img_h);
y=(int)(segment_start/rails_segments_x)*img_h; segment_end = rails_get_segment(end_x + img_w, end_y + img_h);
w=((segment_end%rails_segments_x)-1)*img_w-x+img_w;
h=(int)(segment_end/rails_segments_x)*img_h-y+img_h;
update_rect->x=x; x = ((segment_start % rails_segments_x) - 1) * img_w;
update_rect->y=y; y = (int)(segment_start / rails_segments_x) * img_h;
update_rect->w=w; w = ((segment_end % rails_segments_x) - 1) * img_w - x + img_w;
update_rect->h=h;} h = (int)(segment_end / rails_segments_x) * img_h - y + img_h;
update_rect->x = x;
update_rect->y = y;
update_rect->w = w;
update_rect->h = h;
}
} }

View file

@ -48,47 +48,45 @@ void rain_click(magic_api *, int, int, SDL_Surface *, SDL_Surface *, int, int, S
static const int rain_SIZE = 30; static const int rain_SIZE = 30;
static const int rain_AMOUNT = 200; static const int rain_AMOUNT = 200;
enum { enum
TOOL_rain, {
rain_NUM_TOOLS TOOL_rain,
rain_NUM_TOOLS
}; };
static Mix_Chunk * rain_snd_effect[rain_NUM_TOOLS]; static Mix_Chunk *rain_snd_effect[rain_NUM_TOOLS];
const char * rain_snd_filenames[rain_NUM_TOOLS] = { const char *rain_snd_filenames[rain_NUM_TOOLS] = {
"rain.ogg", "rain.ogg",
}; };
const char * rain_icon_filenames[rain_NUM_TOOLS] = {
const char *rain_icon_filenames[rain_NUM_TOOLS] = {
"rain.png", "rain.png",
}; };
const char * rain_names[rain_NUM_TOOLS] = {
const char *rain_names[rain_NUM_TOOLS] = {
gettext_noop("Rain"), gettext_noop("Rain"),
}; };
const char * rain_descs[rain_NUM_TOOLS][2] = {
const char *rain_descs[rain_NUM_TOOLS][2] = {
{gettext_noop("Click to place a rain drop onto your picture."), {gettext_noop("Click to place a rain drop onto your picture."),
gettext_noop("Click to cover your picture with rain drops."),}, gettext_noop("Click to cover your picture with rain drops."),},
}; };
Uint32 rain_api_version(void); Uint32 rain_api_version(void);
int rain_init(magic_api * api); int rain_init(magic_api * api);
int rain_get_tool_count(magic_api * api); int rain_get_tool_count(magic_api * api);
SDL_Surface * rain_get_icon(magic_api * api, int which); SDL_Surface *rain_get_icon(magic_api * api, int which);
char * rain_get_name(magic_api * api, int which); char *rain_get_name(magic_api * api, int which);
char * rain_get_description(magic_api * api, int which, int mode); char *rain_get_description(magic_api * api, int which, int mode);
static void do_rain_drop(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_rain_drop(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y); static void rain_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void rain_linecb(void * ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void rain_drag(magic_api * api, int which, SDL_Surface * canvas, void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void rain_click(magic_api * api, int which, int mode, void rain_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void rain_release(magic_api * api, int which, void rain_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void rain_shutdown(magic_api * api); void rain_shutdown(magic_api * api);
void rain_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void rain_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int rain_requires_colors(magic_api * api, int which); int rain_requires_colors(magic_api * api, int which);
@ -96,96 +94,121 @@ void rain_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rain_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void rain_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int rain_modes(magic_api * api, int which); int rain_modes(magic_api * api, int which);
Uint32 rain_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 rain_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Checks if a a pixel is inside a raindrop shape centered on the origin //Checks if a a pixel is inside a raindrop shape centered on the origin
static int rain_inRainShape(double x, double y, double r){ static int rain_inRainShape(double x, double y, double r)
if ( sqrt( x*x + y*y ) < ( r * pow( cos( atan2(x,y) ), 10.0) ) ){ {
return 1; if (sqrt(x * x + y * y) < (r * pow(cos(atan2(x, y)), 10.0)))
} {
return 1;
}
return 0; return 0;
} }
int rain_init(magic_api * api){ int rain_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
//Load sounds
for (i = 0; i < rain_NUM_TOOLS; i++){
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, rain_snd_filenames[i]);
rain_snd_effect[i] = Mix_LoadWAV(fname);
}
return(1); //Load sounds
for (i = 0; i < rain_NUM_TOOLS; i++)
{
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, rain_snd_filenames[i]);
rain_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
} }
int rain_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int rain_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(rain_NUM_TOOLS); {
return (rain_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * rain_get_icon(magic_api * api, int which){ SDL_Surface *rain_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, rain_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, rain_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * rain_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *rain_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(rain_names[which]))); {
return (strdup(gettext_noop(rain_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * rain_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *rain_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(rain_descs[which][mode-1]))); {
return (strdup(gettext_noop(rain_descs[which][mode - 1])));
} }
// Do the effect: // Do the effect:
static void do_rain_drop(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, static void do_rain_drop(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
int x, int y){ SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
magic_api * api = (magic_api *) ptr; {
magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
Uint8 r,g,b; Uint8 r, g, b;
for (yy = y - rain_SIZE/2; yy < y + rain_SIZE/2; yy++){ for (yy = y - rain_SIZE / 2; yy < y + rain_SIZE / 2; yy++)
for (xx = x - rain_SIZE; xx < x + rain_SIZE; xx++){ {
if (rain_inRainShape(xx - x, yy - y + rain_SIZE/2, rain_SIZE)){ for (xx = x - rain_SIZE; xx < x + rain_SIZE; xx++)
//api->rgbtohsv(rain_r, rain_g, rain_b, &h, &s, &v); {
//api->hsvtorgb(h, s, rain_weights[(yy-y)*((rain_SIZE*2) -1)+(xx-x)], &r, &g, &b); if (rain_inRainShape(xx - x, yy - y + rain_SIZE / 2, rain_SIZE))
SDL_GetRGB(api->getpixel(canvas, xx , yy), canvas->format, &r, &g, &b); {
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, clamp(0, r - 50, 255), //api->rgbtohsv(rain_r, rain_g, rain_b, &h, &s, &v);
clamp(0, g - 50, 255), //api->hsvtorgb(h, s, rain_weights[(yy-y)*((rain_SIZE*2) -1)+(xx-x)], &r, &g, &b);
clamp(0, b + 200, 255))); SDL_GetRGB(api->getpixel(canvas, xx, yy), canvas->format, &r, &g, &b);
} api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, clamp(0, r - 50, 255),
clamp(0, g - 50, 255), clamp(0, b + 200, 255)));
}
}
} }
}
} }
static void rain_linecb(void * ptr, int which, static void rain_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
SDL_Rect rect; SDL_Rect rect;
if (rand() % 10 == 0) { if (rand() % 10 == 0)
rain_click(api, which, MODE_PAINT, canvas, last, {
x + (rand() % rain_SIZE * 2) - rain_SIZE, rain_click(api, which, MODE_PAINT, canvas, last,
y + (rand() % rain_SIZE * 2) - rain_SIZE, x + (rand() % rain_SIZE * 2) - rain_SIZE, y + (rand() % rain_SIZE * 2) - rain_SIZE, &rect);
&rect); }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void rain_drag(magic_api * api, int which, SDL_Surface * canvas, void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, rain_linecb); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, rain_linecb);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - rain_SIZE * 2; update_rect->x = ox - rain_SIZE * 2;
update_rect->y = oy - rain_SIZE * 2; update_rect->y = oy - rain_SIZE * 2;
@ -195,55 +218,64 @@ void rain_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void rain_click(magic_api * api, int which, int mode, void rain_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT){ if (mode == MODE_PAINT)
do_rain_drop(api, which, canvas, last, x, y); {
do_rain_drop(api, which, canvas, last, x, y);
update_rect->x = x - rain_SIZE; update_rect->x = x - rain_SIZE;
update_rect->y = y - rain_SIZE; update_rect->y = y - rain_SIZE;
update_rect->w = rain_SIZE * 2; update_rect->w = rain_SIZE * 2;
update_rect->h = rain_SIZE * 2; update_rect->h = rain_SIZE * 2;
api->playsound(rain_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(rain_snd_effect[which], (x * 255) / canvas->w, 255);
}else{
int i;
for(i=0; i<rain_AMOUNT; i++){
do_rain_drop(api, which, canvas, last, rand() % canvas->w, rand() % canvas->h);
} }
else
{
update_rect->x = 0; int i;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(rain_snd_effect[which], 128, 255); for (i = 0; i < rain_AMOUNT; i++)
} {
do_rain_drop(api, which, canvas, last, rand() % canvas->w, rand() % canvas->h);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(rain_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void rain_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void rain_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void rain_shutdown(magic_api * api ATTRIBUTE_UNUSED) void rain_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<rain_NUM_TOOLS; i++){
if(rain_snd_effect[i] != NULL){ for (i = 0; i < rain_NUM_TOOLS; i++)
Mix_FreeChunk(rain_snd_effect[i]); {
} if (rain_snd_effect[i] != NULL)
} {
Mix_FreeChunk(rain_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void rain_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void rain_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -254,17 +286,17 @@ int rain_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
} }
void rain_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rain_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void rain_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rain_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int rain_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int rain_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -65,31 +65,24 @@ static const int rainbow_hexes[NUM_RAINBOW_COLORS][3] = {
static int rainbow_color; static int rainbow_color;
static Uint32 rainbow_rgb; static Uint32 rainbow_rgb;
static Mix_Chunk * rainbow_snd; static Mix_Chunk *rainbow_snd;
int rainbow_init(magic_api * api); int rainbow_init(magic_api * api);
Uint32 rainbow_api_version(void); Uint32 rainbow_api_version(void);
int rainbow_get_tool_count(magic_api * api); int rainbow_get_tool_count(magic_api * api);
SDL_Surface * rainbow_get_icon(magic_api * api, int which); SDL_Surface *rainbow_get_icon(magic_api * api, int which);
char * rainbow_get_name(magic_api * api, int which); char *rainbow_get_name(magic_api * api, int which);
char * rainbow_get_description(magic_api * api, int which, int mode); char *rainbow_get_description(magic_api * api, int which, int mode);
static void rainbow_linecb(void * ptr, int which, static void rainbow_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas, void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void rainbow_click(magic_api * api, int which, int mode, void rainbow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y,
SDL_Rect * update_rect);
void rainbow_release(magic_api * api, int which, void rainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y,
SDL_Rect * update_rect);
void rainbow_shutdown(magic_api * api); void rainbow_shutdown(magic_api * api);
@ -99,7 +92,10 @@ void rainbow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas
void rainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void rainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int rainbow_modes(magic_api * api, int which); int rainbow_modes(magic_api * api, int which);
Uint32 rainbow_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 rainbow_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// Load our sfx: // Load our sfx:
int rainbow_init(magic_api * api) int rainbow_init(magic_api * api)
@ -109,79 +105,85 @@ int rainbow_init(magic_api * api)
rainbow_color = 0; rainbow_color = 0;
snprintf(fname, sizeof(fname), "%s/sounds/magic/rainbow.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/rainbow.wav", api->data_directory);
api->data_directory);
rainbow_snd = Mix_LoadWAV(fname); rainbow_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int rainbow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int rainbow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * rainbow_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *rainbow_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/rainbow.png", snprintf(fname, sizeof(fname), "%s/images/magic/rainbow.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * rainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *rainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Rainbow"))); return (strdup(gettext_noop("Rainbow")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * rainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *rainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup( return (strdup(gettext_noop("You can draw in rainbow colors!")));
gettext_noop("You can draw in rainbow colors!")));
} }
// Do the effect: // Do the effect:
static void rainbow_linecb(void * ptr, int which ATTRIBUTE_UNUSED, static void rainbow_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
for (yy = y - 16; yy < y + 16; yy++) for (yy = y - 16; yy < y + 16; yy++)
{
for (xx = x - 16; xx < x + 16; xx++)
{ {
if (api->in_circle(xx - x, yy - y, 16)) for (xx = x - 16; xx < x + 16; xx++)
{ {
api->putpixel(canvas, xx, yy, rainbow_rgb); if (api->in_circle(xx - x, yy - y, 16))
} {
api->putpixel(canvas, xx, yy, rainbow_rgb);
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas, void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
rainbow_color = (rainbow_color + 1) % NUM_RAINBOW_COLORS; rainbow_color = (rainbow_color + 1) % NUM_RAINBOW_COLORS;
rainbow_rgb = SDL_MapRGB(canvas->format, rainbow_rgb = SDL_MapRGB(canvas->format,
rainbow_hexes[rainbow_color][0], rainbow_hexes[rainbow_color][0],
rainbow_hexes[rainbow_color][1], rainbow_hexes[rainbow_color][1], rainbow_hexes[rainbow_color][2]);
rainbow_hexes[rainbow_color][2]);
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, rainbow_linecb); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, rainbow_linecb);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -193,17 +195,14 @@ void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void rainbow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void rainbow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y,
SDL_Rect * update_rect)
{ {
rainbow_drag(api, which, canvas, last, x, y, x, y, update_rect); rainbow_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void rainbow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void rainbow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -215,7 +214,8 @@ void rainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void rainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void rainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -225,15 +225,17 @@ int rainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUT
return 0; return 0;
} }
void rainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void rainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int rainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int rainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -20,48 +20,39 @@ FIXME:
#include "tp_magic_api.h" #include "tp_magic_api.h"
Mix_Chunk * realrainbow_snd; Mix_Chunk *realrainbow_snd;
int realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2; int realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2;
SDL_Rect realrainbow_rect; SDL_Rect realrainbow_rect;
SDL_Surface * realrainbow_colors[2]; SDL_Surface *realrainbow_colors[2];
Uint8 realrainbow_blendr, realrainbow_blendg, realrainbow_blendb, realrainbow_blenda; Uint8 realrainbow_blendr, realrainbow_blendg, realrainbow_blendb, realrainbow_blenda;
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last,
int x1, int y1, int x2, int y2, int x1, int y1, int x2, int y2, int fulldraw, SDL_Rect * update_rect);
int fulldraw, SDL_Rect * update_rect); static void realrainbow_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void realrainbow_linecb(void * ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
Uint32 realrainbow_api_version(void); Uint32 realrainbow_api_version(void);
int realrainbow_init(magic_api * api); int realrainbow_init(magic_api * api);
int realrainbow_get_tool_count(magic_api * api); int realrainbow_get_tool_count(magic_api * api);
SDL_Surface * realrainbow_get_icon(magic_api * api, int which); SDL_Surface *realrainbow_get_icon(magic_api * api, int which);
char * realrainbow_get_name(magic_api * api, int which); char *realrainbow_get_name(magic_api * api, int which);
char * realrainbow_get_description(magic_api * api, int which, int mode); char *realrainbow_get_description(magic_api * api, int which, int mode);
int realrainbow_modes(magic_api * api, int which); int realrainbow_modes(magic_api * api, int which);
int realrainbow_requires_colors(magic_api * api, int which); int realrainbow_requires_colors(magic_api * api, int which);
void realrainbow_shutdown(magic_api * api); void realrainbow_shutdown(magic_api * api);
void realrainbow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void realrainbow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
void realrainbow_click(magic_api * api, int which, int mode, void realrainbow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y,
SDL_Rect * update_rect);
void realrainbow_drag(magic_api * api, int which, void realrainbow_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
int ox, int oy, int x, int y,
SDL_Rect * update_rect);
void realrainbow_release(magic_api * api, int which, void realrainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y,
SDL_Rect * update_rect);
void realrainbow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void realrainbow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void realrainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void realrainbow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
Uint32 realrainbow_api_version(void) Uint32 realrainbow_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
int realrainbow_init(magic_api * api) int realrainbow_init(magic_api * api)
@ -71,60 +62,60 @@ int realrainbow_init(magic_api * api)
snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-colors.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-colors.png", api->data_directory);
realrainbow_colors[0] = IMG_Load(fname); realrainbow_colors[0] = IMG_Load(fname);
if (realrainbow_colors[0] == NULL) if (realrainbow_colors[0] == NULL)
return(0); return (0);
snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-roygbiv-colors.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-roygbiv-colors.png", api->data_directory);
realrainbow_colors[1] = IMG_Load(fname); realrainbow_colors[1] = IMG_Load(fname);
if (realrainbow_colors[1] == NULL) if (realrainbow_colors[1] == NULL)
return(0); return (0);
snprintf(fname, sizeof(fname), "%s/sounds/magic/realrainbow.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/realrainbow.ogg", api->data_directory);
api->data_directory);
realrainbow_snd = Mix_LoadWAV(fname); realrainbow_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int realrainbow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int realrainbow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(2); return (2);
} }
SDL_Surface * realrainbow_get_icon(magic_api * api, int which) SDL_Surface *realrainbow_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == 0) if (which == 0)
snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow.png", snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow.png", api->data_directory);
api->data_directory);
else else
snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-roygbiv.png", snprintf(fname, sizeof(fname), "%s/images/magic/realrainbow-roygbiv.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * realrainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *realrainbow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == 0) if (which == 0)
return(strdup(gettext_noop("Real Rainbow"))); return (strdup(gettext_noop("Real Rainbow")));
else else
return(strdup(gettext_noop("ROYGBIV Rainbow"))); return (strdup(gettext_noop("ROYGBIV Rainbow")));
} }
char * realrainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *realrainbow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click where you want your rainbow to start, drag to where you want it to end, and then let go to draw a rainbow."))); return (strdup
(gettext_noop
("Click where you want your rainbow to start, drag to where you want it to end, and then let go to draw a rainbow.")));
} }
int realrainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int realrainbow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }
int realrainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int realrainbow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(0); return (0);
} }
void realrainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED) void realrainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
@ -137,14 +128,14 @@ void realrainbow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(realrainbow_snd); Mix_FreeChunk(realrainbow_snd);
} }
void realrainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void realrainbow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x, int y, int x, int y, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
realrainbow_x1 = x; realrainbow_x1 = x;
realrainbow_y1 = y; realrainbow_y1 = y;
@ -157,8 +148,7 @@ void realrainbow_click(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
void realrainbow_drag(magic_api * api, int which, void realrainbow_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
int rx1, ry1, rx2, ry2; int rx1, ry1, rx2, ry2;
SDL_Rect rect; SDL_Rect rect;
@ -168,7 +158,8 @@ void realrainbow_drag(magic_api * api, int which,
SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect); SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 0, update_rect); realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 0,
update_rect);
memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect)); memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect));
memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect)); memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect));
@ -194,9 +185,7 @@ void realrainbow_drag(magic_api * api, int which,
} }
void realrainbow_release(magic_api * api, int which, void realrainbow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y,
SDL_Rect * update_rect)
{ {
int rx1, ry1, rx2, ry2; int rx1, ry1, rx2, ry2;
SDL_Rect rect; SDL_Rect rect;
@ -206,7 +195,8 @@ void realrainbow_release(magic_api * api, int which,
SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect); SDL_BlitSurface(last, &realrainbow_rect, canvas, &realrainbow_rect);
realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 1, update_rect); realrainbow_arc(api, which, canvas, last, realrainbow_x1, realrainbow_y1, realrainbow_x2, realrainbow_y2, 1,
update_rect);
memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect)); memcpy(&rect, &realrainbow_rect, sizeof(SDL_Rect));
memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect)); memcpy(&realrainbow_rect, update_rect, sizeof(SDL_Rect));
@ -233,16 +223,19 @@ void realrainbow_release(magic_api * api, int which,
api->playsound(realrainbow_snd, 128, 255); api->playsound(realrainbow_snd, 128, 255);
} }
void realrainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void realrainbow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void realrainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void realrainbow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x1, int y1, int x2, int y2, int fulldraw, SDL_Rect * update_rect) void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x1, int y1, int x2,
int y2, int fulldraw, SDL_Rect * update_rect)
{ {
int lowx, lowy, hix, hiy, xm, ym, xc, yc, r, a1, atan2_a, atan2_b; int lowx, lowy, hix, hiy, xm, ym, xc, yc, r, a1, atan2_a, atan2_b;
int a, oa, ox, oy, nx, ny, step, thick, rr, done; int a, oa, ox, oy, nx, ny, step, thick, rr, done;
@ -250,71 +243,71 @@ void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surfa
int colorindex; int colorindex;
if (abs(x2 - x1) < 50) if (abs(x2 - x1) < 50)
{ {
if (x2 > x1) if (x2 > x1)
x2 = x1 + 50; x2 = x1 + 50;
else else
x2 = x1 - 50; x2 = x1 - 50;
} }
if (y1 == y2) if (y1 == y2)
{
xc = x1 + (x2 - x1) / 2;
yc = y1;
r = abs(xc - x1);
a1 = 0;
theta = -180;
}
else
{
if (y1 > y2)
{ {
lowx = x1; xc = x1 + (x2 - x1) / 2;
lowy = y1; yc = y1;
hix = x2; r = abs(xc - x1);
hiy = y2;
}
else
{
lowx = x2;
lowy = y2;
hix = x1;
hiy = y1;
}
xm = (lowx + hix) / 2;
ym = (lowy + hiy) / 2;
if (hix == lowx)
return;
slope = (float)(hiy - lowy) / (float)(hix - lowx);
yc = lowy;
xc = slope * (ym - yc) + xm;
r = abs(xc - lowx);
atan2_b = hix - xc;
atan2_a = hiy - yc;
theta = atan2(atan2_a, atan2_b) * (180.0 / M_PI);
if (slope > 0)
a1 = 0; a1 = 0;
else theta = -180;
a1 = -180; }
} else
{
if (y1 > y2)
{
lowx = x1;
lowy = y1;
hix = x2;
hiy = y2;
}
else
{
lowx = x2;
lowy = y2;
hix = x1;
hiy = y1;
}
xm = (lowx + hix) / 2;
ym = (lowy + hiy) / 2;
if (hix == lowx)
return;
slope = (float)(hiy - lowy) / (float)(hix - lowx);
yc = lowy;
xc = slope * (ym - yc) + xm;
r = abs(xc - lowx);
atan2_b = hix - xc;
atan2_a = hiy - yc;
theta = atan2(atan2_a, atan2_b) * (180.0 / M_PI);
if (slope > 0)
a1 = 0;
else
a1 = -180;
}
if (fulldraw) if (fulldraw)
{ {
step = 1; step = 1;
/* thick = (r / 5); */ /* thick = (r / 5); */
} }
else else
{ {
step = 30; step = 30;
/* thick = 1; */ /* thick = 1; */
} }
thick = (r / 5); thick = (r / 5);
if (theta < a1) if (theta < a1)
@ -324,52 +317,51 @@ void realrainbow_arc(magic_api * api, int which, SDL_Surface * canvas, SDL_Surfa
oa = a1; oa = a1;
for (a = (a1 + step); done < 2; a = a + step) for (a = (a1 + step); done < 2; a = a + step)
{
for (rr = r - (thick / 2); rr <= r + (thick / 2); rr++)
{ {
ox = (rr * cos(oa * M_PI / 180.0)) + xc; for (rr = r - (thick / 2); rr <= r + (thick / 2); rr++)
oy = (rr * sin(oa * M_PI / 180.0)) + yc; {
ox = (rr * cos(oa * M_PI / 180.0)) + xc;
oy = (rr * sin(oa * M_PI / 180.0)) + yc;
nx = (rr * cos(a * M_PI / 180.0)) + xc; nx = (rr * cos(a * M_PI / 180.0)) + xc;
ny = (rr * sin(a * M_PI / 180.0)) + yc; ny = (rr * sin(a * M_PI / 180.0)) + yc;
colorindex = realrainbow_colors[which]->h - 1 - (((rr - r + (thick / 2)) * realrainbow_colors[which]->h) / thick); colorindex =
realrainbow_colors[which]->h - 1 - (((rr - r + (thick / 2)) * realrainbow_colors[which]->h) / thick);
SDL_GetRGBA(api->getpixel(realrainbow_colors[which], 0, colorindex), SDL_GetRGBA(api->getpixel(realrainbow_colors[which], 0, colorindex),
realrainbow_colors[which]->format, &realrainbow_blendr, &realrainbow_blendg, &realrainbow_blendb, &realrainbow_blenda); realrainbow_colors[which]->format, &realrainbow_blendr, &realrainbow_blendg, &realrainbow_blendb,
&realrainbow_blenda);
if (!fulldraw) if (!fulldraw)
realrainbow_blenda = 255; realrainbow_blenda = 255;
api->line((void *) api, 0, canvas, last, ox, oy, nx, ny, 1, realrainbow_linecb); api->line((void *)api, 0, canvas, last, ox, oy, nx, ny, 1, realrainbow_linecb);
}
oa = a;
if ((step > 0 && a + step > theta) || (step < 0 && a + step < theta))
{
done++;
a = theta - step;
}
} }
oa = a;
if ((step > 0 && a + step > theta) ||
(step < 0 && a + step < theta))
{
done++;
a = theta - step;
}
}
update_rect->y = yc - r - thick - 2; update_rect->y = yc - r - thick - 2;
update_rect->h = r + thick * 2 + 4; update_rect->h = r + thick * 2 + 4;
update_rect->x = xc - r - thick; update_rect->x = xc - r - thick;
update_rect->w = r * 2 + thick * 2; update_rect->w = r * 2 + thick * 2;
} }
static void realrainbow_linecb(void * ptr, int which ATTRIBUTE_UNUSED, static void realrainbow_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 origr, origg, origb; Uint8 origr, origg, origb;
Uint8 newr, newg, newb; Uint8 newr, newg, newb;
SDL_GetRGB(api->getpixel(last, x, y), SDL_GetRGB(api->getpixel(last, x, y), last->format, &origr, &origg, &origb);
last->format, &origr, &origg, &origb);
newr = ((realrainbow_blendr * realrainbow_blenda) / 255) + ((origr * (255 - realrainbow_blenda)) / 255); newr = ((realrainbow_blendr * realrainbow_blenda) / 255) + ((origr * (255 - realrainbow_blenda)) / 255);
newg = ((realrainbow_blendg * realrainbow_blenda) / 255) + ((origg * (255 - realrainbow_blenda)) / 255); newg = ((realrainbow_blendg * realrainbow_blenda) / 255) + ((origg * (255 - realrainbow_blenda)) / 255);
@ -377,4 +369,3 @@ static void realrainbow_linecb(void * ptr, int which ATTRIBUTE_UNUSED,
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, newr, newg, newb)); api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, newr, newg, newb));
} }

View file

@ -37,28 +37,23 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * ripples_snd; static Mix_Chunk *ripples_snd;
static int ripples_z, ripples_brite; static int ripples_z, ripples_brite;
Uint32 ripples_api_version(void); Uint32 ripples_api_version(void);
int ripples_init(magic_api * api); int ripples_init(magic_api * api);
int ripples_get_tool_count(magic_api * api); int ripples_get_tool_count(magic_api * api);
SDL_Surface * ripples_get_icon(magic_api * api, int which); SDL_Surface *ripples_get_icon(magic_api * api, int which);
char * ripples_get_name(magic_api * api, int which); char *ripples_get_name(magic_api * api, int which);
char * ripples_get_description(magic_api * api, int which, int mode); char *ripples_get_description(magic_api * api, int which, int mode);
void ripples_drag(magic_api * api, int which, SDL_Surface * canvas, void ripples_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect); static void ripples_linecb(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void ripples_linecb(void * ptr, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y);
void ripples_click(magic_api * api, int which, int mode, void ripples_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void ripples_release(magic_api * api, int which, void ripples_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void ripples_shutdown(magic_api * api); void ripples_shutdown(magic_api * api);
void ripples_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void ripples_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int ripples_requires_colors(magic_api * api, int which); int ripples_requires_colors(magic_api * api, int which);
@ -66,7 +61,10 @@ void ripples_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas
void ripples_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void ripples_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int ripples_modes(magic_api * api, int which); int ripples_modes(magic_api * api, int which);
Uint32 ripples_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 ripples_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
#define deg_cos(x) cos((x) * M_PI / 180.0) #define deg_cos(x) cos((x) * M_PI / 180.0)
#define deg_sin(x) sin((x) * M_PI / 180.0) #define deg_sin(x) sin((x) * M_PI / 180.0)
@ -76,54 +74,51 @@ int ripples_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/ripples.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/ripples.ogg", api->data_directory);
api->data_directory);
ripples_snd = Mix_LoadWAV(fname); ripples_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int ripples_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int ripples_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * ripples_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *ripples_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/ripples.png", snprintf(fname, sizeof(fname), "%s/images/magic/ripples.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * ripples_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *ripples_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Ripples"))); return (strdup(gettext_noop("Ripples")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * ripples_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *ripples_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click to make ripples appear over your picture."))); return (strdup(gettext_noop("Click to make ripples appear over your picture.")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void ripples_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, void ripples_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
static void ripples_linecb(void * ptr, int which ATTRIBUTE_UNUSED, static void ripples_linecb(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r, g, b; Uint8 r, g, b;
Uint32 pix; Uint32 pix;
@ -139,8 +134,7 @@ static void ripples_linecb(void * ptr, int which ATTRIBUTE_UNUSED,
// Affect the canvas on click: // Affect the canvas on click:
void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
float radius; float radius;
float fli; float fli;
@ -149,25 +143,25 @@ void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
radius = 100; radius = 100;
for (fli = 0; fli < radius; fli = fli + .25) for (fli = 0; fli < radius; fli = fli + .25)
{
ripples_z = (10 * deg_sin(((50 * 50) / (fli + 4)) * 10));
ox = fli * deg_cos(0) + x;
oy = -fli * deg_sin(0) + y;
for (d = 0; d <= 360 + (360 / (fli + 1)); d = d + 360 / (fli + 1))
{ {
nx = fli * deg_cos(d) + x; ripples_z = (10 * deg_sin(((50 * 50) / (fli + 4)) * 10));
ny = -fli * deg_sin(d) + y;
ripples_brite = (ripples_z * 20 * deg_sin(d + 45)) / ((fli / 4) + 1);
api->line((void *) api, which, canvas, last, ox, oy, nx, ny, 1, ripples_linecb); ox = fli * deg_cos(0) + x;
oy = -fli * deg_sin(0) + y;
ox = nx;
oy = ny; for (d = 0; d <= 360 + (360 / (fli + 1)); d = d + 360 / (fli + 1))
{
nx = fli * deg_cos(d) + x;
ny = -fli * deg_sin(d) + y;
ripples_brite = (ripples_z * 20 * deg_sin(d + 45)) / ((fli / 4) + 1);
api->line((void *)api, which, canvas, last, ox, oy, nx, ny, 1, ripples_linecb);
ox = nx;
oy = ny;
}
} }
}
update_rect->x = x - 100; update_rect->x = x - 100;
update_rect->y = y - 100; update_rect->y = y - 100;
@ -179,8 +173,8 @@ void ripples_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release: // Affect the canvas on release:
void ripples_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void ripples_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -192,7 +186,8 @@ void ripples_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void ripples_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void ripples_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -202,15 +197,17 @@ int ripples_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUT
return 0; return 0;
} }
void ripples_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void ripples_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void ripples_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void ripples_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int ripples_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int ripples_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_ONECLICK); return (MODE_ONECLICK);
} }

View file

@ -32,69 +32,64 @@
#include "tp_magic_api.h" #include "tp_magic_api.h"
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
#include <math.h> //for sin, cos, ... #include <math.h> //for sin, cos, ...
#define ROSETTE_R 8 //circle's diameter #define ROSETTE_R 8 //circle's diameter
static int xmid, ymid; static int xmid, ymid;
struct rosette_rgb struct rosette_rgb
{ {
Uint8 r, g, b; Uint8 r, g, b;
}; };
struct rosette_rgb rosette_colors; struct rosette_rgb rosette_colors;
Mix_Chunk * rosette_snd; Mix_Chunk *rosette_snd;
// Housekeeping functions // Housekeeping functions
Uint32 rosette_api_version(void); Uint32 rosette_api_version(void);
void rosette_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void rosette_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int rosette_init(magic_api * api); int rosette_init(magic_api * api);
int rosette_get_tool_count(magic_api * api); int rosette_get_tool_count(magic_api * api);
SDL_Surface * rosette_get_icon(magic_api * api, int which); SDL_Surface *rosette_get_icon(magic_api * api, int which);
char * rosette_get_name(magic_api * api, int which); char *rosette_get_name(magic_api * api, int which);
char * rosette_get_description(magic_api * api, int which, int mode); char *rosette_get_description(magic_api * api, int which, int mode);
int rosette_requires_colors(magic_api * api, int which); int rosette_requires_colors(magic_api * api, int which);
void rosette_release(magic_api * api, int which, void rosette_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void rosette_shutdown(magic_api * api); void rosette_shutdown(magic_api * api);
void rosette_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void rosette_drag(magic_api * api, int which, SDL_Surface * canvas, void rosette_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void rosette_click(magic_api * api, int which, int mode, void rosette_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void rosette_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void rosette_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void rosette_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void rosette_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int rosette_modes(magic_api * api, int which); int rosette_modes(magic_api * api, int which);
void rosette_circle(void * ptr, int which, void rosette_circle(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot,
int x, int y);
Uint32 rosette_api_version(void) Uint32 rosette_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void rosette_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure void rosette_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
{ {
rosette_colors.r=r; rosette_colors.r = r;
rosette_colors.g=g; rosette_colors.g = g;
rosette_colors.b=b; rosette_colors.b = b;
} }
int rosette_init(magic_api * api) int rosette_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/picasso.ogg", api->data_directory);
rosette_snd = Mix_LoadWAV(fname);
return(1); snprintf(fname, sizeof(fname), "%s/sounds/magic/picasso.ogg", api->data_directory);
rosette_snd = Mix_LoadWAV(fname);
return (1);
} }
int rosette_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int rosette_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
@ -102,131 +97,146 @@ int rosette_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return 2; return 2;
} }
SDL_Surface * rosette_get_icon(magic_api * api, int which) SDL_Surface *rosette_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (!which)
snprintf(fname, sizeof(fname), "%s/images/magic/rosette.png", api->data_directory);
else snprintf(fname, sizeof(fname), "%s/images/magic/picasso.png", api->data_directory);
return(IMG_Load(fname)); if (!which)
snprintf(fname, sizeof(fname), "%s/images/magic/rosette.png", api->data_directory);
else
snprintf(fname, sizeof(fname), "%s/images/magic/picasso.png", api->data_directory);
return (IMG_Load(fname));
} }
char * rosette_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) { if (!which) return strdup(gettext_noop("Rosette")); else return strdup(gettext_noop("Picasso"));} char *rosette_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
char * rosette_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (!which) if (!which)
return strdup(gettext_noop("Click and start drawing your rosette.")); //just k'scope with 3 bits? return strdup(gettext_noop("Rosette"));
else else
return strdup(gettext_noop("You can draw just like Picasso!")); //what is this actually doing? return strdup(gettext_noop("Picasso"));
} }
int rosette_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 1; } char *rosette_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{
if (!which)
return strdup(gettext_noop("Click and start drawing your rosette.")); //just k'scope with 3 bits?
else
return strdup(gettext_noop("You can draw just like Picasso!")); //what is this actually doing?
}
int rosette_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 1;
}
void rosette_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void rosette_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void rosette_shutdown(magic_api * api ATTRIBUTE_UNUSED) { Mix_FreeChunk(rosette_snd); } void rosette_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{
Mix_FreeChunk(rosette_snd);
}
// Interactivity functions // Interactivity functions
void rosette_circle(void * ptr, int which ATTRIBUTE_UNUSED, void rosette_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
for (yy = y - ROSETTE_R; yy < y + ROSETTE_R; yy++) for (yy = y - ROSETTE_R; yy < y + ROSETTE_R; yy++)
for (xx = x - ROSETTE_R; xx < x + ROSETTE_R; xx++) for (xx = x - ROSETTE_R; xx < x + ROSETTE_R; xx++)
if (api->in_circle(xx - x , yy - y , ROSETTE_R/2)) if (api->in_circle(xx - x, yy - y, ROSETTE_R / 2))
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, rosette_colors.r, rosette_colors.g, rosette_colors.b)); api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, rosette_colors.r, rosette_colors.g, rosette_colors.b));
} }
void rosette_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y) void rosette_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
double angle;
double xx, yy; //distance to the center of the image
int x1, y1, x2, y2;
xx=(double)(xmid-x);
yy=(double)(y-ymid);
if (which==0)
{
angle=2*M_PI/3; //an angle between brushes
x1=(int)(xx*cos(angle)-yy*sin(angle));
y1=(int)(xx*sin(angle)+yy*cos(angle));
x2=(int)(xx*cos(2*angle)-yy*sin(2*angle));
y2=(int)(xx*sin(2*angle)+yy*cos(2*angle));
}
else
{
angle=atan(yy/xx);
if ((xx<0) && (yy>0)) angle+=M_PI;
if ((xx<0) && (yy<0)) angle+=M_PI;
if ((xx>0) && (yy<0)) angle+=2*M_PI;
if ((y==ymid) && (xx<0)) angle=M_PI; double angle;
double xx, yy; //distance to the center of the image
x1=(int)(xx*cos(2*angle)-yy*sin(2*angle)); int x1, y1, x2, y2;
y1=(int)(xx*sin(2*angle)-yy*cos(angle));
x2=(int)(xx*cos(2*angle)-yy*sin(2*angle));
y2=(int)(xx*sin(2*angle)+yy*cos(2*angle));
}
rosette_circle(api, which, canvas, snapshot, x, y); xx = (double)(xmid - x);
rosette_circle(api, which, canvas, snapshot, (-1)*(x1-xmid), y1+ymid); yy = (double)(y - ymid);
rosette_circle(api, which, canvas, snapshot, (-1)*(x2-xmid), y2+ymid);
if (which == 0)
{
angle = 2 * M_PI / 3; //an angle between brushes
x1 = (int)(xx * cos(angle) - yy * sin(angle));
y1 = (int)(xx * sin(angle) + yy * cos(angle));
x2 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int)(xx * sin(2 * angle) + yy * cos(2 * angle));
}
else
{
angle = atan(yy / xx);
if ((xx < 0) && (yy > 0))
angle += M_PI;
if ((xx < 0) && (yy < 0))
angle += M_PI;
if ((xx > 0) && (yy < 0))
angle += 2 * M_PI;
if ((y == ymid) && (xx < 0))
angle = M_PI;
x1 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y1 = (int)(xx * sin(2 * angle) - yy * cos(angle));
x2 = (int)(xx * cos(2 * angle) - yy * sin(2 * angle));
y2 = (int)(xx * sin(2 * angle) + yy * cos(2 * angle));
}
rosette_circle(api, which, canvas, snapshot, x, y);
rosette_circle(api, which, canvas, snapshot, (-1) * (x1 - xmid), y1 + ymid);
rosette_circle(api, which, canvas, snapshot, (-1) * (x2 - xmid), y2 + ymid);
} }
void rosette_drag(magic_api * api, int which, SDL_Surface * canvas, void rosette_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, 1, rosette_draw); api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, 1, rosette_draw);
api->playsound(rosette_snd, (x * 255) / canvas->w, 255); api->playsound(rosette_snd, (x * 255) / canvas->w, 255);
update_rect->x=update_rect->y=0; update_rect->x = update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
} }
void rosette_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void rosette_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
rosette_drag(api, which, canvas, last, x, y, x, y, update_rect); rosette_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
void rosette_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rosette_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
{ SDL_Surface * canvas ATTRIBUTE_UNUSED)
xmid=canvas->w/2; {
ymid=canvas->h/2; xmid = canvas->w / 2;
ymid = canvas->h / 2;
} }
void rosette_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void rosette_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int rosette_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int rosette_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -44,11 +44,12 @@
/* Our globals: */ /* Our globals: */
enum { enum
TOOL_TRACE, {
TOOL_SHARPEN, TOOL_TRACE,
TOOL_SILHOUETTE, TOOL_SHARPEN,
sharpen_NUM_TOOLS TOOL_SILHOUETTE,
sharpen_NUM_TOOLS
}; };
static const int THRESHOLD = 50; static const int THRESHOLD = 50;
@ -57,54 +58,52 @@ static const int sharpen_RADIUS = 16;
static const double SHARPEN = 0.5; static const double SHARPEN = 0.5;
static Mix_Chunk * sharpen_snd_effect[sharpen_NUM_TOOLS]; static Mix_Chunk *sharpen_snd_effect[sharpen_NUM_TOOLS];
const char * sharpen_snd_filenames[sharpen_NUM_TOOLS] = { const char *sharpen_snd_filenames[sharpen_NUM_TOOLS] = {
"edges.ogg", "edges.ogg",
"sharpen.ogg", "sharpen.ogg",
"silhouette.ogg" "silhouette.ogg"
}; };
const char * sharpen_icon_filenames[sharpen_NUM_TOOLS] = {
const char *sharpen_icon_filenames[sharpen_NUM_TOOLS] = {
"edges.png", "edges.png",
"sharpen.png", "sharpen.png",
"silhouette.png" "silhouette.png"
}; };
const char * sharpen_names[sharpen_NUM_TOOLS] = {
const char *sharpen_names[sharpen_NUM_TOOLS] = {
gettext_noop("Edges"), gettext_noop("Edges"),
gettext_noop("Sharpen"), gettext_noop("Sharpen"),
gettext_noop("Silhouette") gettext_noop("Silhouette")
}; };
const char * sharpen_descs[sharpen_NUM_TOOLS][2] = {
const char *sharpen_descs[sharpen_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse to trace edges in parts of your picture."), {gettext_noop("Click and drag the mouse to trace edges in parts of your picture."),
gettext_noop("Click to trace edges in your entire picture."),}, gettext_noop("Click to trace edges in your entire picture."),},
{gettext_noop("Click and drag the mouse to sharpen parts of your picture."), {gettext_noop("Click and drag the mouse to sharpen parts of your picture."),
gettext_noop("Click to sharpen the entire picture."),}, gettext_noop("Click to sharpen the entire picture."),},
{gettext_noop("Click and drag the mouse to create a black and white silhouette."), {gettext_noop("Click and drag the mouse to create a black and white silhouette."),
gettext_noop("Click to create a black and white silhouette of your entire picture.")}, gettext_noop("Click to create a black and white silhouette of your entire picture.")},
}; };
Uint32 sharpen_api_version(void); Uint32 sharpen_api_version(void);
int sharpen_init(magic_api * api); int sharpen_init(magic_api * api);
int sharpen_get_tool_count(magic_api * api); int sharpen_get_tool_count(magic_api * api);
SDL_Surface * sharpen_get_icon(magic_api * api, int which); SDL_Surface *sharpen_get_icon(magic_api * api, int which);
char * sharpen_get_name(magic_api * api, int which); char *sharpen_get_name(magic_api * api, int which);
char * sharpen_get_description(magic_api * api, int which, int mode); char *sharpen_get_description(magic_api * api, int which, int mode);
static int sharpen_grey(Uint8 r1,Uint8 g1,Uint8 b1); static int sharpen_grey(Uint8 r1, Uint8 g1, Uint8 b1);
static void do_sharpen_pixel(void * ptr, int which, static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last, static void do_sharpen_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
int x, int y); static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_sharpen_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_sharpen_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas, void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void sharpen_click(magic_api * api, int which, int mode, void sharpen_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void sharpen_release(magic_api * api, int which, void sharpen_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void sharpen_shutdown(magic_api * api); void sharpen_shutdown(magic_api * api);
void sharpen_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void sharpen_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -113,149 +112,181 @@ void sharpen_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas
void sharpen_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void sharpen_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int sharpen_modes(magic_api * api, int which); int sharpen_modes(magic_api * api, int which);
Uint32 sharpen_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 sharpen_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
int sharpen_init(magic_api * api){ int sharpen_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
for (i = 0; i < sharpen_NUM_TOOLS; i++){ for (i = 0; i < sharpen_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, sharpen_snd_filenames[i]); {
sharpen_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, sharpen_snd_filenames[i]);
} sharpen_snd_effect[i] = Mix_LoadWAV(fname);
}
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int sharpen_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int sharpen_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(sharpen_NUM_TOOLS); return (sharpen_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * sharpen_get_icon(magic_api * api, int which){ SDL_Surface *sharpen_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, sharpen_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, sharpen_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * sharpen_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *sharpen_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(sharpen_names[which]))); {
return (strdup(gettext_noop(sharpen_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * sharpen_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *sharpen_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(sharpen_descs[which][mode-1]))); {
return (strdup(gettext_noop(sharpen_descs[which][mode - 1])));
} }
//Calculates the grey scale value for a rgb pixel //Calculates the grey scale value for a rgb pixel
static int sharpen_grey(Uint8 r1,Uint8 g1,Uint8 b1){ static int sharpen_grey(Uint8 r1, Uint8 g1, Uint8 b1)
return 0.3*r1+.59*g1+0.11*b1; {
return 0.3 * r1 + .59 * g1 + 0.11 * b1;
} }
// Do the effect: // Do the effect:
static void do_sharpen_pixel(void * ptr, int which, static void do_sharpen_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last, {
int x, int y){
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r1, g1, b1; Uint8 r1, g1, b1;
int grey; int grey;
int i,j; int i, j;
double sobel_1=0,sobel_2=0; double sobel_1 = 0, sobel_2 = 0;
double temp; double temp;
//Sobel weighting masks //Sobel weighting masks
const int sobel_weights_1[3][3] = { {1,2,1}, const int sobel_weights_1[3][3] = { {1, 2, 1},
{0,0,0}, {0, 0, 0},
{-1,-2,-1}}; {-1, -2, -1}
const int sobel_weights_2[3][3] = { {-1,0,1}, };
{-2,0,2}, const int sobel_weights_2[3][3] = { {-1, 0, 1},
{-1,0,1}}; {-2, 0, 2},
{-1, 0, 1}
};
sobel_1=0; sobel_1 = 0;
sobel_2=0; sobel_2 = 0;
for (i=-1;i<2;i++){ for (i = -1; i < 2; i++)
for(j=-1; j<2; j++){ {
//No need to check if inside canvas, getpixel does it for us. for (j = -1; j < 2; j++)
SDL_GetRGB(api->getpixel(last, x+i, y+j), last->format, &r1, &g1, &b1); {
grey = sharpen_grey(r1,g1,b1); //No need to check if inside canvas, getpixel does it for us.
sobel_1 += grey * sobel_weights_1[i+1][j+1]; SDL_GetRGB(api->getpixel(last, x + i, y + j), last->format, &r1, &g1, &b1);
sobel_2 += grey * sobel_weights_2[i+1][j+1]; grey = sharpen_grey(r1, g1, b1);
} sobel_1 += grey * sobel_weights_1[i + 1][j + 1];
} sobel_2 += grey * sobel_weights_2[i + 1][j + 1];
}
temp = sqrt(sobel_1*sobel_1 + sobel_2*sobel_2); }
temp = (temp/1443)*255.0;
// set image to white where edge value is below THRESHOLD temp = sqrt(sobel_1 * sobel_1 + sobel_2 * sobel_2);
if (which == TOOL_TRACE){ temp = (temp / 1443) * 255.0;
if (temp<THRESHOLD){
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255)); // set image to white where edge value is below THRESHOLD
} if (which == TOOL_TRACE)
} {
//Simply display the edge values - provides a nice black and white silhouette image if (temp < THRESHOLD)
else if (which == TOOL_SILHOUETTE){ {
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp, temp, temp)); api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255));
} }
//Add the edge values to the original image, creating a more distinct jump in contrast at edges }
else if(which == TOOL_SHARPEN){ //Simply display the edge values - provides a nice black and white silhouette image
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1); else if (which == TOOL_SILHOUETTE)
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + SHARPEN * temp, 255.0), {
clamp(0.0, g1 + SHARPEN * temp, 255.0), api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, temp, temp, temp));
clamp(0.0, b1 + SHARPEN * temp, 255.0))); }
} //Add the edge values to the original image, creating a more distinct jump in contrast at edges
else if (which == TOOL_SHARPEN)
{
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, clamp(0.0, r1 + SHARPEN * temp, 255.0),
clamp(0.0, g1 + SHARPEN * temp, 255.0),
clamp(0.0, b1 + SHARPEN * temp, 255.0)));
}
} }
// Do the effect for the full image // Do the effect for the full image
static void do_sharpen_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ static void do_sharpen_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
{
// magic_api * api = (magic_api *) ptr; // magic_api * api = (magic_api *) ptr;
int x,y; int x, y;
for (y = 0; y < last->h; y++){ for (y = 0; y < last->h; y++)
for (x=0; x < last->w; x++){ {
do_sharpen_pixel(ptr, which, canvas, last, x, y); for (x = 0; x < last->w; x++)
} {
} do_sharpen_pixel(ptr, which, canvas, last, x, y);
}
}
} }
//do the effect for the brush //do the effect for the brush
static void do_sharpen_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ static void do_sharpen_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
int xx, yy; int xx, yy;
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
for (yy = y - sharpen_RADIUS; yy < y + sharpen_RADIUS; yy++) for (yy = y - sharpen_RADIUS; yy < y + sharpen_RADIUS; yy++)
{
for (xx = x - sharpen_RADIUS; xx < x + sharpen_RADIUS; xx++)
{ {
if (api->in_circle(xx - x, yy - y, sharpen_RADIUS) && for (xx = x - sharpen_RADIUS; xx < x + sharpen_RADIUS; xx++)
!api->touched(xx, yy)) {
{ if (api->in_circle(xx - x, yy - y, sharpen_RADIUS) && !api->touched(xx, yy))
do_sharpen_pixel(api, which, canvas, last, xx, yy); {
} do_sharpen_pixel(api, which, canvas, last, xx, yy);
}
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas, void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_sharpen_brush); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_sharpen_brush);
api->playsound(sharpen_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(sharpen_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - sharpen_RADIUS; update_rect->x = ox - sharpen_RADIUS;
update_rect->y = oy - sharpen_RADIUS; update_rect->y = oy - sharpen_RADIUS;
@ -265,41 +296,46 @@ void sharpen_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void sharpen_click(magic_api * api, int which, int mode, void sharpen_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
sharpen_drag(api, which, canvas, last, x, y, x, y, update_rect); sharpen_drag(api, which, canvas, last, x, y, x, y, update_rect);
else{ else
update_rect->x = 0; {
update_rect->y = 0; update_rect->x = 0;
update_rect->w = canvas->w; update_rect->y = 0;
update_rect->h = canvas->h; update_rect->w = canvas->w;
do_sharpen_full(api, canvas, last, which); update_rect->h = canvas->h;
api->playsound(sharpen_snd_effect[which], 128, 255); do_sharpen_full(api, canvas, last, which);
} api->playsound(sharpen_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void sharpen_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void sharpen_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void sharpen_shutdown(magic_api * api ATTRIBUTE_UNUSED) void sharpen_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<sharpen_NUM_TOOLS; i++){
if(sharpen_snd_effect[i] != NULL){ for (i = 0; i < sharpen_NUM_TOOLS; i++)
Mix_FreeChunk(sharpen_snd_effect[i]); {
} if (sharpen_snd_effect[i] != NULL)
} {
Mix_FreeChunk(sharpen_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void sharpen_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void sharpen_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -309,15 +345,17 @@ int sharpen_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUT
return 0; return 0;
} }
void sharpen_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void sharpen_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void sharpen_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void sharpen_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int sharpen_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int sharpen_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -38,29 +38,25 @@
/* Our globals: */ /* Our globals: */
static int shift_x, shift_y; static int shift_x, shift_y;
static Mix_Chunk * shift_snd; static Mix_Chunk *shift_snd;
/* Local function prototypes: */ /* Local function prototypes: */
static void shift_doit(magic_api * api, int which, SDL_Surface * canvas, static void shift_doit(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect, int crosshairs);
SDL_Rect * update_rect, int crosshairs);
Uint32 shift_api_version(void); Uint32 shift_api_version(void);
int shift_init(magic_api * api); int shift_init(magic_api * api);
int shift_get_tool_count(magic_api * api); int shift_get_tool_count(magic_api * api);
SDL_Surface * shift_get_icon(magic_api * api, int which); SDL_Surface *shift_get_icon(magic_api * api, int which);
char * shift_get_name(magic_api * api, int which); char *shift_get_name(magic_api * api, int which);
char * shift_get_description(magic_api * api, int which, int mode); char *shift_get_description(magic_api * api, int which, int mode);
void shift_drag(magic_api * api, int which, SDL_Surface * canvas, void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void shift_click(magic_api * api, int which, int mode, void shift_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void shift_release(magic_api * api, int which, void shift_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void shift_shutdown(magic_api * api); void shift_shutdown(magic_api * api);
void shift_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void shift_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int shift_requires_colors(magic_api * api, int which); int shift_requires_colors(magic_api * api, int which);
@ -71,7 +67,10 @@ int shift_modes(magic_api * api, int which);
Uint32 shift_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 shift_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -79,57 +78,54 @@ int shift_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/shift.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/shift.ogg", api->data_directory);
api->data_directory);
shift_snd = Mix_LoadWAV(fname); shift_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int shift_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int shift_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * shift_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) SDL_Surface *shift_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/shift.png", snprintf(fname, sizeof(fname), "%s/images/magic/shift.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * shift_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *shift_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Shift"))); return (strdup(gettext_noop("Shift")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * shift_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *shift_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag to shift your picture around on the canvas."))); return (strdup(gettext_noop("Click and drag to shift your picture around on the canvas.")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void shift_drag(magic_api * api, int which, SDL_Surface * canvas, void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
if (ox == x && oy == y) if (ox == x && oy == y)
return; /* No-op */ return; /* No-op */
shift_doit(api, which, canvas, last, ox, oy, x, y, update_rect, 1); shift_doit(api, which, canvas, last, ox, oy, x, y, update_rect, 1);
} }
static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect, int crosshairs) SDL_Rect * update_rect, int crosshairs)
{ {
SDL_Rect dest; SDL_Rect dest;
int dx, dy; int dx, dy;
@ -159,123 +155,123 @@ static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
if (dy > 0) if (dy > 0)
{
if (dx > 0)
{ {
/* Top Left */ if (dx > 0)
{
/* Top Left */
dest.x = dx - canvas->w; dest.x = dx - canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
/* Top */
dest.x = dx;
dest.y = dy - canvas->h; dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest); SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Top Right */
dest.x = dx + canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
} }
/* Top */
dest.x = dx;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Top Right */
dest.x = dx + canvas->w;
dest.y = dy - canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
if (dx > 0) if (dx > 0)
{ {
/* Left */ /* Left */
dest.x = dx - canvas->w; dest.x = dx - canvas->w;
dest.y = dy; dest.y = dy;
SDL_BlitSurface(last, NULL, canvas, &dest); SDL_BlitSurface(last, NULL, canvas, &dest);
} }
if (dx < 0) if (dx < 0)
{ {
/* Right */ /* Right */
dest.x = dx + canvas->w; dest.x = dx + canvas->w;
dest.y = dy; dest.y = dy;
SDL_BlitSurface(last, NULL, canvas, &dest); SDL_BlitSurface(last, NULL, canvas, &dest);
} }
if (dy < 0) if (dy < 0)
{
if (dx > 0)
{ {
/* Bottom Left */ if (dx > 0)
{
/* Bottom Left */
dest.x = dx - canvas->w; dest.x = dx - canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
/* Bottom */
dest.x = dx;
dest.y = dy + canvas->h; dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest); SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Bottom Right */
dest.x = dx + canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
} }
/* Bottom */
dest.x = dx;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
if (dx < 0)
{
/* Bottom Right */
dest.x = dx + canvas->w;
dest.y = dy + canvas->h;
SDL_BlitSurface(last, NULL, canvas, &dest);
}
}
if (crosshairs) if (crosshairs)
{ {
dest.x = (canvas->w / 2) - 1; dest.x = (canvas->w / 2) - 1;
dest.y = 0; dest.y = 0;
dest.w = 3; dest.w = 3;
dest.h = canvas->h; dest.h = canvas->h;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255)); SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
dest.x = 0; dest.x = 0;
dest.y = (canvas->h / 2) - 1; dest.y = (canvas->h / 2) - 1;
dest.w = canvas->w; dest.w = canvas->w;
dest.h = 3; dest.h = 3;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255)); SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
dest.x = canvas->w / 2; dest.x = canvas->w / 2;
dest.y = 0; dest.y = 0;
dest.w = 1; dest.w = 1;
dest.h = canvas->h; dest.h = canvas->h;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0)); SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
dest.x = 0; dest.x = 0;
dest.y = canvas->h / 2; dest.y = canvas->h / 2;
dest.w = canvas->w; dest.w = canvas->w;
dest.h = 1; dest.h = 1;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0)); SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
} }
/* Update everything! */ /* Update everything! */
@ -290,19 +286,17 @@ static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU
// Affect the canvas on click: // Affect the canvas on click:
void shift_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void shift_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
shift_x = x; shift_x = x;
shift_y = y; shift_y = y;
shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 1); shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 1);
} }
// Affect the canvas on release: // Affect the canvas on release:
void shift_release(magic_api * api, int which, void shift_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 0); shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 0);
api->stopsound(); api->stopsound();
@ -318,7 +312,7 @@ void shift_shutdown(magic_api * api ATTRIBUTE_UNUSED)
// Record the color from Tux Paint: // Record the color from Tux Paint:
void shift_set_color(magic_api * api ATTRIBUTE_UNUSED, void shift_set_color(magic_api * api ATTRIBUTE_UNUSED,
Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -328,15 +322,17 @@ int shift_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 0; return 0;
} }
void shift_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void shift_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void shift_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void shift_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int shift_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int shift_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }

View file

@ -37,25 +37,21 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * smudge_snd; static Mix_Chunk *smudge_snd;
static Uint8 smudge_r, smudge_g, smudge_b; static Uint8 smudge_r, smudge_g, smudge_b;
int smudge_init(magic_api * api); int smudge_init(magic_api * api);
Uint32 smudge_api_version(void); Uint32 smudge_api_version(void);
SDL_Surface * smudge_get_icon(magic_api * api, int which); SDL_Surface *smudge_get_icon(magic_api * api, int which);
char * smudge_get_name(magic_api * api, int which); char *smudge_get_name(magic_api * api, int which);
char * smudge_get_description(magic_api * api, int which, int mode); char *smudge_get_description(magic_api * api, int which, int mode);
static void do_smudge(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_smudge(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void smudge_drag(magic_api * api, int which, SDL_Surface * canvas, void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void smudge_click(magic_api * api, int which, int mode, void smudge_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void smudge_release(magic_api * api, int which, void smudge_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void smudge_shutdown(magic_api * api); void smudge_shutdown(magic_api * api);
void smudge_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void smudge_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int smudge_requires_colors(magic_api * api, int which); int smudge_requires_colors(magic_api * api, int which);
@ -69,121 +65,126 @@ int smudge_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/smudge.wav", snprintf(fname, sizeof(fname), "%s/sounds/magic/smudge.wav", api->data_directory);
api->data_directory);
smudge_snd = Mix_LoadWAV(fname); smudge_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
Uint32 smudge_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 smudge_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// We have multiple tools: // We have multiple tools:
int smudge_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int smudge_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(2); return (2);
} }
// Load our icons: // Load our icons:
SDL_Surface * smudge_get_icon(magic_api * api, int which) SDL_Surface *smudge_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (which == 0) if (which == 0)
snprintf(fname, sizeof(fname), "%s/images/magic/smudge.png", snprintf(fname, sizeof(fname), "%s/images/magic/smudge.png", api->data_directory);
api->data_directory); else /* if (which == 1) */
else /* if (which == 1) */ snprintf(fname, sizeof(fname), "%s/images/magic/wetpaint.png", api->data_directory);
snprintf(fname, sizeof(fname), "%s/images/magic/wetpaint.png",
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * smudge_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *smudge_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (which == 0) if (which == 0)
return(strdup(gettext_noop("Smudge"))); return (strdup(gettext_noop("Smudge")));
else /* if (which == 1) */ else /* if (which == 1) */
return(strdup(gettext_noop("Wet Paint"))); return (strdup(gettext_noop("Wet Paint")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * smudge_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *smudge_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (which == 0) if (which == 0)
return(strdup(gettext_noop("Click and drag the mouse around to smudge the picture."))); return (strdup(gettext_noop("Click and drag the mouse around to smudge the picture.")));
else /* if (which == 1) */ else /* if (which == 1) */
return(strdup(gettext_noop("Click and drag the mouse around to draw with wet, smudgy paint."))); return (strdup(gettext_noop("Click and drag the mouse around to draw with wet, smudgy paint.")));
} }
// Do the effect: // Do the effect:
static void do_smudge(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_smudge(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
static double state[32][32][3]; static double state[32][32][3];
unsigned i = 32 * 32; unsigned i = 32 * 32;
double rate = api->button_down() ? 0.5 : 0.0; double rate = api->button_down()? 0.5 : 0.0;
Uint8 r, g, b; Uint8 r, g, b;
int xx, yy, strength; int xx, yy, strength;
if (which == 1) if (which == 1)
{ {
/* Wet paint */ /* Wet paint */
for (yy = -8; yy < 8; yy++) for (yy = -8; yy < 8; yy++)
for (xx = -8; xx < 8; xx++) for (xx = -8; xx < 8; xx++)
if (api->in_circle(xx, yy, 8)) if (api->in_circle(xx, yy, 8))
{ {
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r, &g, &b);
last->format, &r, &g, &b); //strength = (abs(xx * yy) / 8) + 6;
//strength = (abs(xx * yy) / 8) + 6; strength = (abs(xx * yy) / 8) + 1;
strength = (abs(xx * yy) / 8) + 1; api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format,
api->putpixel(canvas, x + xx, y +yy, SDL_MapRGB(canvas->format, (smudge_r + r * strength) / (strength + 1),
(smudge_r + r * strength) / (strength + 1), (smudge_g + g * strength) / (strength + 1),
(smudge_g + g * strength) / (strength + 1), (smudge_b + b * strength) / (strength + 1)));
(smudge_b + b * strength) / (strength + 1))); }
} }
}
while (i--) while (i--)
{ {
int iy = i >> 5; int iy = i >> 5;
int ix = i & 0x1f; int ix = i & 0x1f;
// is it not on the circle of radius sqrt(120) at location 16,16?
if ((ix - 16) * (ix - 16) + (iy - 16) * (iy - 16) > 120)
continue;
// it is on the circle, so grab it
SDL_GetRGB(api->getpixel(canvas, x + ix - 16, y + iy - 16), // is it not on the circle of radius sqrt(120) at location 16,16?
last->format, &r, &g, &b); if ((ix - 16) * (ix - 16) + (iy - 16) * (iy - 16) > 120)
state[ix][iy][0] = continue;
rate * state[ix][iy][0] + (1.0 - rate) * api->sRGB_to_linear(r); // it is on the circle, so grab it
state[ix][iy][1] =
rate * state[ix][iy][1] + (1.0 - rate) * api->sRGB_to_linear(g);
state[ix][iy][2] =
rate * state[ix][iy][2] + (1.0 - rate) * api->sRGB_to_linear(b);
// opacity 100% --> new data not blended w/ existing data SDL_GetRGB(api->getpixel(canvas, x + ix - 16, y + iy - 16), last->format, &r, &g, &b);
api->putpixel(canvas, x + ix - 16, y + iy - 16, state[ix][iy][0] = rate * state[ix][iy][0] + (1.0 - rate) * api->sRGB_to_linear(r);
SDL_MapRGB(canvas->format, api->linear_to_sRGB(state[ix][iy][0]), state[ix][iy][1] = rate * state[ix][iy][1] + (1.0 - rate) * api->sRGB_to_linear(g);
api->linear_to_sRGB(state[ix][iy][1]), state[ix][iy][2] = rate * state[ix][iy][2] + (1.0 - rate) * api->sRGB_to_linear(b);
api->linear_to_sRGB(state[ix][iy][2])));
} // opacity 100% --> new data not blended w/ existing data
api->putpixel(canvas, x + ix - 16, y + iy - 16,
SDL_MapRGB(canvas->format, api->linear_to_sRGB(state[ix][iy][0]),
api->linear_to_sRGB(state[ix][iy][1]), api->linear_to_sRGB(state[ix][iy][2])));
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void smudge_drag(magic_api * api, int which, SDL_Surface * canvas, void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_smudge); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_smudge);
api->playsound(smudge_snd, (x * 255) / canvas->w, 255); api->playsound(smudge_snd, (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
@ -193,16 +194,15 @@ void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void smudge_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void smudge_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
smudge_drag(api, which, canvas, last, x, y, x, y, update_rect); smudge_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on click: // Affect the canvas on click:
void smudge_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void smudge_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -226,19 +226,21 @@ int smudge_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE
{ {
if (which == 0) if (which == 0)
return 0; return 0;
else /* if (which == 1) */ else /* if (which == 1) */
return 1; return 1;
} }
void smudge_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void smudge_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void smudge_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void smudge_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int smudge_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int smudge_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -45,30 +45,34 @@
static const int snow_AMOUNT = 400; static const int snow_AMOUNT = 400;
static const int snow_RADIUS = 5; static const int snow_RADIUS = 5;
static SDL_Surface * snow_flake1; static SDL_Surface *snow_flake1;
static SDL_Surface * snow_flake2; static SDL_Surface *snow_flake2;
enum { enum
{
TOOL_SNOWBALL, TOOL_SNOWBALL,
TOOL_SNOWFLAKE, TOOL_SNOWFLAKE,
snow_NUM_TOOLS snow_NUM_TOOLS
}; };
static Mix_Chunk * snow_snd_effect[snow_NUM_TOOLS]; static Mix_Chunk *snow_snd_effect[snow_NUM_TOOLS];
const char * snow_snd_filenames[snow_NUM_TOOLS] = { const char *snow_snd_filenames[snow_NUM_TOOLS] = {
"snowball.ogg", "snowball.ogg",
"snowflake.ogg", "snowflake.ogg",
}; };
const char * snow_icon_filenames[snow_NUM_TOOLS] = {
const char *snow_icon_filenames[snow_NUM_TOOLS] = {
"snowball.png", "snowball.png",
"snowflake.png", "snowflake.png",
}; };
const char * snow_names[snow_NUM_TOOLS] = {
const char *snow_names[snow_NUM_TOOLS] = {
gettext_noop("Snow Ball"), gettext_noop("Snow Ball"),
gettext_noop("Snow Flake"), gettext_noop("Snow Flake"),
}; };
const char * snow_descs[snow_NUM_TOOLS] = {
const char *snow_descs[snow_NUM_TOOLS] = {
gettext_noop("Click to add snow balls to your picture."), gettext_noop("Click to add snow balls to your picture."),
gettext_noop("Click to add snow flakes to your picture."), gettext_noop("Click to add snow flakes to your picture."),
}; };
@ -76,156 +80,187 @@ const char * snow_descs[snow_NUM_TOOLS] = {
Uint32 snow_api_version(void); Uint32 snow_api_version(void);
int snow_init(magic_api * api); int snow_init(magic_api * api);
int snow_get_tool_count(magic_api * api); int snow_get_tool_count(magic_api * api);
SDL_Surface * snow_get_icon(magic_api * api, int which); SDL_Surface *snow_get_icon(magic_api * api, int which);
char * snow_get_name(magic_api * api, int which); char *snow_get_name(magic_api * api, int which);
char * snow_get_description(magic_api * api, int which); char *snow_get_description(magic_api * api, int which);
static void do_snow(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount); static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount);
void snow_drag(magic_api * api, int which, SDL_Surface * canvas, void snow_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void snow_click(magic_api * api, int which, int mode, void snow_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void snow_release(magic_api * api, int which, void snow_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void snow_shutdown(magic_api * api); void snow_shutdown(magic_api * api);
void snow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void snow_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int snow_requires_colors(magic_api * api, int which); int snow_requires_colors(magic_api * api, int which);
void snow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void snow_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void snow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void snow_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int snow_modes(magic_api * api, int which); int snow_modes(magic_api * api, int which);
Uint32 snow_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 snow_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int snow_init(magic_api * api){ int snow_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
srand(time(0)); srand(time(0));
snprintf(fname, sizeof(fname), "%s/images/magic/Snow_flake4.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/Snow_flake4.png", api->data_directory);
snow_flake1 = IMG_Load(fname); snow_flake1 = IMG_Load(fname);
if (snow_flake1==NULL){ if (snow_flake1 == NULL)
return(0); {
} return (0);
}
snprintf(fname, sizeof(fname), "%s/images/magic/Snow_flake5.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/Snow_flake5.png", api->data_directory);
snow_flake2 = IMG_Load(fname); snow_flake2 = IMG_Load(fname);
if (snow_flake2==NULL){ if (snow_flake2 == NULL)
return(0); {
} return (0);
}
if (snow_flake2==NULL){printf("meh\n");} if (snow_flake2 == NULL)
for (i = 0; i < snow_NUM_TOOLS; i++){ {
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, snow_snd_filenames[i]); printf("meh\n");
snow_snd_effect[i] = Mix_LoadWAV(fname); }
} for (i = 0; i < snow_NUM_TOOLS; i++)
return(1); {
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, snow_snd_filenames[i]);
snow_snd_effect[i] = Mix_LoadWAV(fname);
}
return (1);
} }
int snow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int snow_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(snow_NUM_TOOLS); {
return (snow_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * snow_get_icon(magic_api * api, int which){ SDL_Surface *snow_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, snow_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, snow_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * snow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *snow_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(snow_names[which]))); {
return (strdup(gettext_noop(snow_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * snow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which){ char *snow_get_description(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(snow_descs[which]))); {
return (strdup(gettext_noop(snow_descs[which])));
} }
// Do the effect: // Do the effect:
static void do_snow(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount){ static void do_snow(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which, int snowAmount)
magic_api * api = (magic_api *) ptr; {
magic_api *api = (magic_api *) ptr;
int i,x,y,centre_x,centre_y; int i, x, y, centre_x, centre_y;
Uint8 r,g,b; Uint8 r, g, b;
SDL_Rect dest; SDL_Rect dest;
for(i=0; i<snowAmount; i++){ for (i = 0; i < snowAmount; i++)
centre_x = rand() % canvas->w; {
centre_y = rand() % canvas->h; centre_x = rand() % canvas->w;
if (which == TOOL_SNOWBALL){ centre_y = rand() % canvas->h;
for (y = -snow_RADIUS; y < snow_RADIUS; y++){ if (which == TOOL_SNOWBALL)
for (x= -snow_RADIUS; x < snow_RADIUS; x++){ {
if (api->in_circle(x ,y, snow_RADIUS)){ for (y = -snow_RADIUS; y < snow_RADIUS; y++)
SDL_GetRGB(api->getpixel(last, centre_x + x, centre_y + y), last->format, &r, &g, &b); {
api->putpixel(canvas, centre_x + x, centre_y + y, SDL_MapRGB(canvas->format, 255, 255, 255)); for (x = -snow_RADIUS; x < snow_RADIUS; x++)
{
if (api->in_circle(x, y, snow_RADIUS))
{
SDL_GetRGB(api->getpixel(last, centre_x + x, centre_y + y), last->format, &r, &g, &b);
api->putpixel(canvas, centre_x + x, centre_y + y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
}
}
if (which == TOOL_SNOWFLAKE)
{
dest.x = centre_x;
dest.y = centre_y;
if (rand() % 2 == 0)
{
SDL_BlitSurface(snow_flake1, NULL, canvas, &dest);
}
else
{
SDL_BlitSurface(snow_flake2, NULL, canvas, &dest);
} }
}
} }
}
if(which == TOOL_SNOWFLAKE){
dest.x = centre_x;
dest.y = centre_y;
if (rand()%2==0){
SDL_BlitSurface(snow_flake1, NULL, canvas, &dest);
}else {
SDL_BlitSurface(snow_flake2, NULL, canvas, &dest);
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void snow_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, void snow_drag(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED,
SDL_Rect * update_rect ATTRIBUTE_UNUSED){ int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
// No-op {
// No-op
} }
// Affect the canvas on click: // Affect the canvas on click:
void snow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void snow_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect){ int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect)
{
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
do_snow(api, canvas, last, which, snow_AMOUNT); do_snow(api, canvas, last, which, snow_AMOUNT);
api->playsound(snow_snd_effect[which], 128, 255); api->playsound(snow_snd_effect[which], 128, 255);
} }
// Affect the canvas on release: // Affect the canvas on release:
void snow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void snow_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void snow_shutdown(magic_api * api ATTRIBUTE_UNUSED) void snow_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<snow_NUM_TOOLS; i++){
if(snow_snd_effect[i] != NULL){ for (i = 0; i < snow_NUM_TOOLS; i++)
Mix_FreeChunk(snow_snd_effect[i]); {
} if (snow_snd_effect[i] != NULL)
} {
if (snow_flake1 != NULL){ Mix_FreeChunk(snow_snd_effect[i]);
SDL_FreeSurface(snow_flake1); }
} }
if (snow_flake2 != NULL){ if (snow_flake1 != NULL)
SDL_FreeSurface(snow_flake2); {
} SDL_FreeSurface(snow_flake1);
}
if (snow_flake2 != NULL)
{
SDL_FreeSurface(snow_flake2);
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void snow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void snow_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -235,15 +270,17 @@ int snow_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
return 0; return 0;
} }
void snow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED){ void snow_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
} }
void snow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void snow_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int snow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int snow_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN); return (MODE_FULLSCREEN);
} }

View file

@ -3,107 +3,107 @@
#include "SDL_mixer.h" #include "SDL_mixer.h"
unsigned int img_w, img_h; unsigned int img_w, img_h;
static Uint8 string_r, string_g, string_b; static Uint8 string_r, string_g, string_b;
static int string_ox, string_oy; static int string_ox, string_oy;
static int string_vertex_x, string_vertex_y, string_vertex_done, string_vertex_distance; static int string_vertex_x, string_vertex_y, string_vertex_done, string_vertex_distance;
static SDL_Surface * canvas_backup; static SDL_Surface *canvas_backup;
enum string_tools{ enum string_tools
{
STRING_TOOL_FULL_BY_OFFSET, STRING_TOOL_FULL_BY_OFFSET,
STRING_TOOL_TRIANGLE, STRING_TOOL_TRIANGLE,
STRING_TOOL_ANGLE, STRING_TOOL_ANGLE,
STRING_NUMTOOLS}; STRING_NUMTOOLS
};
Mix_Chunk *string_snd[STRING_NUMTOOLS];
Mix_Chunk * string_snd[STRING_NUMTOOLS];
// Custom function declarations // Custom function declarations
void string_callback(void * ptr, int which_tool, void string_callback(void *ptr, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void string_draw_triangle(magic_api * api, int which, void string_draw_triangle(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect); SDL_Rect * update_rect);
void string_draw_angle(magic_api * api, int which, void string_draw_angle(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect); SDL_Rect * update_rect);
void string_draw_triangle_preview(magic_api * api, int which, void string_draw_triangle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect); SDL_Rect * update_rect);
void string_draw_angle_preview(magic_api * api, int which, void string_draw_angle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect); SDL_Rect * update_rect);
void scale_xcoord(int * xcoord); void scale_xcoord(int *xcoord);
void scale_ycoord(int * ycoord); void scale_ycoord(int *ycoord);
void scale_coords(int * ox, int * oy, int * x, int * y); void scale_coords(int *ox, int *oy, int *x, int *y);
void string_draw_wrapper(magic_api * api, int which, void string_draw_wrapper(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect); SDL_Rect * update_rect);
void string_set_vertex(int x, int y); void string_set_vertex(int x, int y);
void compute_middle( int start_point, int end_point, int vertex, int * middle); void compute_middle(int start_point, int end_point, int vertex, int *middle);
// Prototypes for required functions // Prototypes for required functions
void string_drag(magic_api * api, int which, SDL_Surface * canvas, void string_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
Uint32 string_api_version(void); Uint32 string_api_version(void);
int string_modes(magic_api * api, int which); int string_modes(magic_api * api, int which);
void string_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void string_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int string_get_tool_count(magic_api * api); int string_get_tool_count(magic_api * api);
SDL_Surface * string_get_icon(magic_api * api, int which); SDL_Surface *string_get_icon(magic_api * api, int which);
char * string_get_name(magic_api * api, int which); char *string_get_name(magic_api * api, int which);
char * string_get_description(magic_api * api, int which, int mode); char *string_get_description(magic_api * api, int which, int mode);
int string_requires_colors(magic_api * api, int which); int string_requires_colors(magic_api * api, int which);
void string_release(magic_api * api, int which, void string_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
int string_init(magic_api * api); int string_init(magic_api * api);
void string_shutdown(magic_api * api); void string_shutdown(magic_api * api);
void string_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); void string_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void string_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); void string_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot);
void string_click(magic_api * api, int which, int mode, void string_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
// Required functions // Required functions
Uint32 string_api_version(void) Uint32 string_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
int string_modes(__attribute__((unused)) magic_api * api, int which) int string_modes( __attribute__ ((unused)) magic_api * api, int which)
{ {
if (which == STRING_TOOL_FULL_BY_OFFSET) if (which == STRING_TOOL_FULL_BY_OFFSET)
return(MODE_PAINT); return (MODE_PAINT);
else else
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }
void string_set_color(__attribute__((unused)) magic_api * api, Uint8 r, Uint8 g, Uint8 b) void string_set_color( __attribute__ ((unused)) magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{ {
string_r=r; string_r = r;
string_g=g; string_g = g;
string_b=b; string_b = b;
} }
int string_get_tool_count(__attribute__((unused)) magic_api * api)
int string_get_tool_count( __attribute__ ((unused)) magic_api * api)
{ {
return STRING_NUMTOOLS; return STRING_NUMTOOLS;
} }
SDL_Surface * string_get_icon(magic_api * api, int which) SDL_Surface *string_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
switch (which) switch (which)
{ {
case STRING_TOOL_FULL_BY_OFFSET: case STRING_TOOL_FULL_BY_OFFSET:
snprintf(fname, sizeof(fname), "%s/images/magic/string_art_full_by_offset.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/string_art_full_by_offset.png", api->data_directory);
break; break;
case STRING_TOOL_TRIANGLE: case STRING_TOOL_TRIANGLE:
snprintf(fname, sizeof(fname), "%s/images/magic/string_art_triangles.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/string_art_triangles.png", api->data_directory);
break; break;
case STRING_TOOL_ANGLE: case STRING_TOOL_ANGLE:
@ -111,18 +111,19 @@ SDL_Surface * string_get_icon(magic_api * api, int which)
break; break;
} }
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * string_get_name(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which) char *string_get_name( __attribute__ ((unused)) magic_api * api, __attribute__ ((unused))
int which)
{ {
switch (which) switch (which)
{ {
case STRING_TOOL_FULL_BY_OFFSET: case STRING_TOOL_FULL_BY_OFFSET:
return strdup(gettext_noop("String edges")); return strdup(gettext_noop("String edges"));
break; break;
case STRING_TOOL_TRIANGLE: case STRING_TOOL_TRIANGLE:
return strdup(gettext_noop("String corner")); return strdup(gettext_noop("String corner"));
break; break;
default: default:
@ -130,13 +131,17 @@ char * string_get_name(__attribute__((unused)) magic_api * api, __attribute__((u
} }
} }
char * string_get_description(__attribute__((unused)) magic_api * api, int which, __attribute__((unused)) int mode) { char *string_get_description( __attribute__ ((unused)) magic_api * api, int which, __attribute__ ((unused))
int mode)
{
switch (which) switch (which)
{ {
case STRING_TOOL_FULL_BY_OFFSET: case STRING_TOOL_FULL_BY_OFFSET:
return strdup(gettext_noop("Click and drag to draw string art. Drag top-bottom to draw less or more lines, left or right to make a bigger hole.")); return
strdup(gettext_noop
("Click and drag to draw string art. Drag top-bottom to draw less or more lines, left or right to make a bigger hole."));
break; break;
case STRING_TOOL_TRIANGLE: case STRING_TOOL_TRIANGLE:
return strdup(gettext_noop("Click and drag to draw arrows made of string art.")); return strdup(gettext_noop("Click and drag to draw arrows made of string art."));
break; break;
default: default:
@ -144,181 +149,192 @@ char * string_get_description(__attribute__((unused)) magic_api * api, int which
} }
} }
int string_requires_colors(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which) { return 1;} int string_requires_colors( __attribute__ ((unused)) magic_api * api, __attribute__ ((unused))
int which)
{
return 1;
}
void string_release(magic_api * api, int which, void string_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
int dx, dy; int dx, dy;
if (which==STRING_TOOL_TRIANGLE)
string_draw_triangle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); if (which == STRING_TOOL_TRIANGLE)
if (which==STRING_TOOL_ANGLE) string_draw_triangle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
if (which == STRING_TOOL_ANGLE)
{ {
if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag if (!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
{ {
dx=string_ox - x; dx = string_ox - x;
dy=string_oy - y; dy = string_oy - y;
y=y + dx; y = y + dx;
x=x - dy; x = x - dy;
} }
string_draw_angle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); string_draw_angle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
} }
} }
int string_init(__attribute__((unused)) magic_api * api) int string_init( __attribute__ ((unused)) magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/string.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/string.ogg", api->data_directory);
api->data_directory);
string_snd[STRING_TOOL_FULL_BY_OFFSET] = Mix_LoadWAV(fname); string_snd[STRING_TOOL_FULL_BY_OFFSET] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/string2.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/string2.ogg", api->data_directory);
api->data_directory);
string_snd[STRING_TOOL_TRIANGLE] = Mix_LoadWAV(fname); string_snd[STRING_TOOL_TRIANGLE] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/string3.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/string3.ogg", api->data_directory);
api->data_directory);
string_snd[STRING_TOOL_ANGLE] = Mix_LoadWAV(fname); string_snd[STRING_TOOL_ANGLE] = Mix_LoadWAV(fname);
return(1); return (1);
} }
void string_shutdown(__attribute__((unused)) magic_api * api) void string_shutdown( __attribute__ ((unused)) magic_api * api)
{ {
int i = 0; int i = 0;
if (canvas_backup) if (canvas_backup)
SDL_FreeSurface(canvas_backup); SDL_FreeSurface(canvas_backup);
while (i < STRING_NUMTOOLS) while (i < STRING_NUMTOOLS)
{ {
if (string_snd[i] != NULL) if (string_snd[i] != NULL)
Mix_FreeChunk(string_snd[i]); Mix_FreeChunk(string_snd[i]);
i ++; i++;
} }
} }
void string_switchin(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which, __attribute__((unused)) int mode, SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot) void string_switchin( __attribute__ ((unused)) magic_api * api, __attribute__ ((unused))
int which, __attribute__ ((unused))
int mode, SDL_Surface * canvas, __attribute__ ((unused)) SDL_Surface * snapshot)
{ {
canvas_backup=SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas_backup = SDL_CreateRGBSurface(SDL_SWSURFACE, canvas->w, canvas->h, canvas->format->BitsPerPixel,
canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask,
canvas->format->Amask);
} }
void string_switchout(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which, __attribute__((unused)) int mode, __attribute__((unused)) SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot) void string_switchout( __attribute__ ((unused)) magic_api * api, __attribute__ ((unused))
int which, __attribute__ ((unused))
int mode, __attribute__ ((unused)) SDL_Surface * canvas,
__attribute__ ((unused)) SDL_Surface * snapshot)
{ {
SDL_FreeSurface(canvas_backup); SDL_FreeSurface(canvas_backup);
canvas_backup=NULL; canvas_backup = NULL;
} }
// Interactivity functions // Interactivity functions
void string_callback(void * ptr,__attribute__((unused)) int which, void string_callback(void *ptr, __attribute__ ((unused))
SDL_Surface * canvas,__attribute__((unused)) SDL_Surface * snapshot, int x, int y) int which, SDL_Surface * canvas, __attribute__ ((unused)) SDL_Surface * snapshot, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format, string_r, string_g, string_b,255));
api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format, string_r, string_g, string_b, 255));
} }
void string_click(magic_api * api, int which,__attribute__((unused)) int mode, void string_click(magic_api * api, int which, __attribute__ ((unused))
SDL_Surface * canvas, SDL_Surface * snapshot, int mode, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); SDL_BlitSurface(canvas, NULL, canvas_backup, NULL);
string_ox=x; string_ox = x;
string_oy=y; string_oy = y;
string_vertex_distance=0; string_vertex_distance = 0;
string_vertex_done=0; string_vertex_done = 0;
string_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); string_drag(api, which, canvas, snapshot, x, y, x, y, update_rect);
} }
static void string_draw_full_by_offset(void * ptr, __attribute__((unused)) int which, SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot, static void string_draw_full_by_offset(void *ptr, __attribute__ ((unused))
int x, int y, SDL_Rect * update_rect) int which, SDL_Surface * canvas, __attribute__ ((unused)) SDL_Surface * snapshot,
int x, int y, SDL_Rect * update_rect)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
int u; int u;
int i; int i;
int o; //offset int o; //offset
// int n=y/5; // int n=y/5;
int ** a; int **a;
float step_w, step_h, aux; float step_w, step_h, aux;
int side=(int)(y/3); int side = (int)(y / 3);
SDL_BlitSurface(snapshot,0,canvas,0); SDL_BlitSurface(snapshot, 0, canvas, 0);
if (side<3) side=3; if (side < 3)
side = 3;
o=(int)(side*4*x/canvas->w); o = (int)(side * 4 * x / canvas->w);
step_w=canvas->w/(float)side; step_w = canvas->w / (float)side;
step_h=canvas->h/(float)side; step_h = canvas->h / (float)side;
a=malloc(sizeof(int*)*side*4*2); a = malloc(sizeof(int *) * side * 4 * 2);
for (i=0;i<side*4;i++) for (i = 0; i < side * 4; i++)
{ {
a[i]=malloc(sizeof(int*)*2); a[i] = malloc(sizeof(int *) * 2);
if (i<side) if (i < side)
{ {
a[i][0]= 0; a[i][0] = 0;
aux=step_h*(float)i; aux = step_h * (float)i;
a[i][1]= (int)aux; a[i][1] = (int)aux;
} }
else else if (i < (side * 2))
if(i<(side*2)) {
{ a[i][0] = (int)((float)(i % side) * step_w);
a[i][0]= (int)((float)(i%side)*step_w); a[i][1] = canvas->h;
a[i][1]= canvas->h; }
} else if (i < (int)(side * 3))
else {
if (i<(int)(side*3)) a[i][0] = canvas->w;
{ a[i][1] = (int)(canvas->h - (float)((i % side) * step_h));
a[i][0]= canvas->w; }
a[i][1]= (int)(canvas->h - (float)((i%side)*step_h)); else if (i < (int)(side * 4))
} {
else a[i][0] = (int)(canvas->w - ((float)((i % side) * step_w)));
if (i<(int)(side*4)) a[i][1] = 0;
{ }
a[i][0]=(int)( canvas->w-((float)((i%side)*step_w)));
a[i][1]= 0;
}
}
for (i=0;i<side*4;i++)
{
u=(i+o)%(side*4);
api->line((void *) api, which, canvas, snapshot,a[i][0],a[i][1],a[u][0],a[u][1],1, string_callback);
} }
for (i=0;i<side*4;i++)
for (i = 0; i < side * 4; i++)
{ {
free( a[i]); u = (i + o) % (side * 4);
api->line((void *)api, which, canvas, snapshot, a[i][0], a[i][1], a[u][0], a[u][1], 1, string_callback);
}
for (i = 0; i < side * 4; i++)
{
free(a[i]);
} }
free(a); free(a);
update_rect->x=0; update_rect->x = 0;
update_rect->y=0; update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
} }
void scale_xcoord(int * xcoord) void scale_xcoord(int *xcoord)
{ {
if (*xcoord < string_ox) *xcoord=string_ox-(string_ox - *xcoord)*4; if (*xcoord < string_ox)
else *xcoord=string_ox+(*xcoord-string_ox)*4; *xcoord = string_ox - (string_ox - *xcoord) * 4;
else
*xcoord = string_ox + (*xcoord - string_ox) * 4;
} }
void scale_ycoord(int * ycoord) void scale_ycoord(int *ycoord)
{ {
if (*ycoord < string_oy) *ycoord=string_oy-(string_oy - *ycoord)*4; if (*ycoord < string_oy)
else *ycoord=string_oy+(*ycoord-string_oy)*4; *ycoord = string_oy - (string_oy - *ycoord) * 4;
else
*ycoord = string_oy + (*ycoord - string_oy) * 4;
} }
void scale_coords(int * ox, int * oy, int * x, int * y) void scale_coords(int *ox, int *oy, int *x, int *y)
{ {
scale_xcoord(ox); scale_xcoord(ox);
scale_xcoord(x); scale_xcoord(x);
@ -326,161 +342,174 @@ void scale_coords(int * ox, int * oy, int * x, int * y)
scale_ycoord(y); scale_ycoord(y);
} }
void compute_middle( int start_point, int end_point, int vertex, int * middle) void compute_middle(int start_point, int end_point, int vertex, int *middle)
{ {
*middle=min(start_point,end_point)+(max(start_point,end_point)-min(start_point,end_point))/2; *middle = min(start_point, end_point) + (max(start_point, end_point) - min(start_point, end_point)) / 2;
*middle=min(*middle,vertex)+(max(*middle,vertex)-min(*middle,vertex))/2; *middle = min(*middle, vertex) + (max(*middle, vertex) - min(*middle, vertex)) / 2;
} }
void string_draw_triangle_preview(magic_api * api, int which, void string_draw_triangle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
int middle_x, middle_y; int middle_x, middle_y;
int w, h; int w, h;
scale_coords(&ox, &oy,&x, &y);
w=max(string_ox,x)-min(string_ox,x); scale_coords(&ox, &oy, &x, &y);
h=max(string_oy,y)-min(string_oy,y); w = max(string_ox, x) - min(string_ox, x);
h = max(string_oy, y) - min(string_oy, y);
/* /*
This is enouth if you move the mouse slowly, but if you move the mouse fast, This is enouth if you move the mouse slowly, but if you move the mouse fast,
there are rests of old previews left around. there are rests of old previews left around.
update_rect->w=max(max(string_ox,x),max(ox,x))-min(min(string_ox,x),min(ox,x)) +80; update_rect->w=max(max(string_ox,x),max(ox,x))-min(min(string_ox,x),min(ox,x)) +80;
update_rect->h=max(max(string_oy,y),max(oy,y))-min(min(string_oy,y),min(oy,y)) +80; update_rect->h=max(max(string_oy,y),max(oy,y))-min(min(string_oy,y),min(oy,y)) +80;
update_rect->x=min(string_ox,x) -40; update_rect->x=min(string_ox,x) -40;
update_rect->y=min(string_oy,y) -40; update_rect->y=min(string_oy,y) -40;
*/ */
update_rect->x=0; update_rect->x = 0;
update_rect->y=0; update_rect->y = 0;
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect); SDL_BlitSurface(canvas_backup, update_rect, canvas, update_rect);
compute_middle(x, string_ox, string_ox, &middle_x); compute_middle(x, string_ox, string_ox, &middle_x);
compute_middle(y, string_oy, string_oy, &middle_y); compute_middle(y, string_oy, string_oy, &middle_y);
api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, string_ox , y,1, string_callback); api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, string_ox, y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, x , string_oy,1, string_callback); api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, x, string_oy, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, middle_x,middle_y, x , string_oy,1, string_callback); api->line((void *)api, which, canvas, snapshot, middle_x, middle_y, x, string_oy, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox,y, middle_x , middle_y,1, string_callback); api->line((void *)api, which, canvas, snapshot, string_ox, y, middle_x, middle_y, 1, string_callback);
} }
void string_draw_angle_preview(magic_api * api, int which, void string_draw_angle_preview(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, __attribute__((unused)) int ox, __attribute__ ((unused)) int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, __attribute__ ((unused))
SDL_Rect * update_rect) int ox, __attribute__ ((unused))
{ int oy, int x, int y, SDL_Rect * update_rect)
{
int w, h; int w, h;
int middle_x, middle_y; int middle_x, middle_y;
int dx, dy; int dx, dy;
w=max(string_ox,x)-min(string_ox,x);
h=max(string_oy,y)-min(string_oy,y);
update_rect->x=0; w = max(string_ox, x) - min(string_ox, x);
update_rect->y=0; h = max(string_oy, y) - min(string_oy, y);
update_rect->w=canvas->w;
update_rect->h=canvas->h;
SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect);
api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, string_vertex_x , string_vertex_y,1, string_callback); update_rect->x = 0;
if(!string_vertex_done) update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
SDL_BlitSurface(canvas_backup, update_rect, canvas, update_rect);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, string_vertex_x, string_vertex_y, 1,
string_callback);
if (!string_vertex_done)
{ {
// if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag // if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag
//{ //{
dx=string_ox - x; dx = string_ox - x;
dy=string_oy - y; dy = string_oy - y;
y=y + dx; y = y + dx;
x=x - dy; x = x - dy;
} }
compute_middle(string_ox, x, string_vertex_x, &middle_x); compute_middle(string_ox, x, string_vertex_x, &middle_x);
compute_middle(string_oy, y, string_vertex_y, &middle_y); compute_middle(string_oy, y, string_vertex_y, &middle_y);
api->line((void *)api, which, canvas, snapshot, string_vertex_x, string_vertex_y, x, y, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, string_ox, string_oy, middle_x, middle_y, 1, string_callback);
api->line((void *)api, which, canvas, snapshot, x, y, middle_x, middle_y, 1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_vertex_x,string_vertex_y, x , y,1, string_callback);
api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, middle_x , middle_y,1, string_callback);
api->line((void *) api, which, canvas, snapshot, x, y, middle_x , middle_y,1, string_callback);
} }
void string_draw_angle(magic_api * api, __attribute__((unused)) int which, void string_draw_angle(magic_api * api, __attribute__ ((unused))
SDL_Surface * canvas, __attribute__((unused))SDL_Surface * snapshot, __attribute__ ((unused)) int ox, __attribute__ ((unused)) int oy, int x, int y, int which,
SDL_Rect * update_rect) SDL_Surface * canvas, __attribute__ ((unused)) SDL_Surface * snapshot, __attribute__ ((unused))
int ox, __attribute__ ((unused))
int oy, int x, int y, SDL_Rect * update_rect)
{ {
float first_arm_step_x, first_arm_step_y, second_arm_step_x, second_arm_step_y; float first_arm_step_x, first_arm_step_y, second_arm_step_x, second_arm_step_y;
int i; int i;
int max_wh , steps; int max_wh, steps;
int max_separation=10; int max_separation = 10;
update_rect->x=min(min(string_ox,string_vertex_x),x); update_rect->x = min(min(string_ox, string_vertex_x), x);
update_rect->y=min(min(string_oy,string_vertex_y),y); update_rect->y = min(min(string_oy, string_vertex_y), y);
update_rect->w=max(max(string_ox,string_vertex_x),x)-update_rect->x; update_rect->w = max(max(string_ox, string_vertex_x), x) - update_rect->x;
update_rect->h=max(max(string_oy,string_vertex_y),y)-update_rect->y; update_rect->h = max(max(string_oy, string_vertex_y), y) - update_rect->y;
SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect); SDL_BlitSurface(canvas_backup, update_rect, canvas, update_rect);
max_wh= max( max(max(string_ox,string_vertex_x),x)- min(min(string_vertex_x , x),string_ox) , max(max(string_oy , string_vertex_y),y)- min(min(string_vertex_y ,y),string_oy)); max_wh =
max(max(max(string_ox, string_vertex_x), x) - min(min(string_vertex_x, x), string_ox),
max(max(string_oy, string_vertex_y), y) - min(min(string_vertex_y, y), string_oy));
steps=max_wh/max_separation; steps = max_wh / max_separation;
first_arm_step_x=(float)(string_ox-string_vertex_x)/(float)steps; first_arm_step_x = (float)(string_ox - string_vertex_x) / (float)steps;
first_arm_step_y=(float)(string_oy-string_vertex_y)/(float)steps; first_arm_step_y = (float)(string_oy - string_vertex_y) / (float)steps;
second_arm_step_x=(float)(string_vertex_x-x)/(float)steps; second_arm_step_x = (float)(string_vertex_x - x) / (float)steps;
second_arm_step_y=(float)(string_vertex_y-y)/(float)steps; second_arm_step_y = (float)(string_vertex_y - y) / (float)steps;
for (i=0;i<=steps;i++) for (i = 0; i <= steps; i++)
{ {
api->line((void *) api, 0, canvas, snapshot, string_ox-first_arm_step_x*i,string_oy-first_arm_step_y*i, string_vertex_x-second_arm_step_x*i,string_vertex_y-second_arm_step_y*i,1, string_callback); api->line((void *)api, 0, canvas, snapshot, string_ox - first_arm_step_x * i, string_oy - first_arm_step_y * i,
string_vertex_x - second_arm_step_x * i, string_vertex_y - second_arm_step_y * i, 1, string_callback);
} }
} }
void string_draw_triangle(magic_api * api, __attribute__((unused)) int which, void string_draw_triangle(magic_api * api, __attribute__ ((unused))
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, int which,
SDL_Rect * update_rect) SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{ {
SDL_BlitSurface(canvas_backup,0,canvas,0); SDL_BlitSurface(canvas_backup, 0, canvas, 0);
scale_coords(&ox, &oy,&x, &y); scale_coords(&ox, &oy, &x, &y);
string_vertex_x=string_ox; string_vertex_x = string_ox;
string_vertex_y=string_oy; string_vertex_y = string_oy;
string_ox=string_vertex_x; string_ox = string_vertex_x;
string_oy=y; string_oy = y;
y=string_vertex_y; y = string_vertex_y;
string_draw_angle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); string_draw_angle((void *)api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect);
} }
void string_draw_wrapper(magic_api * api, int which, void string_draw_wrapper(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y,
SDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
if (which==STRING_TOOL_FULL_BY_OFFSET) if (which == STRING_TOOL_FULL_BY_OFFSET)
string_draw_full_by_offset((void *) api, which, canvas, snapshot, x, y, update_rect); string_draw_full_by_offset((void *)api, which, canvas, snapshot, x, y, update_rect);
else if (which==STRING_TOOL_TRIANGLE) else if (which == STRING_TOOL_TRIANGLE)
string_draw_triangle_preview ((void *) api, which, canvas, snapshot, ox, oy, x, y, update_rect); string_draw_triangle_preview((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
else if (which==STRING_TOOL_ANGLE) else if (which == STRING_TOOL_ANGLE)
string_draw_angle_preview ((void *) api, which, canvas, snapshot, ox, oy, x, y, update_rect); string_draw_angle_preview((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
} }
void string_set_vertex(int x, int y) void string_set_vertex(int x, int y)
{ {
int dx, dy; int dx, dy;
if (string_vertex_done) return;
dx=max(string_ox,x)-min(string_ox,x); if (string_vertex_done)
dy=max(string_oy,y)-min(string_oy,y); return;
if(dx+dy>string_vertex_distance) dx = max(string_ox, x) - min(string_ox, x);
dy = max(string_oy, y) - min(string_oy, y);
if (dx + dy > string_vertex_distance)
{ {
string_vertex_distance=dx+dy; string_vertex_distance = dx + dy;
string_vertex_x=x; string_vertex_x = x;
string_vertex_y=y; string_vertex_y = y;
} }
if(dx+dy+30<string_vertex_distance) string_vertex_done=1; if (dx + dy + 30 < string_vertex_distance)
string_vertex_done = 1;
} }
void string_drag(magic_api * api, int which, void string_drag(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
if ((x<canvas->w)&&(y<canvas->h)&&(ox<canvas->w)&&(oy<canvas->h)&&((signed)x>0)&&((signed)y>0)&&((signed)ox>0)&&((signed)oy>0)) if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0)
&& ((signed)ox > 0) && ((signed)oy > 0))
{ {
string_set_vertex(x,y); string_set_vertex(x, y);
string_draw_wrapper((void *) api, which, canvas, snapshot,ox,oy, x, y, update_rect); string_draw_wrapper((void *)api, which, canvas, snapshot, ox, oy, x, y, update_rect);
api->playsound(string_snd[which], (x * 255) / canvas->w, 255); api->playsound(string_snd[which], (x * 255) / canvas->w, 255);
} }

View file

@ -46,59 +46,58 @@
#define gettext_noop(String) String #define gettext_noop(String) String
#endif #endif
enum { enum
TOOL_TINT, {
TOOL_THRESHOLD, TOOL_TINT,
tint_NUM_TOOLS TOOL_THRESHOLD,
tint_NUM_TOOLS
}; };
static Uint8 tint_r, tint_g, tint_b; static Uint8 tint_r, tint_g, tint_b;
static int tint_min = INT_MAX; static int tint_min = INT_MAX;
static int tint_max = 0; static int tint_max = 0;
static const int tint_RADIUS =16; static const int tint_RADIUS = 16;
static Mix_Chunk * tint_snd_effect[tint_NUM_TOOLS]; static Mix_Chunk *tint_snd_effect[tint_NUM_TOOLS];
const char * tint_snd_filenames[tint_NUM_TOOLS] = { const char *tint_snd_filenames[tint_NUM_TOOLS] = {
"tint.wav", "tint.wav",
"fold.ogg" /* FIXME */ "fold.ogg" /* FIXME */
}; };
const char * tint_icon_filenames[tint_NUM_TOOLS] = {
const char *tint_icon_filenames[tint_NUM_TOOLS] = {
"tint.png", "tint.png",
"colornwhite.png" "colornwhite.png"
}; };
const char * tint_names[tint_NUM_TOOLS] = {
const char *tint_names[tint_NUM_TOOLS] = {
gettext_noop("Tint"), gettext_noop("Tint"),
gettext_noop("Color & White") // It does more than this but more intuitive than threshold. gettext_noop("Color & White") // It does more than this but more intuitive than threshold.
}; };
const char * tint_descs[tint_NUM_TOOLS][2] = {
const char *tint_descs[tint_NUM_TOOLS][2] = {
{gettext_noop("Click and drag the mouse around to change the color of parts of your picture."), {gettext_noop("Click and drag the mouse around to change the color of parts of your picture."),
gettext_noop("Click to change the color of your entire picture."),}, gettext_noop("Click to change the color of your entire picture."),},
{gettext_noop("Click and drag the mouse around to turn parts of your picture into white and a color you choose."), {gettext_noop("Click and drag the mouse around to turn parts of your picture into white and a color you choose."),
gettext_noop("Click to turn your entire picture into white and a color you choose.")} gettext_noop("Click to turn your entire picture into white and a color you choose.")}
}; };
int tint_init(magic_api * api); int tint_init(magic_api * api);
Uint32 tint_api_version(void); Uint32 tint_api_version(void);
int tint_get_tool_count(magic_api * api); int tint_get_tool_count(magic_api * api);
SDL_Surface * tint_get_icon(magic_api * api, int which); SDL_Surface *tint_get_icon(magic_api * api, int which);
char * tint_get_name(magic_api * api, int which); char *tint_get_name(magic_api * api, int which);
char * tint_get_description(magic_api * api, int which, int mode); char *tint_get_description(magic_api * api, int which, int mode);
static int tint_grey(Uint8 r1,Uint8 g1,Uint8 b1); static int tint_grey(Uint8 r1, Uint8 g1, Uint8 b1);
static void do_tint_pixel(void * ptr, int which, static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
SDL_Surface * canvas, SDL_Surface * last, static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which);
int x, int y); static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
static void do_tint_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which);
static void do_tint_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
void tint_drag(magic_api * api, int which, SDL_Surface * canvas, void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void tint_click(magic_api * api, int which, int mode, void tint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tint_release(magic_api * api, int which, void tint_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tint_shutdown(magic_api * api); void tint_shutdown(magic_api * api);
void tint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void tint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int tint_requires_colors(magic_api * api, int which); int tint_requires_colors(magic_api * api, int which);
@ -106,112 +105,145 @@ void tint_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tint_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void tint_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int tint_modes(magic_api * api, int which); int tint_modes(magic_api * api, int which);
Uint32 tint_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 tint_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
//Load sounds //Load sounds
int tint_init(magic_api * api){ int tint_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
for (i = 0; i < tint_NUM_TOOLS; i++){ for (i = 0; i < tint_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, tint_snd_filenames[i]); {
tint_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, tint_snd_filenames[i]);
} tint_snd_effect[i] = Mix_LoadWAV(fname);
return(1); }
return (1);
} }
int tint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int tint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(tint_NUM_TOOLS); {
return (tint_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * tint_get_icon(magic_api * api, int which){ SDL_Surface *tint_get_icon(magic_api * api, int which)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, tint_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, tint_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * tint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *tint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(tint_names[which]))); {
return (strdup(gettext_noop(tint_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * tint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode){ char *tint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
return(strdup(gettext_noop(tint_descs[which][mode-1]))); {
return (strdup(gettext_noop(tint_descs[which][mode - 1])));
} }
//Calculates the grey scale value for a rgb pixel //Calculates the grey scale value for a rgb pixel
static int tint_grey(Uint8 r1,Uint8 g1,Uint8 b1){ static int tint_grey(Uint8 r1, Uint8 g1, Uint8 b1)
return 0.3*r1+.59*g1+0.11*b1; {
return 0.3 * r1 + .59 * g1 + 0.11 * b1;
} }
static void do_tint_pixel(void * ptr, int which, static void do_tint_pixel(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
SDL_Surface * canvas, SDL_Surface * last, {
int x, int y){
magic_api *api = (magic_api *) ptr;
magic_api * api = (magic_api *) ptr; Uint8 r, g, b;
Uint8 r,g,b; float h, s, v;
float h,s,v;
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r, &g, &b);
SDL_GetRGB(api->getpixel(last, x, y), last->format, &r, &g, &b); {
int greyValue = tint_grey(r, g, b);
if (which == TOOL_TINT)
{
api->rgbtohsv(tint_r, tint_g, tint_b, &h, &s, &v);
api->hsvtorgb(h, s, greyValue / 255.0, &r, &g, &b);
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
}
else if (which == TOOL_THRESHOLD)
{
int thresholdValue = (tint_max - tint_min) / 2;
if (greyValue < thresholdValue)
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, tint_r, tint_g, tint_b));
}
else
{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255));
}
}
}
}
// Do the effect:
static void do_tint_full(void *ptr, SDL_Surface * canvas, SDL_Surface * last, int which)
{
int x, y;
for (y = 0; y < last->h; y++)
{ {
for (x = 0; x < last->w; x++)
int greyValue = tint_grey(r,g,b); {
do_tint_pixel(ptr, which, canvas, last, x, y);
if (which == TOOL_TINT){ }
api->rgbtohsv(tint_r, tint_g, tint_b, &h, &s, &v); }
api->hsvtorgb(h, s, greyValue/255.0, &r, &g, &b); }
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, r, g, b));
} else if (which == TOOL_THRESHOLD){ static void do_tint_brush(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
int thresholdValue = (tint_max-tint_min)/2; {
if (greyValue < thresholdValue){ int xx, yy;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, tint_r, tint_g, tint_b)); magic_api *api = (magic_api *) ptr;
} else{
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255)); for (yy = y - tint_RADIUS; yy < y + tint_RADIUS; yy++)
{
for (xx = x - tint_RADIUS; xx < x + tint_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, tint_RADIUS) && !api->touched(xx, yy))
{
do_tint_pixel(api, which, canvas, last, xx, yy);
} }
} }
} }
} }
// Do the effect:
static void do_tint_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){
int x,y;
for (y = 0; y < last->h; y++){
for (x=0; x < last->w; x++){
do_tint_pixel(ptr, which, canvas, last, x, y);
}
}
}
static void do_tint_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){
int xx, yy;
magic_api * api = (magic_api *) ptr;
for (yy = y - tint_RADIUS; yy < y + tint_RADIUS; yy++)
{
for (xx = x - tint_RADIUS; xx < x + tint_RADIUS; xx++)
{
if (api->in_circle(xx - x, yy - y, tint_RADIUS) &&
!api->touched(xx, yy))
{
do_tint_pixel(api, which, canvas, last, xx, yy);
}
}
}
}
// Affect the canvas on drag: // Affect the canvas on drag:
void tint_drag(magic_api * api, int which, SDL_Surface * canvas, void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_tint_brush); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_tint_brush);
api->playsound(tint_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(tint_snd_effect[which], (x * 255) / canvas->w, 255);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x)
if (oy > y) { int tmp = oy; oy = y; y = tmp; } {
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - tint_RADIUS; update_rect->x = ox - tint_RADIUS;
update_rect->y = oy - tint_RADIUS; update_rect->y = oy - tint_RADIUS;
@ -221,37 +253,41 @@ void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void tint_click(magic_api * api, int which, int mode, void tint_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
tint_drag(api, which, canvas, last, x, y, x, y, update_rect); tint_drag(api, which, canvas, last, x, y, x, y, update_rect);
else{ else
update_rect->x = 0; {
update_rect->y = 0; update_rect->x = 0;
update_rect->w = canvas->w; update_rect->y = 0;
update_rect->h = canvas->h; update_rect->w = canvas->w;
do_tint_full(api, canvas, last, which); update_rect->h = canvas->h;
api->playsound(tint_snd_effect[which], 128, 255); do_tint_full(api, canvas, last, which);
} api->playsound(tint_snd_effect[which], 128, 255);
}
} }
// Affect the canvas on release: // Affect the canvas on release:
void tint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void tint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void tint_shutdown(magic_api * api ATTRIBUTE_UNUSED) void tint_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<tint_NUM_TOOLS; i++){
if(tint_snd_effect[i] != NULL){ for (i = 0; i < tint_NUM_TOOLS; i++)
Mix_FreeChunk(tint_snd_effect[i]); {
} if (tint_snd_effect[i] != NULL)
} {
Mix_FreeChunk(tint_snd_effect[i]);
}
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
@ -268,32 +304,39 @@ int tint_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U
return 1; return 1;
} }
void tint_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas){ void tint_switchin(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas)
{
int x,y; int x, y;
Uint8 r1,g1,b1; Uint8 r1, g1, b1;
for (y = 0; y < canvas->h; y++){ for (y = 0; y < canvas->h; y++)
for (x=0; x < canvas->w; x++){ {
SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r1, &g1, &b1); for (x = 0; x < canvas->w; x++)
{ {
int greyValue = tint_grey(r1,g1,b1); SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r1, &g1, &b1);
if (greyValue<tint_min){ {
tint_min=greyValue; int greyValue = tint_grey(r1, g1, b1);
}
if (greyValue>tint_max){ if (greyValue < tint_min)
tint_max=greyValue; {
} tint_min = greyValue;
} }
} if (greyValue > tint_max)
} {
tint_max = greyValue;
}
}
}
}
} }
void tint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void tint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int tint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int tint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN|MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -46,25 +46,29 @@
double pi; double pi;
static Uint8 toothpaste_r, toothpaste_g, toothpaste_b; static Uint8 toothpaste_r, toothpaste_g, toothpaste_b;
static const int toothpaste_RADIUS = 10; static const int toothpaste_RADIUS = 10;
double* toothpaste_weights = NULL; double *toothpaste_weights = NULL;
enum { enum
TOOL_toothpaste, {
toothpaste_NUM_TOOLS TOOL_toothpaste,
toothpaste_NUM_TOOLS
}; };
static Mix_Chunk * toothpaste_snd_effect[toothpaste_NUM_TOOLS]; static Mix_Chunk *toothpaste_snd_effect[toothpaste_NUM_TOOLS];
const char * toothpaste_snd_filenames[toothpaste_NUM_TOOLS] = { const char *toothpaste_snd_filenames[toothpaste_NUM_TOOLS] = {
"toothpaste.ogg", "toothpaste.ogg",
}; };
const char * toothpaste_icon_filenames[toothpaste_NUM_TOOLS] = {
const char *toothpaste_icon_filenames[toothpaste_NUM_TOOLS] = {
"toothpaste.png", "toothpaste.png",
}; };
const char * toothpaste_names[toothpaste_NUM_TOOLS] = {
const char *toothpaste_names[toothpaste_NUM_TOOLS] = {
gettext_noop("Toothpaste"), gettext_noop("Toothpaste"),
}; };
const char * toothpaste_descs[toothpaste_NUM_TOOLS] = {
const char *toothpaste_descs[toothpaste_NUM_TOOLS] = {
gettext_noop("Click and drag to squirt toothpaste onto your picture."), gettext_noop("Click and drag to squirt toothpaste onto your picture."),
}; };
@ -72,20 +76,16 @@ const char * toothpaste_descs[toothpaste_NUM_TOOLS] = {
Uint32 toothpaste_api_version(void); Uint32 toothpaste_api_version(void);
int toothpaste_init(magic_api * api); int toothpaste_init(magic_api * api);
int toothpaste_get_tool_count(magic_api * api); int toothpaste_get_tool_count(magic_api * api);
SDL_Surface * toothpaste_get_icon(magic_api * api, int which); SDL_Surface *toothpaste_get_icon(magic_api * api, int which);
char * toothpaste_get_name(magic_api * api, int which); char *toothpaste_get_name(magic_api * api, int which);
char * toothpaste_get_description(magic_api * api, int which, int mode); char *toothpaste_get_description(magic_api * api, int which, int mode);
static void do_toothpaste(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, static void do_toothpaste(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
int x, int y);
void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas, void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void toothpaste_click(magic_api * api, int which, int mode, void toothpaste_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void toothpaste_release(magic_api * api, int which, void toothpaste_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void toothpaste_shutdown(magic_api * api); void toothpaste_shutdown(magic_api * api);
void toothpaste_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void toothpaste_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int toothpaste_requires_colors(magic_api * api, int which); int toothpaste_requires_colors(magic_api * api, int which);
@ -93,89 +93,112 @@ void toothpaste_switchin(magic_api * api, int which, int mode, SDL_Surface * can
void toothpaste_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void toothpaste_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int toothpaste_modes(magic_api * api, int which); int toothpaste_modes(magic_api * api, int which);
Uint32 toothpaste_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 toothpaste_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
int toothpaste_init(magic_api * api){ int toothpaste_init(magic_api * api)
{
int i; int i;
char fname[1024]; char fname[1024];
int k,j; int k, j;
//Load sounds //Load sounds
for (i = 0; i < toothpaste_NUM_TOOLS; i++){ for (i = 0; i < toothpaste_NUM_TOOLS; i++)
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, toothpaste_snd_filenames[i]); {
toothpaste_snd_effect[i] = Mix_LoadWAV(fname); snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, toothpaste_snd_filenames[i]);
} toothpaste_snd_effect[i] = Mix_LoadWAV(fname);
}
//Set up weights //Set up weights
pi = acos(0.0) * 2; pi = acos(0.0) * 2;
toothpaste_weights = (double*)malloc(toothpaste_RADIUS*2 * toothpaste_RADIUS*2 * sizeof(double)); toothpaste_weights = (double *)malloc(toothpaste_RADIUS * 2 * toothpaste_RADIUS * 2 * sizeof(double));
if (toothpaste_weights == NULL){ if (toothpaste_weights == NULL)
return(0); {
} return (0);
for (k = - toothpaste_RADIUS; k < + toothpaste_RADIUS; k++){
for (j = - toothpaste_RADIUS; j < + toothpaste_RADIUS; j++){
if (api->in_circle(j , k, toothpaste_RADIUS)){
toothpaste_weights[(k+toothpaste_RADIUS)*((toothpaste_RADIUS*2) -1)+(j+toothpaste_RADIUS)] = ((fabs(atan2((double)(j),(double)(k))))/pi);
}
} }
}
return(1); for (k = -toothpaste_RADIUS; k < +toothpaste_RADIUS; k++)
{
for (j = -toothpaste_RADIUS; j < +toothpaste_RADIUS; j++)
{
if (api->in_circle(j, k, toothpaste_RADIUS))
{
toothpaste_weights[(k + toothpaste_RADIUS) * ((toothpaste_RADIUS * 2) - 1) + (j + toothpaste_RADIUS)] =
((fabs(atan2((double)(j), (double)(k)))) / pi);
}
}
}
return (1);
} }
int toothpaste_get_tool_count(magic_api * api ATTRIBUTE_UNUSED){ int toothpaste_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
return(toothpaste_NUM_TOOLS); {
return (toothpaste_NUM_TOOLS);
} }
// Load our icons: // Load our icons:
SDL_Surface * toothpaste_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED){ SDL_Surface *toothpaste_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, toothpaste_icon_filenames[which]); snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, toothpaste_icon_filenames[which]);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * toothpaste_get_name(magic_api * api ATTRIBUTE_UNUSED, int which){ char *toothpaste_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
return(strdup(gettext_noop(toothpaste_names[which]))); {
return (strdup(gettext_noop(toothpaste_names[which])));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * toothpaste_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED){ char *toothpaste_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
return(strdup(gettext_noop(toothpaste_descs[which]))); {
return (strdup(gettext_noop(toothpaste_descs[which])));
} }
// Do the effect: // Do the effect:
static void do_toothpaste(void * ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y){ static void do_toothpaste(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
magic_api * api = (magic_api *) ptr; SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy; int xx, yy;
// double colr; // double colr;
float h,s,v; float h, s, v;
Uint8 r,g,b; Uint8 r, g, b;
for (yy = y - toothpaste_RADIUS; yy < y + toothpaste_RADIUS; yy++){ for (yy = y - toothpaste_RADIUS; yy < y + toothpaste_RADIUS; yy++)
for (xx = x - toothpaste_RADIUS; xx < x + toothpaste_RADIUS; xx++){ {
if (api->in_circle(xx - x, yy - y, toothpaste_RADIUS) && for (xx = x - toothpaste_RADIUS; xx < x + toothpaste_RADIUS; xx++)
!api->touched(xx, yy)){ {
if (api->in_circle(xx - x, yy - y, toothpaste_RADIUS) && !api->touched(xx, yy))
{
api->rgbtohsv(toothpaste_r, toothpaste_g, toothpaste_b, &h, &s, &v); api->rgbtohsv(toothpaste_r, toothpaste_g, toothpaste_b, &h, &s, &v);
api->hsvtorgb(h, s, toothpaste_weights[(yy-y+toothpaste_RADIUS)*((toothpaste_RADIUS*2) -1)+(xx-x+toothpaste_RADIUS)], &r, &g, &b); api->hsvtorgb(h, s,
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); toothpaste_weights[(yy - y + toothpaste_RADIUS) * ((toothpaste_RADIUS * 2) - 1) +
(xx - x + toothpaste_RADIUS)], &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
} }
}
} }
}
} }
// Affect the canvas on drag: // Affect the canvas on drag:
void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas, void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect){ {
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_toothpaste); api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_toothpaste);
api->playsound(toothpaste_snd_effect[which], (x * 255) / canvas->w, 255); api->playsound(toothpaste_snd_effect[which], (x * 255) / canvas->w, 255);
@ -188,33 +211,37 @@ void toothpaste_drag(magic_api * api, int which, SDL_Surface * canvas,
// Affect the canvas on click: // Affect the canvas on click:
void toothpaste_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void toothpaste_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect){ {
toothpaste_drag(api, which, canvas, last, x, y, x, y, update_rect); toothpaste_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:
void toothpaste_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void toothpaste_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
// No setup happened: // No setup happened:
void toothpaste_shutdown(magic_api * api ATTRIBUTE_UNUSED) void toothpaste_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ {
//Clean up sounds //Clean up sounds
int i; int i;
for(i=0; i<toothpaste_NUM_TOOLS; i++){
if(toothpaste_snd_effect[i] != NULL){ for (i = 0; i < toothpaste_NUM_TOOLS; i++)
Mix_FreeChunk(toothpaste_snd_effect[i]); {
} if (toothpaste_snd_effect[i] != NULL)
} {
if (toothpaste_weights != NULL){ Mix_FreeChunk(toothpaste_snd_effect[i]);
free(toothpaste_weights); }
toothpaste_weights = NULL; }
} if (toothpaste_weights != NULL)
{
free(toothpaste_weights);
toothpaste_weights = NULL;
}
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
@ -232,17 +259,17 @@ int toothpaste_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRI
} }
void toothpaste_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void toothpaste_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void toothpaste_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void toothpaste_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int toothpaste_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int toothpaste_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -40,20 +40,22 @@
/* Our globals: */ /* Our globals: */
enum { SIDE_LEFT, SIDE_RIGHT }; enum
enum { LEAFSIDE_RIGHT_DOWN, { SIDE_LEFT, SIDE_RIGHT };
LEAFSIDE_LEFT_DOWN, enum
LEAFSIDE_RIGHT_UP, { LEAFSIDE_RIGHT_DOWN,
LEAFSIDE_LEFT_UP }; LEAFSIDE_LEFT_DOWN,
LEAFSIDE_RIGHT_UP,
LEAFSIDE_LEFT_UP
};
static Mix_Chunk /* * tornado_click_snd, */ * tornado_release_snd; static Mix_Chunk /* * tornado_click_snd, */ * tornado_release_snd;
static Uint8 tornado_r, tornado_g, tornado_b; static Uint8 tornado_r, tornado_g, tornado_b;
static int tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y; static int tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y;
static int tornado_side_first; static int tornado_side_first;
static int tornado_side_decided; static int tornado_side_decided;
static SDL_Surface * tornado_base, * tornado_cloud, static SDL_Surface *tornado_base, *tornado_cloud, *tornado_cloud_colorized;
* tornado_cloud_colorized; static int top_w;
static int top_w;
/* Local function prototypes: */ /* Local function prototypes: */
@ -62,24 +64,22 @@ typedef struct
float x, y; float x, y;
} Point2D; } Point2D;
static void tornado_predrag(magic_api * api, SDL_Surface * canvas, static void tornado_predrag(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y);
SDL_Surface * last, int ox, int oy, int x, int y);
static void tornado_drawbase(magic_api * api, SDL_Surface * canvas); static void tornado_drawbase(magic_api * api, SDL_Surface * canvas);
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last,
int top_x, int top_y, int minx, int maxx, int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final);
int bottom_x, int bottom_y, int final);
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y); static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y);
static Point2D tornado_PointOnCubicBezier(Point2D* cp, float t); static Point2D tornado_PointOnCubicBezier(Point2D * cp, float t);
static void tornado_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve); static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve);
static void tornado_colorize_cloud(magic_api * api); static void tornado_colorize_cloud(magic_api * api);
static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas); static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas);
Uint32 tornado_api_version(void); Uint32 tornado_api_version(void);
int tornado_init(magic_api * api); int tornado_init(magic_api * api);
int tornado_get_tool_count(magic_api * api); int tornado_get_tool_count(magic_api * api);
SDL_Surface * tornado_get_icon(magic_api * api, int which); SDL_Surface *tornado_get_icon(magic_api * api, int which);
char * tornado_get_name(magic_api * api, int which); char *tornado_get_name(magic_api * api, int which);
char * tornado_get_description(magic_api * api, int which, int mode); char *tornado_get_description(magic_api * api, int which, int mode);
@ -87,14 +87,11 @@ char * tornado_get_description(magic_api * api, int which, int mode);
void tornado_drag(magic_api * api, int which, SDL_Surface * canvas, void tornado_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void tornado_click(magic_api * api, int which, int mode, void tornado_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tornado_release(magic_api * api, int which, void tornado_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tornado_shutdown(magic_api * api); void tornado_shutdown(magic_api * api);
void tornado_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void tornado_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -105,7 +102,10 @@ int tornado_modes(magic_api * api, int which);
Uint32 tornado_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 tornado_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -119,53 +119,49 @@ int tornado_init(magic_api * api)
tornado_click_snd = Mix_LoadWAV(fname); tornado_click_snd = Mix_LoadWAV(fname);
*/ */
snprintf(fname, sizeof(fname), "%s/sounds/magic/tornado_release.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/tornado_release.ogg", api->data_directory);
api->data_directory);
tornado_release_snd = Mix_LoadWAV(fname); tornado_release_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/tornado_base.png", snprintf(fname, sizeof(fname), "%s/images/magic/tornado_base.png", api->data_directory);
api->data_directory);
tornado_base = IMG_Load(fname); tornado_base = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/tornado_cloud.png", snprintf(fname, sizeof(fname), "%s/images/magic/tornado_cloud.png", api->data_directory);
api->data_directory);
tornado_cloud = IMG_Load(fname); tornado_cloud = IMG_Load(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
int tornado_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int tornado_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
// Load our icons: // Load our icons:
SDL_Surface * tornado_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *tornado_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/tornado.png", snprintf(fname, sizeof(fname), "%s/images/magic/tornado.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * tornado_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *tornado_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Tornado"))); return (strdup(gettext_noop("Tornado")));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * tornado_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) char *tornado_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Click and drag to draw a tornado funnel on your picture."))); return (strdup(gettext_noop("Click and drag to draw a tornado funnel on your picture.")));
} }
// Affect the canvas on drag: // Affect the canvas on drag:
static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y) SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y)
{ {
if (x < tornado_min_x) if (x < tornado_min_x)
tornado_min_x = x; tornado_min_x = x;
@ -184,23 +180,22 @@ static void tornado_predrag(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * canv
// Determine which way to bend first: // Determine which way to bend first:
// //
if (tornado_side_decided == 0) if (tornado_side_decided == 0)
{
if (x < tornado_bottom_x - 10)
{ {
tornado_side_first = SIDE_LEFT; if (x < tornado_bottom_x - 10)
tornado_side_decided = 1; {
tornado_side_first = SIDE_LEFT;
tornado_side_decided = 1;
}
else if (x > tornado_bottom_x + 10)
{
tornado_side_first = SIDE_RIGHT;
tornado_side_decided = 1;
}
} }
else if (x > tornado_bottom_x + 10)
{
tornado_side_first = SIDE_RIGHT;
tornado_side_decided = 1;
}
}
} }
void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
tornado_predrag(api, canvas, last, ox, oy, x, y); tornado_predrag(api, canvas, last, ox, oy, x, y);
@ -213,32 +208,30 @@ void tornado_drag(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * can
/* Draw the base and the stalk (low-quality) for now: */ /* Draw the base and the stalk (low-quality) for now: */
tornado_drawstalk(api, canvas, last, tornado_drawstalk(api, canvas, last,
x, y, tornado_min_x, tornado_max_x, x, y, tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y, !(api->button_down()));
tornado_bottom_x, tornado_bottom_y, !(api->button_down()));
tornado_drawbase(api, canvas); tornado_drawbase(api, canvas);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
} }
// Affect the canvas on click: // Affect the canvas on click:
void tornado_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void tornado_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
tornado_min_x = x; tornado_min_x = x;
tornado_max_x = x; tornado_max_x = x;
tornado_bottom_x = x; tornado_bottom_x = x;
tornado_bottom_y = y;// - tornado_base->h; tornado_bottom_y = y; // - tornado_base->h;
tornado_side_decided = 0; tornado_side_decided = 0;
tornado_side_first = SIDE_LEFT; tornado_side_first = SIDE_LEFT;
tornado_drag(api, which, canvas, last, x, y, x, y, update_rect); tornado_drag(api, which, canvas, last, x, y, x, y, update_rect);
/* /*
api->playsound(tornado_click_snd, (x * 255) / canvas->w, 255); api->playsound(tornado_click_snd, (x * 255) / canvas->w, 255);
*/ */
@ -246,8 +239,7 @@ void tornado_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release: // Affect the canvas on release:
void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED, void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
/* Don't let tornado be too low compared to base: */ /* Don't let tornado be too low compared to base: */
@ -259,7 +251,7 @@ void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
tornado_predrag(api, canvas, last, x, y, x, y); tornado_predrag(api, canvas, last, x, y, x, y);
/* Erase any old stuff: */ /* Erase any old stuff: */
SDL_BlitSurface(last, NULL, canvas, NULL); SDL_BlitSurface(last, NULL, canvas, NULL);
@ -267,15 +259,13 @@ void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
/* Draw high-quality stalk, and tornado: */ /* Draw high-quality stalk, and tornado: */
tornado_drawstalk(api, canvas, last, tornado_drawstalk(api, canvas, last, x, y, tornado_min_x, tornado_max_x, tornado_bottom_x, tornado_bottom_y, 1);
x, y, tornado_min_x, tornado_max_x,
tornado_bottom_x, tornado_bottom_y, 1);
tornado_drawtornado(api, canvas, x, y); tornado_drawtornado(api, canvas, x, y);
tornado_drawbase(api, canvas);
tornado_drawbase(api, canvas);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -287,10 +277,10 @@ void tornado_release(magic_api * api, int which ATTRIBUTE_UNUSED,
static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y) static void tornado_drawtornado(magic_api * api, SDL_Surface * canvas, int x, int y)
{ {
SDL_Surface * aux_surf; SDL_Surface *aux_surf;
SDL_Rect dest; SDL_Rect dest;
aux_surf = api->scale(tornado_cloud_colorized, top_w *2, top_w,0); aux_surf = api->scale(tornado_cloud_colorized, top_w * 2, top_w, 0);
dest.x = x - (aux_surf->w / 2); dest.x = x - (aux_surf->w / 2);
dest.y = y - (aux_surf->h / 2); dest.y = y - (aux_surf->h / 2);
@ -311,21 +301,19 @@ static void tornado_drawbase(magic_api * api ATTRIBUTE_UNUSED, SDL_Surface * can
static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas) static Uint32 tornado_mess(Uint32 pixel, SDL_Surface * canvas)
{ {
Uint8 r, g, b, a; Uint8 r, g, b, a;
float f = (float)rand()*255/RAND_MAX; float f = (float)rand() * 255 / RAND_MAX;
SDL_GetRGBA(pixel, canvas->format, &r, &g, &b, &a); SDL_GetRGBA(pixel, canvas->format, &r, &g, &b, &a);
return (SDL_MapRGBA(canvas->format, return (SDL_MapRGBA(canvas->format,
(tornado_r + r + (Uint8)f * 2) / 4, (tornado_r + r + (Uint8) f * 2) / 4,
(tornado_g + g + (Uint8)f * 2) / 4, (tornado_g + g + (Uint8) f * 2) / 4, (tornado_b + b + (Uint8) f * 2) / 4, a));
(tornado_b + b + (Uint8)f * 2) / 4,
a));
} }
static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last, static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface * last,
int top_x, int top_y, int minx, int maxx, int top_x, int top_y, int minx, int maxx, int bottom_x, int bottom_y, int final)
int bottom_x, int bottom_y, int final)
{ {
Point2D control_points[4]; Point2D control_points[4];
Point2D * curve; Point2D *curve;
int i, n_points; int i, n_points;
int left, right; int left, right;
SDL_Rect dest; SDL_Rect dest;
@ -340,22 +328,22 @@ static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface
control_points[0].y = top_y; control_points[0].y = top_y;
if (tornado_side_first == SIDE_LEFT) if (tornado_side_first == SIDE_LEFT)
{ {
control_points[1].x = minx; control_points[1].x = minx;
control_points[2].x = maxx; control_points[2].x = maxx;
} }
else else
{ {
control_points[1].x = maxx; control_points[1].x = maxx;
control_points[2].x = minx; control_points[2].x = minx;
} }
control_points[1].y = ((bottom_y - top_y) / 3) + top_y; control_points[1].y = ((bottom_y - top_y) / 3) + top_y;
control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y; control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y;
control_points[3].x = bottom_x; control_points[3].x = bottom_x;
control_points[3].y = bottom_y; control_points[3].y = bottom_y;
if (final == 0) if (final == 0)
n_points = 8; n_points = 8;
else else
@ -370,58 +358,61 @@ static void tornado_drawstalk(magic_api * api, SDL_Surface * canvas, SDL_Surface
top_w = max(32, n_points * n_points / 1000); top_w = max(32, n_points * n_points / 1000);
/* Draw the curve: */ /* Draw the curve: */
for (i = 0; i < n_points - 1; i++) for (i = 0; i < n_points - 1; i++)
{
if (final == 0)
{ {
dest.x = curve[i].x; if (final == 0)
dest.y = curve[i].y; {
dest.w = 2; dest.x = curve[i].x;
dest.h = 2; dest.y = curve[i].y;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0)); dest.w = 2;
} dest.h = 2;
else SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
{ }
ii = n_points - i;
/* min 10 pixels then ii^2 / 2000 or 4 * ii^2 / canvas->w,
don't let the top of funnel be wider than the half of canvas */
if (n_points * n_points / 2000 > canvas->w / 4)
ww = 4 * n_points * n_points / canvas->w;
else else
ww = 2000; {
ii = n_points - i;
/* min 10 pixels then ii^2 / 2000 or 4 * ii^2 / canvas->w,
don't let the top of funnel be wider than the half of canvas */
if (n_points * n_points / 2000 > canvas->w / 4)
ww = 4 * n_points * n_points / canvas->w;
else
ww = 2000;
left = min(curve[i].x, curve[i + 1].x)-5-ii*ii/ww; left = min(curve[i].x, curve[i + 1].x) - 5 - ii * ii / ww;
right = max(curve[i].x, curve[i + 1].x)+5+ii*ii/ww; right = max(curve[i].x, curve[i + 1].x) + 5 + ii * ii / ww;
dest.x = left; dest.x = left;
dest.y = curve[i].y; dest.y = curve[i].y;
dest.w = right - left + 1; dest.w = right - left + 1;
dest.h = 2; dest.h = 2;
}
rotation += 3;
/* The body of the tornado: 3x 1y rotation + some random particles */
for (p = dest.x; p < dest.x + dest.w; p++)
{
if ((float)rand() * 100 / RAND_MAX > 10)
{
api->putpixel(canvas, p, dest.y, api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y));
}
else
{
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y),
canvas));
}
}
/* Some random particles flying around the tornado */
for (p = dest.x - dest.w * 20 / 100; p < dest.x + dest.w + dest.w * 20 / 100; p++)
{
if ((float)rand() * 100 / RAND_MAX < 5 && ((p < dest.x) || (p > dest.w)))
api->putpixel(canvas, p, dest.y,
tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w, dest.y), canvas));
}
} }
rotation +=3;
/* The body of the tornado: 3x 1y rotation + some random particles */
for (p = dest.x; p < dest.x + dest.w; p++)
{
if ((float)rand() * 100 / RAND_MAX > 10 )
{
api->putpixel(canvas, p, dest.y, api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w , dest.y));
}
else
{
api->putpixel(canvas, p, dest.y, tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w , dest.y), canvas));
}
}
/* Some random particles flying around the tornado */
for (p = dest.x - dest.w * 20 / 100; p < dest.x + dest.w + dest.w * 20 / 100; p++)
{
if ((float)rand() * 100 / RAND_MAX < 5 && ((p < dest.x) || (p > dest.w)))
api->putpixel(canvas, p, dest.y, tornado_mess(api->getpixel(last, dest.x + (p - dest.x + rotation) % dest.w , dest.y), canvas));
}
}
free(curve); free(curve);
} }
@ -474,32 +465,32 @@ cp[3] is the end point, or P3 in the above diagram
t is the parameter value, 0 <= t <= 1 t is the parameter value, 0 <= t <= 1
*/ */
static Point2D tornado_PointOnCubicBezier( Point2D* cp, float t ) static Point2D tornado_PointOnCubicBezier(Point2D * cp, float t)
{ {
float ax, bx, cx; float ax, bx, cx;
float ay, by, cy; float ay, by, cy;
float tSquared, tCubed; float tSquared, tCubed;
Point2D result; Point2D result;
/* calculate the polynomial coefficients */ /* calculate the polynomial coefficients */
cx = 3.0 * (cp[1].x - cp[0].x); cx = 3.0 * (cp[1].x - cp[0].x);
bx = 3.0 * (cp[2].x - cp[1].x) - cx; bx = 3.0 * (cp[2].x - cp[1].x) - cx;
ax = cp[3].x - cp[0].x - cx - bx; ax = cp[3].x - cp[0].x - cx - bx;
cy = 3.0 * (cp[1].y - cp[0].y); cy = 3.0 * (cp[1].y - cp[0].y);
by = 3.0 * (cp[2].y - cp[1].y) - cy; by = 3.0 * (cp[2].y - cp[1].y) - cy;
ay = cp[3].y - cp[0].y - cy - by; ay = cp[3].y - cp[0].y - cy - by;
/* calculate the curve point at parameter value t */ /* calculate the curve point at parameter value t */
tSquared = t * t; tSquared = t * t;
tCubed = tSquared * t; tCubed = tSquared * t;
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x; result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y; result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
return result; return result;
} }
/* /*
@ -509,15 +500,15 @@ static Point2D tornado_PointOnCubicBezier( Point2D* cp, float t )
<sizeof(Point2D) numberOfPoints> <sizeof(Point2D) numberOfPoints>
*/ */
static void tornado_ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve ) static void tornado_ComputeBezier(Point2D * cp, int numberOfPoints, Point2D * curve)
{ {
float dt; float dt;
int i; int i;
dt = 1.0 / ( numberOfPoints - 1 ); dt = 1.0 / (numberOfPoints - 1);
for( i = 0; i < numberOfPoints; i++) for (i = 0; i < numberOfPoints; i++)
curve[i] = tornado_PointOnCubicBezier( cp, i*dt ); curve[i] = tornado_PointOnCubicBezier(cp, i * dt);
} }
@ -532,9 +523,7 @@ static void tornado_colorize_cloud(magic_api * api)
/* Create a surface to render into: */ /* Create a surface to render into: */
amask = ~(tornado_cloud->format->Rmask | amask = ~(tornado_cloud->format->Rmask | tornado_cloud->format->Gmask | tornado_cloud->format->Bmask);
tornado_cloud->format->Gmask |
tornado_cloud->format->Bmask);
tornado_cloud_colorized = tornado_cloud_colorized =
SDL_CreateRGBSurface(SDL_SWSURFACE, SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -542,8 +531,7 @@ static void tornado_colorize_cloud(magic_api * api)
tornado_cloud->h, tornado_cloud->h,
tornado_cloud->format->BitsPerPixel, tornado_cloud->format->BitsPerPixel,
tornado_cloud->format->Rmask, tornado_cloud->format->Rmask,
tornado_cloud->format->Gmask, tornado_cloud->format->Gmask, tornado_cloud->format->Bmask, amask);
tornado_cloud->format->Bmask, amask);
/* Render the new cloud: */ /* Render the new cloud: */
@ -551,32 +539,33 @@ static void tornado_colorize_cloud(magic_api * api)
SDL_LockSurface(tornado_cloud_colorized); SDL_LockSurface(tornado_cloud_colorized);
for (y = 0; y < tornado_cloud->h; y++) for (y = 0; y < tornado_cloud->h; y++)
{
for (x = 0; x < tornado_cloud->w; x++)
{ {
SDL_GetRGBA(api->getpixel(tornado_cloud, x, y), for (x = 0; x < tornado_cloud->w; x++)
tornado_cloud->format, &r, &g, &b, &a); {
SDL_GetRGBA(api->getpixel(tornado_cloud, x, y), tornado_cloud->format, &r, &g, &b, &a);
api->putpixel(tornado_cloud_colorized, x, y, api->putpixel(tornado_cloud_colorized, x, y,
SDL_MapRGBA(tornado_cloud_colorized->format, SDL_MapRGBA(tornado_cloud_colorized->format,
(tornado_r + r * 2) / 3, (tornado_g + g * 2) / 3, (tornado_b + b * 2) / 3, a)); (tornado_r + r * 2) / 3, (tornado_g + g * 2) / 3, (tornado_b + b * 2) / 3, a));
}
} }
}
SDL_UnlockSurface(tornado_cloud_colorized); SDL_UnlockSurface(tornado_cloud_colorized);
SDL_UnlockSurface(tornado_cloud); SDL_UnlockSurface(tornado_cloud);
} }
void tornado_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void tornado_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void tornado_switchout(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void tornado_switchout(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
api->stopsound(); api->stopsound();
} }
int tornado_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int tornado_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT_WITH_PREVIEW); return (MODE_PAINT_WITH_PREVIEW);
} }

View file

@ -32,42 +32,37 @@
int RADIUS = 16; int RADIUS = 16;
Mix_Chunk * tv_snd; Mix_Chunk *tv_snd;
Uint32 tv_api_version(void); Uint32 tv_api_version(void);
void tv_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void tv_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int tv_init(magic_api * api); int tv_init(magic_api * api);
int tv_get_tool_count(magic_api * api); int tv_get_tool_count(magic_api * api);
SDL_Surface * tv_get_icon(magic_api * api, int which); SDL_Surface *tv_get_icon(magic_api * api, int which);
char * tv_get_name(magic_api * api, int which); char *tv_get_name(magic_api * api, int which);
char * tv_get_description(magic_api * api, int which, int mode); char *tv_get_description(magic_api * api, int which, int mode);
int tv_requires_colors(magic_api * api, int which); int tv_requires_colors(magic_api * api, int which);
void tv_release(magic_api * api, int which, void tv_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * snapshot, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tv_shutdown(magic_api * api); void tv_shutdown(magic_api * api);
void tv_paint_tv(void * ptr_to_api, int which_tool, void tv_paint_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); void tv_do_tv(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void tv_do_tv(void * ptr_to_api, int which_tool,
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
void tv_drag(magic_api * api, int which, SDL_Surface * canvas, void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void tv_click(magic_api * api, int which, int mode, void tv_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void tv_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void tv_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void tv_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void tv_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int tv_modes(magic_api * api, int which); int tv_modes(magic_api * api, int which);
// Housekeeping functions // Housekeeping functions
Uint32 tv_api_version(void) Uint32 tv_api_version(void)
{ {
return(TP_MAGIC_API_VERSION); return (TP_MAGIC_API_VERSION);
} }
void tv_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) //get the colors from API and store it in structure void tv_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) //get the colors from API and store it in structure
{ {
} }
@ -75,79 +70,83 @@ void tv_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Ui
int tv_init(magic_api * api ATTRIBUTE_UNUSED) int tv_init(magic_api * api ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/tv.ogg", api->data_directory);
tv_snd = Mix_LoadWAV(fname);
return(1); snprintf(fname, sizeof(fname), "%s/sounds/magic/tv.ogg", api->data_directory);
tv_snd = Mix_LoadWAV(fname);
return (1);
} }
int tv_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int tv_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return 1; return 1;
} }
SDL_Surface * tv_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *tv_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/tv.png", snprintf(fname, sizeof(fname), "%s/images/magic/tv.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * tv_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("TV")); } char *tv_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return strdup(gettext_noop("TV"));
}
char * tv_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) char *tv_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return strdup(gettext_noop("Click and drag to make parts of your picture look like they are on television.")); return strdup(gettext_noop("Click and drag to make parts of your picture look like they are on television."));
else else
return strdup(gettext_noop("Click to make your picture look like it's on television.")); return strdup(gettext_noop("Click to make your picture look like it's on television."));
} }
int tv_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 0; } int tv_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return 0;
}
void tv_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void tv_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
void tv_shutdown(magic_api * api ATTRIBUTE_UNUSED) void tv_shutdown(magic_api * api ATTRIBUTE_UNUSED)
{ Mix_FreeChunk(tv_snd); } {
Mix_FreeChunk(tv_snd);
}
// Interactivity functions // Interactivity functions
void tv_paint_tv(void * ptr_to_api, int which_tool ATTRIBUTE_UNUSED, void tv_paint_tv(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{ {
int i, j; int i, j;
magic_api * api = (magic_api *) ptr_to_api; magic_api *api = (magic_api *) ptr_to_api;
for (i = x - RADIUS; i < x + RADIUS; i++) for (i = x - RADIUS; i < x + RADIUS; i++)
for (j = y - RADIUS; j < y + RADIUS; j++) for (j = y - RADIUS; j < y + RADIUS; j++)
if ((j + 1) % 2 && if ((j + 1) % 2 && api->in_circle(i - x, j - y, RADIUS) && !api->touched(i, j))
api->in_circle(i - x, j - y, RADIUS) && api->putpixel(canvas, i, j, SDL_MapRGB(canvas->format, 128, 128, 165));
! api->touched(i, j))
api->putpixel(canvas, i, j, SDL_MapRGB(canvas->format, 128, 128, 165));
} }
void tv_do_tv(void * ptr_to_api, int which_tool ATTRIBUTE_UNUSED, void tv_do_tv(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr_to_api; magic_api *api = (magic_api *) ptr_to_api;
api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 128, 128, 165)); api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 128, 128, 165));
//api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 0, 0, 255)); //api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 0, 0, 255));
} }
void tv_drag(magic_api * api, int which, SDL_Surface * canvas, void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
SDL_Rect * update_rect)
{ {
api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, tv_paint_tv); api->line(api, which, canvas, snapshot, ox, oy, x, y, 1, tv_paint_tv);
@ -159,38 +158,39 @@ void tv_drag(magic_api * api, int which, SDL_Surface * canvas,
} }
void tv_click(magic_api * api, int which, int mode, void tv_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
if (mode == MODE_FULLSCREEN) if (mode == MODE_FULLSCREEN)
{ {
int i; int i;
for (i=0; i<canvas->h; i+=2) for (i = 0; i < canvas->h; i += 2)
api->line(api, which, canvas, last, 0, i, canvas->w, i, 1, tv_do_tv); api->line(api, which, canvas, last, 0, i, canvas->w, i, 1, tv_do_tv);
update_rect->w=canvas->w; update_rect->w = canvas->w;
update_rect->h=canvas->h; update_rect->h = canvas->h;
update_rect->x=update_rect->y=0; update_rect->x = update_rect->y = 0;
api->playsound(tv_snd, 128,255); api->playsound(tv_snd, 128, 255);
} }
else else
{ {
tv_drag(api, which, canvas, last, x, y, x, y, update_rect); tv_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
} }
void tv_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void tv_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
{ SDL_Surface * canvas ATTRIBUTE_UNUSED)
{
} }
void tv_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void tv_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int tv_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int tv_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_FULLSCREEN | MODE_PAINT); return (MODE_FULLSCREEN | MODE_PAINT);
} }

View file

@ -34,25 +34,22 @@
/* Our globals: */ /* Our globals: */
static Mix_Chunk * waves_snd[2]; static Mix_Chunk *waves_snd[2];
/* Local function prototypes: */ /* Local function prototypes: */
Uint32 waves_api_version(void); Uint32 waves_api_version(void);
int waves_init(magic_api * api); int waves_init(magic_api * api);
int waves_get_tool_count(magic_api * api); int waves_get_tool_count(magic_api * api);
SDL_Surface * waves_get_icon(magic_api * api, int which); SDL_Surface *waves_get_icon(magic_api * api, int which);
char * waves_get_name(magic_api * api, int which); char *waves_get_name(magic_api * api, int which);
char * waves_get_description(magic_api * api, int which, int mode); char *waves_get_description(magic_api * api, int which, int mode);
void waves_drag(magic_api * api, int which, SDL_Surface * canvas, void waves_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void waves_click(magic_api * api, int which, int mode, void waves_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void waves_release(magic_api * api, int which, void waves_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void waves_shutdown(magic_api * api); void waves_shutdown(magic_api * api);
void waves_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void waves_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
int waves_requires_colors(magic_api * api, int which); int waves_requires_colors(magic_api * api, int which);
@ -60,7 +57,10 @@ void waves_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void waves_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void waves_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int waves_modes(magic_api * api, int which); int waves_modes(magic_api * api, int which);
Uint32 waves_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 waves_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
// No setup required: // No setup required:
@ -68,16 +68,14 @@ int waves_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/waves.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/waves.ogg", api->data_directory);
api->data_directory);
waves_snd[0] = Mix_LoadWAV(fname); waves_snd[0] = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/sounds/magic/wavelet.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/wavelet.ogg", api->data_directory);
api->data_directory);
waves_snd[1] = Mix_LoadWAV(fname); waves_snd[1] = Mix_LoadWAV(fname);
return(1); return (1);
} }
// We have multiple tools: // We have multiple tools:
@ -87,35 +85,43 @@ int waves_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
} }
// Load our icons: // Load our icons:
SDL_Surface * waves_get_icon(magic_api * api, int which) SDL_Surface *waves_get_icon(magic_api * api, int which)
{ {
char fname[1024]; char fname[1024];
if (!which) snprintf(fname, sizeof(fname), "%s/images/magic/waves.png", api->data_directory); if (!which)
else snprintf(fname, sizeof(fname), "%s/images/magic/wavelet.png", api->data_directory); snprintf(fname, sizeof(fname), "%s/images/magic/waves.png", api->data_directory);
else
snprintf(fname, sizeof(fname), "%s/images/magic/wavelet.png", api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
// Return our names, localized: // Return our names, localized:
char * waves_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) char *waves_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{ {
if (!which) return(strdup(gettext_noop("Waves"))); if (!which)
else return strdup(gettext_noop("Wavelets")); return (strdup(gettext_noop("Waves")));
else
return strdup(gettext_noop("Wavelets"));
} }
// Return our descriptions, localized: // Return our descriptions, localized:
char * waves_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) char *waves_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
{ {
if (!which) if (!which)
return(strdup(gettext_noop("Click to make the picture horizontally wavy. Click toward the top for shorter waves, the bottom for taller waves, the left for small waves, and the right for long waves."))); return (strdup
return strdup(gettext_noop("Click to make the picture vertically wavy. Click toward the top for shorter waves, the bottom for taller waves, the left for small waves, and the right for long waves.")); (gettext_noop
} ("Click to make the picture horizontally wavy. Click toward the top for shorter waves, the bottom for taller waves, the left for small waves, and the right for long waves.")));
return
strdup(gettext_noop
("Click to make the picture vertically wavy. Click toward the top for shorter waves, the bottom for taller waves, the left for small waves, and the right for long waves."));
}
void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canvas, void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y, SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
SDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
int xx, yy; int xx, yy;
SDL_Rect src, dest; SDL_Rect src, dest;
@ -123,48 +129,48 @@ void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canva
int height; int height;
SDL_BlitSurface(last, NULL, canvas, NULL); SDL_BlitSurface(last, NULL, canvas, NULL);
if (which==0)
{
//waves effect
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
for (yy = 0; yy < canvas->h; yy++)
{
xx = sin((yy * height) * M_PI / 180.0) * width;
src.x = 0; if (which == 0)
src.y = yy; {
src.w = canvas->w; //waves effect
src.h = 1; width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
dest.x = xx; for (yy = 0; yy < canvas->h; yy++)
dest.y = yy; {
xx = sin((yy * height) * M_PI / 180.0) * width;
SDL_BlitSurface(last, &src, canvas, &dest); src.x = 0;
} src.y = yy;
} src.w = canvas->w;
src.h = 1;
dest.x = xx;
dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
else else
{ {
width = ((x * 10) / canvas->w) + 10; width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1; height = ((canvas->h - y) / 10) + 1;
for (xx = 0; xx < canvas->w; xx++)
{
yy = sin((xx * height) * M_PI / 180.0) * width;
src.x = xx; for (xx = 0; xx < canvas->w; xx++)
src.y = 0; {
src.w = 1; yy = sin((xx * height) * M_PI / 180.0) * width;
src.h = canvas->h;
dest.x = xx; src.x = xx;
dest.y = yy; src.y = 0;
src.w = 1;
src.h = canvas->h;
SDL_BlitSurface(last, &src, canvas, &dest); dest.x = xx;
} dest.y = yy;
}
SDL_BlitSurface(last, &src, canvas, &dest);
}
}
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
@ -173,8 +179,7 @@ void waves_drag(magic_api * api ATTRIBUTE_UNUSED, int which, SDL_Surface * canva
// Affect the canvas on click: // Affect the canvas on click:
void waves_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void waves_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
waves_drag(api, which, canvas, last, x, y, x, y, update_rect); waves_drag(api, which, canvas, last, x, y, x, y, update_rect);
api->playsound(waves_snd[which], 128, 255); api->playsound(waves_snd[which], 128, 255);
@ -182,8 +187,8 @@ void waves_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
// Affect the canvas on release: // Affect the canvas on release:
void waves_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void waves_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -197,7 +202,8 @@ void waves_shutdown(magic_api * api ATTRIBUTE_UNUSED)
} }
// Record the color from Tux Paint: // Record the color from Tux Paint:
void waves_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void waves_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -207,15 +213,17 @@ int waves_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_
return 0; return 0;
} }
void waves_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void waves_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void waves_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void waves_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int waves_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int waves_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT); return (MODE_PAINT);
} }

View file

@ -34,26 +34,23 @@
#include "SDL_image.h" #include "SDL_image.h"
#include "SDL_mixer.h" #include "SDL_mixer.h"
static Mix_Chunk * xor_snd; static Mix_Chunk *xor_snd;
Uint32 xor_api_version(void); Uint32 xor_api_version(void);
int xor_init(magic_api * api); int xor_init(magic_api * api);
int xor_get_tool_count(magic_api * api); int xor_get_tool_count(magic_api * api);
SDL_Surface * xor_get_icon(magic_api * api, int which); SDL_Surface *xor_get_icon(magic_api * api, int which);
char * xor_get_name(magic_api * api, int which); char *xor_get_name(magic_api * api, int which);
char * xor_get_description(magic_api * api, int which, int mode); char *xor_get_description(magic_api * api, int which, int mode);
void xor_drag(magic_api * api, int which, SDL_Surface * canvas, void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
SDL_Rect * update_rect);
void xor_click(magic_api * api, int which, int mode, void xor_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void xor_release(magic_api * api, int which, void xor_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
int x, int y, SDL_Rect * update_rect);
void xor_shutdown(magic_api * api); void xor_shutdown(magic_api * api);
void xor_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); void xor_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
@ -62,123 +59,138 @@ void xor_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
void xor_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); void xor_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int xor_modes(magic_api * api, int which); int xor_modes(magic_api * api, int which);
Uint32 xor_api_version(void) { return(TP_MAGIC_API_VERSION); } Uint32 xor_api_version(void)
{
return (TP_MAGIC_API_VERSION);
}
int xor_init(magic_api * api) int xor_init(magic_api * api)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/xor.ogg", snprintf(fname, sizeof(fname), "%s/sounds/magic/xor.ogg", api->data_directory);
api->data_directory);
xor_snd = Mix_LoadWAV(fname); xor_snd = Mix_LoadWAV(fname);
return(1); return (1);
} }
int xor_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) int xor_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{ {
return(1); return (1);
} }
SDL_Surface * xor_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) SDL_Surface *xor_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
{ {
char fname[1024]; char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/xor.png", snprintf(fname, sizeof(fname), "%s/images/magic/xor.png", api->data_directory);
api->data_directory);
return(IMG_Load(fname)); return (IMG_Load(fname));
} }
char * xor_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) char *xor_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(strdup(gettext_noop("Xor Colors"))); return (strdup(gettext_noop("Xor Colors")));
} }
char * xor_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode) char *xor_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
return(strdup(gettext_noop("Click and drag to draw a XOR effect"))); return (strdup(gettext_noop("Click and drag to draw a XOR effect")));
else else
return(strdup(gettext_noop("Click to draw a XOR effect on the whole picture"))); return (strdup(gettext_noop("Click to draw a XOR effect on the whole picture")));
} }
static void do_xor(void * ptr, int which ATTRIBUTE_UNUSED, static void do_xor(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y) SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{ {
magic_api * api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r,g,b,xor; Uint8 r, g, b, xor;
float hue,sat,val; float hue, sat, val;
Uint32 pixel; Uint32 pixel;
SDL_GetRGB(api->getpixel(canvas,x,y),canvas->format,&r,&g,&b);
api->rgbtohsv(r,g,b,&hue,&sat,&val);
if (sat == 0) xor = (2*(int)hue+(x^y))%360;
else xor = ((int)hue+(x^y))%360;
api->hsvtorgb(xor,1,1,&r,&g,&b);
pixel = SDL_MapRGB(canvas->format,r,g,b);
api->putpixel(canvas,x,y,pixel);
}
static void do_xor_circle(void * ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx,yy;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(xx+x,yy+y)) do_xor(api,which,canvas,last,x + xx,y + yy);
}
}
}
}
void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_xor_circle);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r, &g, &b);
if (oy > y) { int tmp = oy; oy = y; y = tmp; } api->rgbtohsv(r, g, b, &hue, &sat, &val);
if (sat == 0)
xor = (2 * (int)hue + (x ^ y)) % 360;
else
xor = ((int)hue + (x ^ y)) % 360;
api->hsvtorgb(xor, 1, 1, &r, &g, &b);
pixel = SDL_MapRGB(canvas->format, r, g, b);
api->putpixel(canvas, x, y, pixel);
}
static void do_xor_circle(void *ptr, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
{
magic_api *api = (magic_api *) ptr;
int xx, yy;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
if (!api->touched(xx + x, yy + y))
do_xor(api, which, canvas, last, x + xx, y + yy);
}
}
}
}
void xor_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last ATTRIBUTE_UNUSED, int ox, int oy, int x, int y, SDL_Rect * update_rect)
{
api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_xor_circle);
if (ox > x)
{
int tmp = ox;
ox = x;
x = tmp;
}
if (oy > y)
{
int tmp = oy;
oy = y;
y = tmp;
}
update_rect->x = ox - 16; update_rect->x = ox - 16;
update_rect->y = oy - 16; update_rect->y = oy - 16;
update_rect->w = (x + 16) - update_rect->x; update_rect->w = (x + 16) - update_rect->x;
update_rect->h = (y + 16) - update_rect->h; update_rect->h = (y + 16) - update_rect->h;
api->playsound(xor_snd,(x * 255) / canvas->w, 255); api->playsound(xor_snd, (x * 255) / canvas->w, 255);
} }
void xor_click(magic_api * api, int which, int mode, void xor_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect)
int x, int y, SDL_Rect * update_rect)
{ {
if (mode == MODE_PAINT) if (mode == MODE_PAINT)
xor_drag(api, which, canvas, last, x, y, x, y, update_rect); xor_drag(api, which, canvas, last, x, y, x, y, update_rect);
else else
{ {
int xx, yy; int xx, yy;
for (yy = 0; yy < canvas->h; yy++) for (yy = 0; yy < canvas->h; yy++)
for (xx = 0; xx < canvas->w; xx++) for (xx = 0; xx < canvas->w; xx++)
do_xor(api, which, canvas, last, xx, yy); do_xor(api, which, canvas, last, xx, yy);
update_rect->x = 0; update_rect->x = 0;
update_rect->y = 0; update_rect->y = 0;
update_rect->w = canvas->w; update_rect->w = canvas->w;
update_rect->h = canvas->h; update_rect->h = canvas->h;
api->playsound(xor_snd,(x * 255) / canvas->w, 255); api->playsound(xor_snd, (x * 255) / canvas->w, 255);
} }
} }
void xor_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, void xor_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
{ {
} }
@ -188,7 +200,8 @@ void xor_shutdown(magic_api * api ATTRIBUTE_UNUSED)
Mix_FreeChunk(xor_snd); Mix_FreeChunk(xor_snd);
} }
void xor_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) void xor_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED,
Uint8 b ATTRIBUTE_UNUSED)
{ {
} }
@ -197,15 +210,17 @@ int xor_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UN
return 0; return 0;
} }
void xor_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void xor_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
void xor_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) void xor_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
SDL_Surface * canvas ATTRIBUTE_UNUSED)
{ {
} }
int xor_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) int xor_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{ {
return(MODE_PAINT | MODE_FULLSCREEN); return (MODE_PAINT | MODE_FULLSCREEN);
} }

13
src/.indent.pro vendored Normal file
View file

@ -0,0 +1,13 @@
--blank-lines-after-declarations
--blank-lines-after-procedures
--break-before-boolean-operator
--continue-at-parentheses
--declaration-indentation1
--dont-break-function-decl-args
--dont-break-procedure-type
--line-length120
--no-blank-lines-after-commas
--no-space-after-casts
--no-space-after-function-call-names
--no-space-after-parentheses
--no-tabs

View file

@ -1,8 +1,8 @@
/* BeOS_print.h */ /* BeOS_print.h */
/* printing support for Tux Paint */ /* printing support for Tux Paint */
/* Marcin 'Shard' Konicki <shard@beosjournal.org> */ /* Marcin 'Shard' Konicki <shard@beosjournal.org> */
/* /*
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -18,25 +18,25 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
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)
*/ */
/* Jan. 17, 2003 */ /* Jan. 17, 2003 */
/* $Id$ */ /* $Id$ */
#ifndef __BEOS_PRINT_H__ #ifndef __BEOS_PRINT_H__
#define __BEOS_PRINT_H__ #define __BEOS_PRINT_H__
#include "SDL.h" #include "SDL.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif /* __cplusplus */ #endif /* __cplusplus */
extern int SurfacePrint(SDL_Surface * surf); extern int SurfacePrint(SDL_Surface * surf);
extern int IsPrinterAvailable(); extern int IsPrinterAvailable();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __BEOS_PRINT__ */ #endif /* __BEOS_PRINT__ */

View file

@ -59,23 +59,23 @@ enum
/* Hex codes: */ /* Hex codes: */
const int default_color_hexes[NUM_DEFAULT_COLORS][3] = { const int default_color_hexes[NUM_DEFAULT_COLORS][3] = {
{0, 0, 0}, /* Black */ {0, 0, 0}, /* Black */
{128, 128, 128}, /* Dark grey */ {128, 128, 128}, /* Dark grey */
{192, 192, 192}, /* Light grey */ {192, 192, 192}, /* Light grey */
{255, 255, 255}, /* White */ {255, 255, 255}, /* White */
{255, 0, 0}, /* Red */ {255, 0, 0}, /* Red */
{255, 128, 0}, /* Orange */ {255, 128, 0}, /* Orange */
{255, 255, 0}, /* Yellow */ {255, 255, 0}, /* Yellow */
{160, 228, 128}, /* Light green */ {160, 228, 128}, /* Light green */
{33, 148, 70}, /* Dark green */ {33, 148, 70}, /* Dark green */
{138, 168, 205}, /* Sky blue */ {138, 168, 205}, /* Sky blue */
{50, 100, 255}, /* Blue */ {50, 100, 255}, /* Blue */
{186, 157, 255}, /* Lavender */ {186, 157, 255}, /* Lavender */
{128, 0, 128}, /* Purple */ {128, 0, 128}, /* Purple */
{255, 165, 211}, /* Pink */ {255, 165, 211}, /* Pink */
{128, 80, 0}, /* Brown */ {128, 80, 0}, /* Brown */
{226, 189, 166}, /* Tan */ {226, 189, 166}, /* Tan */
{247, 228, 219} /* Beige */ {247, 228, 219} /* Beige */
}; };

View file

@ -84,7 +84,7 @@
// since gcc-2.5 // since gcc-2.5
#ifdef __GNUC__ #ifdef __GNUC__
#define NORETURN __attribute__((__noreturn__)) #define NORETURN __attribute__((__noreturn__))
#define FUNCTION __attribute__((__const__)) // no access to global mem, even via ptr, and no side effect #define FUNCTION __attribute__((__const__)) // no access to global mem, even via ptr, and no side effect
#else #else
#define NORETURN #define NORETURN
#define FUNCTION #define FUNCTION

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -63,10 +63,10 @@
#define SDL_WaitThread(tid,rcp) do{(void)tid;(void)rcp;}while(0) #define SDL_WaitThread(tid,rcp) do{(void)tid;(void)rcp;}while(0)
#define SDL_Thread int #define SDL_Thread int
#define SDL_mutex int #define SDL_mutex int
#define SDL_CreateMutex() 0 // creates in released state #define SDL_CreateMutex() 0 // creates in released state
#define SDL_DestroyMutex(lock) #define SDL_DestroyMutex(lock)
#define SDL_mutexP(lock) // take lock #define SDL_mutexP(lock) // take lock
#define SDL_mutexV(lock) // release lock #define SDL_mutexV(lock) // release lock
#endif #endif
#endif #endif
@ -91,21 +91,23 @@ TTF_Font *BUGFIX_TTF_OpenFont206(const char *const file, int ptsize);
/* Stuff that wraps either SDL_Pango or SDL_TTF for font rendering: */ /* Stuff that wraps either SDL_Pango or SDL_TTF for font rendering: */
enum { enum
{
#ifndef NO_SDLPANGO #ifndef NO_SDLPANGO
FONT_TYPE_PANGO, FONT_TYPE_PANGO,
#endif #endif
FONT_TYPE_TTF FONT_TYPE_TTF
}; };
typedef struct TuxPaint_Font_s { typedef struct TuxPaint_Font_s
{
#ifndef NO_SDLPANGO #ifndef NO_SDLPANGO
SDLPango_Context * pango_context; SDLPango_Context *pango_context;
#endif #endif
int typ; int typ;
TTF_Font * ttf_font; TTF_Font *ttf_font;
int height; int height;
char * desc; char *desc;
} TuxPaint_Font; } TuxPaint_Font;
int TuxPaint_Font_FontHeight(TuxPaint_Font * tpf); int TuxPaint_Font_FontHeight(TuxPaint_Font * tpf);
@ -140,7 +142,7 @@ static int text_sizes[] = {
#endif #endif
12, 18, 24, 36, 48, 12, 18, 24, 36, 48,
56, 64, 96, 112, 128, 160 56, 64, 96, 112, 128, 160
}; // point sizes }; // point sizes
#define MIN_TEXT_SIZE 0u #define MIN_TEXT_SIZE 0u
#define MAX_TEXT_SIZE (sizeof text_sizes / sizeof text_sizes[0] - 1) #define MAX_TEXT_SIZE (sizeof text_sizes / sizeof text_sizes[0] - 1)
@ -150,12 +152,12 @@ typedef struct style_info
{ {
char *filename; char *filename;
char *directory; char *directory;
char *family; // name like "FooCorp Thunderstruck" char *family; // name like "FooCorp Thunderstruck"
char *style; // junk like "Oblique Demi-Bold" char *style; // junk like "Oblique Demi-Bold"
int italic; int italic;
int boldness; int boldness;
int score; int score;
int truetype; // Is it? (TrueType gets priority) int truetype; // Is it? (TrueType gets priority)
} style_info; } style_info;
// user's notion of a font // user's notion of a font
@ -183,15 +185,15 @@ TuxPaint_Font *getfonthandle(int desire);
int charset_works(TuxPaint_Font * font, const char *s); int charset_works(TuxPaint_Font * font, const char *s);
TuxPaint_Font * TuxPaint_Font_OpenFont(const char * pangodesc, const char * ttffilename, int size); TuxPaint_Font *TuxPaint_Font_OpenFont(const char *pangodesc, const char *ttffilename, int size);
void TuxPaint_Font_CloseFont(TuxPaint_Font * tpf); void TuxPaint_Font_CloseFont(TuxPaint_Font * tpf);
const char * TuxPaint_Font_FontFaceFamilyName(TuxPaint_Font * tpf); const char *TuxPaint_Font_FontFaceFamilyName(TuxPaint_Font * tpf);
const char * TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf); const char *TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf);
#ifdef NO_SDLPANGO #ifdef NO_SDLPANGO
TuxPaint_Font *load_locale_font(TuxPaint_Font * fallback, int size); TuxPaint_Font *load_locale_font(TuxPaint_Font * fallback, int size);
#else #else
void sdl_color_to_pango_color(SDL_Color sdl_color, SDLPango_Matrix *pango_color); void sdl_color_to_pango_color(SDL_Color sdl_color, SDLPango_Matrix * pango_color);
#endif #endif
int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, void *vp, const char *restrict const locale); int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, void *vp, const char *restrict const locale);

View file

@ -33,7 +33,7 @@
/* DIR_SAVE: Where is the user's saved directory? /* DIR_SAVE: Where is the user's saved directory?
This is where their saved files are stored This is where their saved files are stored
and where the "current_id.txt" file is saved. and where the "current_id.txt" file is saved.
Windows predefines "savedir" as: Windows predefines "savedir" as:
"C:\Documents and Settings\%USERNAME%\Application Data\TuxPaint" "C:\Documents and Settings\%USERNAME%\Application Data\TuxPaint"
though it may get overridden with "--savedir" option though it may get overridden with "--savedir" option
@ -60,10 +60,10 @@ const char *datadir;
char *get_fname(const char *const name, int kind) char *get_fname(const char *const name, int kind)
{ {
char f[512]; char f[512];
const char *restrict const dir = (kind==DIR_SAVE) ? savedir : datadir; const char *restrict const dir = (kind == DIR_SAVE) ? savedir : datadir;
// Some mkdir()'s don't like trailing slashes // Some mkdir()'s don't like trailing slashes
snprintf(f, sizeof(f), "%s%c%s", dir, (*name)?'/':'\0', name); snprintf(f, sizeof(f), "%s%c%s", dir, (*name) ? '/' : '\0', name);
return strdup(f); return strdup(f);
} }

View file

@ -28,7 +28,8 @@
extern const char *savedir; extern const char *savedir;
extern const char *datadir; extern const char *datadir;
enum { enum
{
DIR_SAVE, DIR_SAVE,
DIR_DATA DIR_DATA
}; };

View file

@ -54,20 +54,21 @@
// setlocale cannot get current default locale of the device. // setlocale cannot get current default locale of the device.
// Here, JNI and Java Locale class can get the default locale // Here, JNI and Java Locale class can get the default locale
// if user has not set locale and lang in the config file yet. // if user has not set locale and lang in the config file yet.
static char * android_locale () static char *android_locale()
{ {
static char android_locale_buf[32]; static char android_locale_buf[32];
JNIEnv *mEnv = Android_JNI_GetEnv(); JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mLocaleClass = (*mEnv)->FindClass(mEnv, "java/util/Locale"); jclass mLocaleClass = (*mEnv)->FindClass(mEnv, "java/util/Locale");
jmethodID mGetDefaultMethod = (*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault", "()Ljava/util/Locale;"); jmethodID mGetDefaultMethod = (*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault", "()Ljava/util/Locale;");
jobject mLocaleObject = (*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod); jobject mLocaleObject = (*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod);
jmethodID mToStringMethod = (*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString", "()Ljava/lang/String;"); jmethodID mToStringMethod = (*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString", "()Ljava/lang/String;");
jstring mLocaleString = (*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod); jstring mLocaleString = (*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod);
const char* locale = (*mEnv)->GetStringUTFChars(mEnv, mLocaleString, 0); const char *locale = (*mEnv)->GetStringUTFChars(mEnv, mLocaleString, 0);
strcpy(android_locale_buf, locale);
(*mEnv)->ReleaseStringUTFChars(mEnv, mLocaleString, locale); strcpy(android_locale_buf, locale);
printf("android locale %s\n", android_locale_buf); (*mEnv)->ReleaseStringUTFChars(mEnv, mLocaleString, locale);
return android_locale_buf; printf("android locale %s\n", android_locale_buf);
return android_locale_buf;
} }
#endif #endif
@ -255,7 +256,7 @@ int need_right_to_left_word;
const char *lang_prefix, *short_lang_prefix; const char *lang_prefix, *short_lang_prefix;
int num_wished_langs = 0; int num_wished_langs = 0;
w_langs wished_langs[255]; w_langs wished_langs[255];
static const language_to_locale_struct language_to_locale_array[] = { static const language_to_locale_struct language_to_locale_array[] = {
{"english", "C"}, {"english", "C"},
@ -390,10 +391,10 @@ static const language_to_locale_struct language_to_locale_array[] = {
{"northern-sotho", "nso_ZA.UTF-8"}, {"northern-sotho", "nso_ZA.UTF-8"},
{"sesotho-sa-leboa", "nso_ZA.UTF-8"}, {"sesotho-sa-leboa", "nso_ZA.UTF-8"},
{"occitan", "oc_FR.UTF-8"}, {"occitan", "oc_FR.UTF-8"},
{"odia", "or_IN.UTF-8"}, // Proper spelling {"odia", "or_IN.UTF-8"}, // Proper spelling
{"oriya", "or_IN.UTF-8"}, // Alternative {"oriya", "or_IN.UTF-8"}, // Alternative
{"ojibwe", "oj_CA.UTF-8"}, // Proper spelling {"ojibwe", "oj_CA.UTF-8"}, // Proper spelling
{"ojibway", "oj_CA.UTF-8"}, // For compatibility {"ojibway", "oj_CA.UTF-8"}, // For compatibility
{"punjabi", "pa_IN.UTF-8"}, {"punjabi", "pa_IN.UTF-8"},
{"panjabi", "pa_IN.UTF-8"}, {"panjabi", "pa_IN.UTF-8"},
{"polish", "pl_PL.UTF-8"}, {"polish", "pl_PL.UTF-8"},
@ -409,7 +410,7 @@ static const language_to_locale_struct language_to_locale_array[] = {
{"sanskrit", "sa_IN.UTF-8"}, {"sanskrit", "sa_IN.UTF-8"},
{"santali-devaganari", "sat_IN.UTF-8"}, {"santali-devaganari", "sat_IN.UTF-8"},
{"santali-ol-chiki", "sat@olchiki"}, {"santali-ol-chiki", "sat@olchiki"},
{"serbian", "sr_RS.UTF-8"}, /* Was sr_YU, but that's not in /usr/share/i18n/SUPPORTED, and sr_RS is -bjk 2014.08.04 */ {"serbian", "sr_RS.UTF-8"}, /* Was sr_YU, but that's not in /usr/share/i18n/SUPPORTED, and sr_RS is -bjk 2014.08.04 */
{"serbian-latin", "sr_RS@latin"}, {"serbian-latin", "sr_RS@latin"},
{"shuswap", "shs_CA.UTF-8"}, {"shuswap", "shs_CA.UTF-8"},
{"secwepemctin", "shs_CA.UTF-8"}, {"secwepemctin", "shs_CA.UTF-8"},
@ -426,7 +427,7 @@ static const language_to_locale_struct language_to_locale_array[] = {
{"swahili", "sw_TZ.UTF-8"}, {"swahili", "sw_TZ.UTF-8"},
{"tagalog", "tl_PH.UTF-8"}, {"tagalog", "tl_PH.UTF-8"},
{"thai", "th_TH.UTF-8"}, {"thai", "th_TH.UTF-8"},
{"tibetan", "bo_CN.UTF-8"}, /* Based on: http://texinfo.org/pipermail/texinfo-pretest/2005-April/000334.html */ {"tibetan", "bo_CN.UTF-8"}, /* Based on: http://texinfo.org/pipermail/texinfo-pretest/2005-April/000334.html */
{"turkish", "tr_TR.UTF-8"}, {"turkish", "tr_TR.UTF-8"},
{"twi", "tw_GH.UTF-8"}, {"twi", "tw_GH.UTF-8"},
{"ukrainian", "uk_UA.UTF-8"}, {"ukrainian", "uk_UA.UTF-8"},
@ -449,13 +450,12 @@ static const language_to_locale_struct language_to_locale_array[] = {
/* Show available languages: */ /* Show available languages: */
static void show_lang_usage(int exitcode) static void show_lang_usage(int exitcode)
{ {
FILE * f = exitcode ? stderr : stdout; FILE *f = exitcode ? stderr : stdout;
const char *const prg = "tuxpaint"; const char *const prg = "tuxpaint";
fprintf(f,
"\n" fprintf(f, "\n" "Usage: %s [--lang LANGUAGE]\n" "\n" "LANGUAGE may be one of:\n"
"Usage: %s [--lang LANGUAGE]\n" "\n" "LANGUAGE may be one of:\n" /* C */ " english american-english\n"
/* C */ " english american-english\n" /* ach */ " acholi acoli\n"
/* ach */" acholi acoli\n"
/* af */ " afrikaans\n" /* af */ " afrikaans\n"
/* ak */ " akan twi-fante\n" /* ak */ " akan twi-fante\n"
/* sq */ " albanian\n" /* sq */ " albanian\n"
@ -464,7 +464,7 @@ static void show_lang_usage(int exitcode)
/* an */ " aragones\n" /* an */ " aragones\n"
/* hy */ " armenian hayeren\n" /* hy */ " armenian hayeren\n"
/* as */ " assamese\n" /* as */ " assamese\n"
/* ast */" asturian\n" /* ast */ " asturian\n"
/* en_AU */ " australian-english\n" /* en_AU */ " australian-english\n"
/* az */ " azerbaijani\n" /* az */ " azerbaijani\n"
/* bm */ " bambara\n" /* bm */ " bambara\n"
@ -498,7 +498,7 @@ static void show_lang_usage(int exitcode)
/* ka */ " georgian\n" /* ka */ " georgian\n"
/* de */ " german deutsch\n" /* de */ " german deutsch\n"
/* el */ " greek\n" /* el */ " greek\n"
/* gos */" gronings zudelk-veenkelonioals\n" /* gos */ " gronings zudelk-veenkelonioals\n"
/* gu */ " gujarati\n" /* gu */ " gujarati\n"
/* he */ " hebrew\n" /* he */ " hebrew\n"
/* hi */ " hindi\n" /* hi */ " hindi\n"
@ -513,18 +513,18 @@ static void show_lang_usage(int exitcode)
/* ks@devanagari */ " kashmiri-devanagari\n" /* ks@devanagari */ " kashmiri-devanagari\n"
/* ks */ " kashmiri-perso-arabic\n" /* ks */ " kashmiri-perso-arabic\n"
/* km */ " khmer\n" /* km */ " khmer\n"
/* cgg */" kiga chiga\n" /* cgg */ " kiga chiga\n"
/* rw */ " kinyarwanda\n" /* rw */ " kinyarwanda\n"
/* tlh */" klingon tlhIngan\n" /* tlh */ " klingon tlhIngan\n"
/* kok */" konkani-devaganari\n" /* kok */ " konkani-devaganari\n"
/* kok@roman */" konkani-roman\n" /* kok@roman */ " konkani-roman\n"
/* ko */ " korean\n" /* ko */ " korean\n"
/* ku */ " kurdish\n" /* ku */ " kurdish\n"
/* lv */ " latvian\n" /* lv */ " latvian\n"
/* lt */ " lithuanian lietuviu\n" /* lt */ " lithuanian lietuviu\n"
/* lg */ " luganda\n" /* lg */ " luganda\n"
/* lb */ " luxembourgish letzebuergesch\n" /* lb */ " luxembourgish letzebuergesch\n"
/* mai */" maithili\n" /* mai */ " maithili\n"
/* mk */ " macedonian\n" /* mk */ " macedonian\n"
/* ms */ " malay\n" /* ms */ " malay\n"
/* ml */ " malayalam\n" /* ml */ " malayalam\n"
@ -535,7 +535,7 @@ static void show_lang_usage(int exitcode)
/* mn */ " mongolian\n" /* mn */ " mongolian\n"
/* nr */ " ndebele\n" /* nr */ " ndebele\n"
/* ne */ " nepali\n" /* ne */ " nepali\n"
/* nso */" northern-sotho sesotho-sa-leboa\n" /* nso */ " northern-sotho sesotho-sa-leboa\n"
/* nn */ " norwegian nynorsk norsk\n" /* nn */ " norwegian nynorsk norsk\n"
/* oc */ " occitan\n" /* oc */ " occitan\n"
/* or */ " odia oriya\n" /* or */ " odia oriya\n"
@ -547,8 +547,8 @@ static void show_lang_usage(int exitcode)
/* ro */ " romanian\n" /* ro */ " romanian\n"
/* ru */ " russian russkiy\n" /* ru */ " russian russkiy\n"
/* sa */ " sanskrit\n" /* sa */ " sanskrit\n"
/* sat */" santali-devaganari\n" /* sat */ " santali-devaganari\n"
/* sat@olchiki */" santali-ol-chiki\n" /* sat@olchiki */ " santali-ol-chiki\n"
/* gd */ " scottish scottish-gaelic ghaidhlig\n" /* gd */ " scottish scottish-gaelic ghaidhlig\n"
/* sr */ " serbian\n" /* sr */ " serbian\n"
/* sr@latin */ " serbian-latin\n" /* sr@latin */ " serbian-latin\n"
@ -573,15 +573,15 @@ static void show_lang_usage(int exitcode)
/* tr */ " turkish\n" /* tr */ " turkish\n"
/* uk */ " ukrainian\n" /* uk */ " ukrainian\n"
/* ur */ " urdu\n" /* ur */ " urdu\n"
/* ca@valencia */ " valencian valencia\n" /* ca@valencia */ " valencian valencia\n"
/* ve */ " venda\n" /* ve */ " venda\n"
/* vec */" venetian veneto\n" /* vec */ " venetian veneto\n"
/* vi */ " vietnamese\n" /* vi */ " vietnamese\n"
/* wa */ " walloon walon\n" /* wa */ " walloon walon\n"
/* wo */ " wolof\n" /* wo */ " wolof\n"
/* cy */ " welsh cymraeg\n" /* cy */ " welsh cymraeg\n"
/* xh */ " xhosa\n" /* xh */ " xhosa\n"
/* zam */" zapotec miahuatlan-zapotec\n" /* zam */ " zapotec miahuatlan-zapotec\n"
/* zu */ " zulu\n" /* zu */ " zulu\n"
"\n", prg); "\n", prg);
exit(exitcode); exit(exitcode);
@ -593,13 +593,13 @@ static void show_lang_usage(int exitcode)
static void show_locale_usage(FILE * f, const char *const prg) static void show_locale_usage(FILE * f, const char *const prg)
{ {
fprintf(f, fprintf(f,
"\n" "\n"
"Usage: %s [--locale LOCALE]\n" "Usage: %s [--locale LOCALE]\n"
"\n" "\n"
"LOCALE may be one of:\n" "LOCALE may be one of:\n"
" C (English American English)\n" " C (English American English)\n"
" ach_UG (Acholi Acoli)\n" " ach_UG (Acholi Acoli)\n"
" af_ZA (Afrikaans)\n" " af_ZA (Afrikaans)\n"
" ak_GH (Akan Twi-Fante)\n" " ak_GH (Akan Twi-Fante)\n"
" am_ET (Amharic)\n" " am_ET (Amharic)\n"
" ar_SA (Arabic)\n" " ar_SA (Arabic)\n"
@ -615,44 +615,44 @@ static void show_locale_usage(FILE * f, const char *const prg)
" brx_IN (Bodo)\n" " brx_IN (Bodo)\n"
" bs_BA (Bosnian)\n" " bs_BA (Bosnian)\n"
" nb_NO (Bokmal)\n" " nb_NO (Bokmal)\n"
" pt_BR (Brazilian Brazilian Portuguese Portugues Brazilian)\n" " pt_BR (Brazilian Brazilian Portuguese Portugues Brazilian)\n"
" br_FR (Breton Brezhoneg)\n" " br_FR (Breton Brezhoneg)\n"
" en_AU (Australian English)\n" " en_AU (Australian English)\n"
" en_CA (Canadian English)\n" " en_CA (Canadian English)\n"
" en_GB (British British English)\n" " en_GB (British British English)\n"
" en_ZA (South African English)\n" " en_ZA (South African English)\n"
" bg_BG (Bulgarian)\n" " bg_BG (Bulgarian)\n"
" ca_ES (Catalan Catala)\n" " ca_ES (Catalan Catala)\n"
" ca_ES@valencia (Valencian Valencia)n" " ca_ES@valencia (Valencian Valencia)n"
" zh_CN (Chinese-Simplified)\n" " zh_CN (Chinese-Simplified)\n"
" zh_TW (Chinese-Traditional)\n" " zh_TW (Chinese-Traditional)\n"
" cs_CZ (Czech Cesky)\n" " cs_CZ (Czech Cesky)\n"
" da_DK (Danish Dansk)\n" " da_DK (Danish Dansk)\n"
" doi_IN (Dogri)\n" " doi_IN (Dogri)\n"
" nl_NL (Dutch)\n" " nl_NL (Dutch)\n"
" fa_IR (Persian)\n" " fa_IR (Persian)\n"
" ff_SN (Fulah)\n" " ff_SN (Fulah)\n"
" fi_FI (Finnish Suomi)\n" " fi_FI (Finnish Suomi)\n"
" fo_FO (Faroese)\n" " fo_FO (Faroese)\n"
" fr_FR (French Francais)\n" " fr_FR (French Francais)\n"
" ga_IE (Irish Gaelic Gaidhlig)\n" " ga_IE (Irish Gaelic Gaidhlig)\n"
" gd_GB (Scottish Gaelic Ghaidhlig)\n" " gd_GB (Scottish Gaelic Ghaidhlig)\n"
" gl_ES (Galician Galego)\n" " gl_ES (Galician Galego)\n"
" gos_NL (Gronings Zudelk Veenkelonioals)\n" " gos_NL (Gronings Zudelk Veenkelonioals)\n"
" gu_IN (Gujarati)\n" " gu_IN (Gujarati)\n"
" de_DE (German Deutsch)\n" " de_DE (German Deutsch)\n"
" eo (Esperanto)\n" " eo (Esperanto)\n"
" et_EE (Estonian)\n" " et_EE (Estonian)\n"
" el_GR (Greek)\n" " el_GR (Greek)\n"
" he_IL (Hebrew)\n" " he_IL (Hebrew)\n"
" hi_IN (Hindi)\n" " hi_IN (Hindi)\n"
" hr_HR (Croatian Hrvatski)\n" " hr_HR (Croatian Hrvatski)\n"
" hu_HU (Hungarian Magyar)\n" " hu_HU (Hungarian Magyar)\n"
" cgg_UG (Kiga Chiga)\n" " cgg_UG (Kiga Chiga)\n"
" tlh (Klingon tlhIngan)\n" " tlh (Klingon tlhIngan)\n"
" is_IS (Icelandic Islenska)\n" " is_IS (Icelandic Islenska)\n"
" id_ID (Indonesian Bahasa Indonesia)\n" " id_ID (Indonesian Bahasa Indonesia)\n"
" it_IT (Italian Italiano)\n" " it_IT (Italian Italiano)\n"
" iu_CA (Inuktitut)\n" " iu_CA (Inuktitut)\n"
" ja_JP (Japanese)\n" " ja_JP (Japanese)\n"
" ka_GE (Georgian)\n" " ka_GE (Georgian)\n"
@ -679,16 +679,16 @@ static void show_locale_usage(FILE * f, const char *const prg)
" nr_ZA (Ndebele)\n" " nr_ZA (Ndebele)\n"
" ne_NP (Nepali)\n" " ne_NP (Nepali)\n"
" nso_ZA (Northern Sotho Sotho sa Leboa)\n" " nso_ZA (Northern Sotho Sotho sa Leboa)\n"
" nn_NO (Norwegian Nynorsk Norsk)\n" " nn_NO (Norwegian Nynorsk Norsk)\n"
" oc_FR (Occitan)\n" " oc_FR (Occitan)\n"
" oj_CA (Ojibway)\n" " oj_CA (Ojibway)\n"
" or_IN (Odia Oriya)\n" " or_IN (Odia Oriya)\n"
" pa_IN (Punjabi Panjabi)\n" " pa_IN (Punjabi Panjabi)\n"
" pl_PL (Polish Polski)\n" " pl_PL (Polish Polski)\n"
" pt_PT (Portuguese Portugues)\n" " pt_PT (Portuguese Portugues)\n"
" ro_RO (Romanian)\n" " ro_RO (Romanian)\n"
" ru_RU (Russian Russkiy)\n" " ru_RU (Russian Russkiy)\n"
" rw_RW (Kinyarwanda)\n" " rw_RW (Kinyarwanda)\n"
" sa_IN (Sanskrit)\n" " sa_IN (Sanskrit)\n"
" sat_IN (Santali)\n" " sat_IN (Santali)\n"
" sat@olchiki (Santali (Ol-Chiki))\n" " sat@olchiki (Santali (Ol-Chiki))\n"
@ -696,10 +696,10 @@ static void show_locale_usage(FILE * f, const char *const prg)
" sd_IN (Sindhii (Perso-Arabic))\n" " sd_IN (Sindhii (Perso-Arabic))\n"
" shs_CA (Shuswap Secwepemctin)\n" " shs_CA (Shuswap Secwepemctin)\n"
" si_LK (Sinhala)\n" " si_LK (Sinhala)\n"
" sk_SK (Slovak)\n" " sk_SK (Slovak)\n"
" sl_SI (Slovenian)\n" " sl_SI (Slovenian)\n"
" son (Songhay)\n" " son (Songhay)\n"
" sq_AL (Albanian)\n" " sq_AL (Albanian)\n"
" sr_YU (Serbian (cyrillic))\n" " sr_YU (Serbian (cyrillic))\n"
" sr_RS@latin (Serbian (latin))\n" " sr_RS@latin (Serbian (latin))\n"
" es_ES (Spanish Espanol)\n" " es_ES (Spanish Espanol)\n"
@ -707,12 +707,12 @@ static void show_locale_usage(FILE * f, const char *const prg)
" es_MX (Mexican Mexican Spanish Espanol Mejicano)\n" " es_MX (Mexican Mexican Spanish Espanol Mejicano)\n"
" sw_TZ (Swahili)\n" " sw_TZ (Swahili)\n"
" sv_SE (Swedish Svenska)\n" " sv_SE (Swedish Svenska)\n"
" ta_IN (Tamil)\n" " ta_IN (Tamil)\n"
" te_IN (Telugu)\n" " te_IN (Telugu)\n"
" tl_PH (Tagalog)\n" " tl_PH (Tagalog)\n"
" bo_CN (Tibetan)\n" " bo_CN (Tibetan)\n"
" th_TH (Thai)\n" " th_TH (Thai)\n"
" tr_TR (Turkish)\n" " tr_TR (Turkish)\n"
" tw_GH (Twi)\n" " tw_GH (Twi)\n"
" uk_UA (Ukrainian)\n" " uk_UA (Ukrainian)\n"
" ur_IN (Urdu)\n" " ur_IN (Urdu)\n"
@ -722,10 +722,7 @@ static void show_locale_usage(FILE * f, const char *const prg)
" wa_BE (Walloon)\n" " wa_BE (Walloon)\n"
" wo_SN (Wolof)\n" " wo_SN (Wolof)\n"
" cy_GB (Welsh Cymraeg)\n" " cy_GB (Welsh Cymraeg)\n"
" xh_ZA (Xhosa)\n" " xh_ZA (Xhosa)\n" " zam (Zapoteco-Miahuatlan)\n" " zu_ZA (Zulu)\n" "\n", prg);
" zam (Zapoteco-Miahuatlan)\n"
" zu_ZA (Zulu)\n"
"\n", prg);
} }
@ -740,10 +737,10 @@ static int search_int_array(int l, int *array)
int i; int i;
for (i = 0; array[i] != -1; i++) for (i = 0; array[i] != -1; i++)
{ {
if (array[i] == l) if (array[i] == l)
return 1; return 1;
} }
return 0; return 0;
} }
@ -754,17 +751,19 @@ static void ctype_utf8(void)
{ {
#ifndef _WIN32 #ifndef _WIN32
/* FIXME: should this iterate over more locales? /* FIXME: should this iterate over more locales?
A zapotec speaker may have es_MX.UTF-8 available but not have en_US.UTF-8 for example */ A zapotec speaker may have es_MX.UTF-8 available but not have en_US.UTF-8 for example */
const char *names[] = {"en_US.UTF8","en_US.UTF-8","UTF8","UTF-8","C.UTF-8"}; const char *names[] = { "en_US.UTF8", "en_US.UTF-8", "UTF8", "UTF-8", "C.UTF-8" };
int i = sizeof(names)/sizeof(names[0]); int i = sizeof(names) / sizeof(names[0]);
for(;;){
if(iswprint((wchar_t)0xf7)) // division symbol -- which is in Latin-1 :-/ for (;;)
return; {
if(--i < 0) if (iswprint((wchar_t) 0xf7)) // division symbol -- which is in Latin-1 :-/
break; return;
setlocale(LC_CTYPE,names[i]); if (--i < 0)
setlocale(LC_MESSAGES,names[i]); break;
} setlocale(LC_CTYPE, names[i]);
setlocale(LC_MESSAGES, names[i]);
}
fprintf(stderr, "Failed to find a locale with iswprint() working!\n"); fprintf(stderr, "Failed to find a locale with iswprint() working!\n");
#endif #endif
} }
@ -773,11 +772,12 @@ static void ctype_utf8(void)
static const char *language_to_locale(const char *langstr) static const char *language_to_locale(const char *langstr)
{ {
int i = sizeof language_to_locale_array / sizeof language_to_locale_array[0]; int i = sizeof language_to_locale_array / sizeof language_to_locale_array[0];
while (i--) while (i--)
{ {
if (!strcmp(langstr, language_to_locale_array[i].language)) if (!strcmp(langstr, language_to_locale_array[i].language))
return language_to_locale_array[i].locale; return language_to_locale_array[i].locale;
} }
if (strcmp(langstr, "help") == 0 || strcmp(langstr, "list") == 0) if (strcmp(langstr, "help") == 0 || strcmp(langstr, "list") == 0)
show_lang_usage(0); show_lang_usage(0);
fprintf(stderr, "%s is an invalid language\n", langstr); fprintf(stderr, "%s is an invalid language\n", langstr);
@ -797,6 +797,7 @@ static void set_langint_from_locale_string(const char *restrict loc)
size_t len_baseloc; size_t len_baseloc;
int found = 0; int found = 0;
int i; int i;
// printf("langint %i\n", langint); // printf("langint %i\n", langint);
if (!loc) if (!loc)
@ -808,75 +809,73 @@ static void set_langint_from_locale_string(const char *restrict loc)
if it still fails, try to find language and country code without the variant, if it still fails, try to find language and country code without the variant,
finally scan just the lang part. finally scan just the lang part.
as a last resource reverse the scanning as a last resource reverse the scanning
*/ */
if(dot) if (dot)
*dot = '\0'; *dot = '\0';
if (cntrycode) if (cntrycode)
{ {
ccodeaux = strdup(cntrycode); ccodeaux = strdup(cntrycode);
*cntrycode = '\0'; *cntrycode = '\0';
} }
if (at) if (at)
{
ataux = strdup(at);
*at = '\0';
if(cntrycode)
{ {
/* ll_CC@variant */ ataux = strdup(at);
//if (found == 0) printf("ll_CC@variant check\n"); *at = '\0';
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
if (cntrycode)
{
/* ll_CC@variant */
//if (found == 0) printf("ll_CC@variant check\n");
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
langint = i;
found = 1;
}
}
}
/* ll@variant */
//if (found == 0) printf("ll@variant check\n");
snprintf(straux, 255, "%s%s", baseloc, ataux);
len_baseloc = strlen(straux); len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++) for (i = 0; i < NUM_LANGS && found == 0; i++)
{ {
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.) // Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
!strncasecmp(straux, lang_prefixes[i], len_baseloc)) {
{ langint = i;
langint = i; found = 1;
found = 1; }
} }
}
} }
/* ll@variant*/ if (cntrycode)
//if (found == 0) printf("ll@variant check\n");
snprintf(straux, 255, "%s%s", baseloc, ataux);
len_baseloc = strlen(straux);
for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) &&
!strncasecmp(straux, lang_prefixes[i], len_baseloc))
{
langint = i;
found = 1;
}
}
}
if(cntrycode)
{ {
/* ll_CC */ /* ll_CC */
//if (found == 0) printf("ll_CC check\n"); //if (found == 0) printf("ll_CC check\n");
snprintf(straux, 255, "%s%s",baseloc, ccodeaux); snprintf(straux, 255, "%s%s", baseloc, ccodeaux);
len_baseloc = strlen(straux); len_baseloc = strlen(straux);
/* Which, if any, of the locales is it? */ /* Which, if any, of the locales is it? */
for (i = 0; i < NUM_LANGS && found == 0; i++) for (i = 0; i < NUM_LANGS && found == 0; i++)
{ {
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.) // Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) && if (len_baseloc == strlen(lang_prefixes[i]) &&
!strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i]))) !strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i])))
{ {
langint = i; langint = i;
found = 1; found = 1;
} }
} }
} }
/* ll */ /* ll */
@ -885,15 +884,14 @@ static void set_langint_from_locale_string(const char *restrict loc)
/* Which, if any, of the locales is it? */ /* Which, if any, of the locales is it? */
for (i = 0; i < NUM_LANGS && found == 0; i++) for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (len_baseloc == strlen(lang_prefixes[i]) &&
!strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
{ {
langint = i; // Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
found = 1; if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
} }
}
/* Last resource, we should never arrive here, this check depends /* Last resource, we should never arrive here, this check depends
on the right order in lang_prefixes[] on the right order in lang_prefixes[]
@ -903,21 +901,21 @@ static void set_langint_from_locale_string(const char *restrict loc)
// printf("Language still not found: loc= %s Trying reverse check as last resource...\n", loc); // printf("Language still not found: loc= %s Trying reverse check as last resource...\n", loc);
for (i = 0; i < NUM_LANGS && found == 0; i++) for (i = 0; i < NUM_LANGS && found == 0; i++)
{
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
{ {
langint = i; // Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
found = 1; if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
{
langint = i;
found = 1;
}
} }
}
// printf("langint %i, lang_ext %s\n", langint, lang_prefixes[langint]); // printf("langint %i, lang_ext %s\n", langint, lang_prefixes[langint]);
free(baseloc); free(baseloc);
if (ataux) if (ataux)
free(ataux); free(ataux);
if (ccodeaux) if (ccodeaux)
free(ccodeaux); free(ccodeaux);
} }
#define HAVE_SETENV #define HAVE_SETENV
@ -930,8 +928,9 @@ static void mysetenv(const char *name, const char *value)
#ifdef HAVE_SETENV #ifdef HAVE_SETENV
setenv(name, value, 1); setenv(name, value, 1);
#else #else
int len = strlen(name)+1+strlen(value)+1; int len = strlen(name) + 1 + strlen(value) + 1;
char *str = malloc(len); char *str = malloc(len);
sprintf(str, "%s=%s", name, value); sprintf(str, "%s=%s", name, value);
putenv(str); putenv(str);
#endif #endif
@ -939,32 +938,32 @@ static void mysetenv(const char *name, const char *value)
static int set_current_language(const char *restrict locale_choice) MUST_CHECK; static int set_current_language(const char *restrict locale_choice) MUST_CHECK;
static int set_current_language(const char *restrict loc) static int set_current_language(const char *restrict loc)
{ {
int i; int i;
int y_nudge = 0; int y_nudge = 0;
char * oldloc; char *oldloc;
char *env_language; char *env_language;
if (strlen(loc) > 0) if (strlen(loc) > 0)
{
/* Got command line or config file language */
mysetenv("LANGUAGE", loc);
}
else
{
/* Find what language to use from env vars */
if (getenv("LANGUAGE") == NULL)
{ {
if (getenv("LC_ALL")) /* Got command line or config file language */
mysetenv("LANGUAGE", getenv("LC_ALL")); mysetenv("LANGUAGE", loc);
else if (getenv("LC_MESSAGES")) }
mysetenv("LANGUAGE", getenv("LC_MESSAGES")); else
else if (getenv("LANG")) {
mysetenv("LANGUAGE", getenv("LANG")); /* Find what language to use from env vars */
if (getenv("LANGUAGE") == NULL)
{
if (getenv("LC_ALL"))
mysetenv("LANGUAGE", getenv("LC_ALL"));
else if (getenv("LC_MESSAGES"))
mysetenv("LANGUAGE", getenv("LC_MESSAGES"));
else if (getenv("LANG"))
mysetenv("LANGUAGE", getenv("LANG"));
}
} }
}
oldloc = strdup(loc); oldloc = strdup(loc);
@ -972,14 +971,14 @@ static int set_current_language(const char *restrict loc)
after that, ctype_utf8() call will test the compatibility with utf8 and try to load after that, ctype_utf8() call will test the compatibility with utf8 and try to load
a different locale if the resulting one is not compatible. */ a different locale if the resulting one is not compatible. */
#ifdef DEBUG #ifdef DEBUG
printf ("Locale BEFORE is: %s\n", setlocale(LC_ALL,NULL));//EP printf("Locale BEFORE is: %s\n", setlocale(LC_ALL, NULL)); //EP
#endif #endif
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
setlocale(LC_ALL, loc); setlocale(LC_ALL, loc);
ctype_utf8(); ctype_utf8();
#ifdef DEBUG #ifdef DEBUG
printf ("Locale AFTER is: %s\n", setlocale(LC_ALL,NULL));//EP printf("Locale AFTER is: %s\n", setlocale(LC_ALL, NULL)); //EP
#endif #endif
bindtextdomain("tuxpaint", LOCALEDIR); bindtextdomain("tuxpaint", LOCALEDIR);
/* Old version of glibc does not have bind_textdomain_codeset() */ /* Old version of glibc does not have bind_textdomain_codeset() */
@ -997,78 +996,82 @@ printf ("Locale AFTER is: %s\n", setlocale(LC_ALL,NULL));//EP
loc = setlocale(LC_MESSAGES, NULL); loc = setlocale(LC_MESSAGES, NULL);
#endif #endif
if (oldloc && loc && strcmp(oldloc, "") != 0 && strcmp(loc, oldloc) != 0) { if (oldloc && loc && strcmp(oldloc, "") != 0 && strcmp(loc, oldloc) != 0)
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */ {
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */
/* Albert's comments from December 2009: /* Albert's comments from December 2009:
gettext() won't even bother to look up messages unless it gettext() won't even bother to look up messages unless it
is totally satisfied that you are using one of the locales that is totally satisfied that you are using one of the locales that
it ships with! Make gettext() unhappy, and it'll switch to the it ships with! Make gettext() unhappy, and it'll switch to the
lobotomized 7-bit Linux "C" locale just to spite you. lobotomized 7-bit Linux "C" locale just to spite you.
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
You can confuse gettext() into mostly behaving. For example, a
user could pick a random UTF-8 locale and change the messages.
In that case, Tux Paint thinks it's in the other locale but the
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
or set it to random nonsense. Yeah, Tux Paint will think it's in
a French locale, but the messages will be Zapotec nonetheless.
Maybe it's time to give up on gettext().
[see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ] http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
*/
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */ You can confuse gettext() into mostly behaving. For example, a
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */ user could pick a random UTF-8 locale and change the messages.
In that case, Tux Paint thinks it's in the other locale but the
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
or set it to random nonsense. Yeah, Tux Paint will think it's in
a French locale, but the messages will be Zapotec nonetheless.
mysetenv("LANGUAGE", oldloc); Maybe it's time to give up on gettext().
set_langint_from_locale_string(oldloc);
} else { [see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ]
*/
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */
mysetenv("LANGUAGE", oldloc);
set_langint_from_locale_string(oldloc);
}
else
{
#ifdef _WIN32 #ifdef _WIN32
if (getenv("LANGUAGE") == NULL) if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", loc); mysetenv("LANGUAGE", loc);
#endif #endif
if (getenv("LANGUAGE") == NULL) if (getenv("LANGUAGE") == NULL)
mysetenv("LANGUAGE", "C"); mysetenv("LANGUAGE", "C");
} }
env_language = strdup(getenv("LANGUAGE")); env_language = strdup(getenv("LANGUAGE"));
int j = 0; int j = 0;
char *env_language_lang; char *env_language_lang;
if (*env_language)
{ if (*env_language)
{
env_language_lang = strtok(env_language, ":"); env_language_lang = strtok(env_language, ":");
while (env_language_lang != NULL) while (env_language_lang != NULL)
{ {
num_wished_langs++; num_wished_langs++;
set_langint_from_locale_string(env_language_lang); set_langint_from_locale_string(env_language_lang);
wished_langs[j].langint = langint; wished_langs[j].langint = langint;
wished_langs[j].lang_prefix = lang_prefixes[langint]; wished_langs[j].lang_prefix = lang_prefixes[langint];
wished_langs[j].need_own_font = search_int_array(langint, lang_use_own_font); wished_langs[j].need_own_font = search_int_array(langint, lang_use_own_font);
wished_langs[j].need_right_to_left = search_int_array(langint, lang_use_right_to_left); wished_langs[j].need_right_to_left = search_int_array(langint, lang_use_right_to_left);
wished_langs[j].need_right_to_left_word = search_int_array(langint, lang_use_right_to_left_word); wished_langs[j].need_right_to_left_word = search_int_array(langint, lang_use_right_to_left_word);
for (i = 0; lang_y_nudge[i][0] != -1; i++) for (i = 0; lang_y_nudge[i][0] != -1; i++)
{ {
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]); // printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
if (lang_y_nudge[i][0] == langint) if (lang_y_nudge[i][0] == langint)
{ {
wished_langs[j].lang_y_nudge = lang_y_nudge[i][1]; wished_langs[j].lang_y_nudge = lang_y_nudge[i][1];
//printf("y_nudge = %d\n", y_nudge); //printf("y_nudge = %d\n", y_nudge);
break; break;
} }
} }
j++;
env_language_lang = strtok(NULL, ":"); j++;
} env_language_lang = strtok(NULL, ":");
}
if (*env_language) if (*env_language)
free(env_language); free(env_language);
} }
// set_langint_from_locale_string(loc); // set_langint_from_locale_string(loc);
lang_prefix = lang_prefixes[wished_langs[0].langint]; lang_prefix = lang_prefixes[wished_langs[0].langint];
@ -1084,21 +1087,19 @@ printf ("Locale AFTER is: %s\n", setlocale(LC_ALL,NULL));//EP
#if 0 #if 0
for (i = 0; lang_y_nudge[i][0] != -1; i++) for (i = 0; lang_y_nudge[i][0] != -1; i++)
{
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
if (lang_y_nudge[i][0] == langint)
{ {
y_nudge = lang_y_nudge[i][1]; // printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
//printf("y_nudge = %d\n", y_nudge); if (lang_y_nudge[i][0] == langint)
break; {
y_nudge = lang_y_nudge[i][1];
//printf("y_nudge = %d\n", y_nudge);
break;
}
} }
}
#endif #endif
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: Language is %s (%d) %s/%s\n", fprintf(stderr, "DEBUG: Language is %s (%d) %s/%s\n",
lang_prefix, langint, lang_prefix, langint, need_right_to_left ? "(RTL)" : "", need_right_to_left_word ? "(RTL words)" : "");
need_right_to_left ? "(RTL)" : "",
need_right_to_left_word ? "(RTL words)" : "");
fflush(stderr); fflush(stderr);
#endif #endif
@ -1118,29 +1119,29 @@ int setup_i18n(const char *restrict lang, const char *restrict locale)
printf("lang \"%s\", locale \"%s\"\n", lang, locale); printf("lang \"%s\", locale \"%s\"\n", lang, locale);
#endif #endif
if(locale) if (locale)
{
if(!strcmp(locale,"help"))
{ {
show_locale_usage(stdout,"tuxpaint"); if (!strcmp(locale, "help"))
exit(0); {
show_locale_usage(stdout, "tuxpaint");
exit(0);
}
} }
}
if(lang) if (lang)
locale = language_to_locale(lang); locale = language_to_locale(lang);
#ifdef __APPLE__ #ifdef __APPLE__
patch_i18n(locale); //EP patch_i18n(locale); //EP
#endif #endif
#ifdef __ANDROID__ #ifdef __ANDROID__
if(locale == NULL) if (locale == NULL)
locale = android_locale(); locale = android_locale();
#endif #endif
if(locale == NULL) if (locale == NULL)
locale = ""; locale = "";
return set_current_language(locale); return set_current_language(locale);
} }

View file

@ -40,133 +40,133 @@
enum enum
{ {
LANG_ACH, /* Acholi */ LANG_ACH, /* Acholi */
LANG_AF, /* Afrikaans */ LANG_AF, /* Afrikaans */
LANG_AK, /* Akan */ LANG_AK, /* Akan */
LANG_AM, /* Amharic */ LANG_AM, /* Amharic */
LANG_AN, /* Aragones */ LANG_AN, /* Aragones */
LANG_AR, /* Arabic */ LANG_AR, /* Arabic */
LANG_AS, /* Assamese */ LANG_AS, /* Assamese */
LANG_AST, /* Asturian */ LANG_AST, /* Asturian */
LANG_AZ, /* Azerbaijani */ LANG_AZ, /* Azerbaijani */
LANG_BE, /* Belarusian */ LANG_BE, /* Belarusian */
LANG_BG, /* Bulgarian */ LANG_BG, /* Bulgarian */
LANG_BM, /* Bambara */ LANG_BM, /* Bambara */
LANG_BN, /* Bengali */ LANG_BN, /* Bengali */
LANG_BO, /* Tibetan */ LANG_BO, /* Tibetan */
LANG_BR, /* Breton */ LANG_BR, /* Breton */
LANG_BRX, /* Bodo */ LANG_BRX, /* Bodo */
LANG_BS, /* Bosnian */ LANG_BS, /* Bosnian */
LANG_CA_VALENCIA, /* Valencian */ LANG_CA_VALENCIA, /* Valencian */
LANG_CA, /* Catalan */ LANG_CA, /* Catalan */
LANG_CGG, /* Kiga */ LANG_CGG, /* Kiga */
LANG_CS, /* Czech */ LANG_CS, /* Czech */
LANG_CY, /* Welsh */ LANG_CY, /* Welsh */
LANG_DA, /* Danish */ LANG_DA, /* Danish */
LANG_DE, /* German */ LANG_DE, /* German */
LANG_DOI, /* Dogri */ LANG_DOI, /* Dogri */
LANG_EL, /* Greek */ LANG_EL, /* Greek */
LANG_EN, /* English (American) (DEFAULT) */ LANG_EN, /* English (American) (DEFAULT) */
LANG_EN_AU, /* English (Australian) */ LANG_EN_AU, /* English (Australian) */
LANG_EN_CA, /* English (Canadian) */ LANG_EN_CA, /* English (Canadian) */
LANG_EN_GB, /* English (British) */ LANG_EN_GB, /* English (British) */
LANG_EN_ZA, /* English (South African) */ LANG_EN_ZA, /* English (South African) */
LANG_EO, /* Esperanto */ LANG_EO, /* Esperanto */
LANG_ES_MX, /* Spanish (Mexican) */ LANG_ES_MX, /* Spanish (Mexican) */
LANG_ES, /* Spanish */ LANG_ES, /* Spanish */
LANG_ET, /* Estonian */ LANG_ET, /* Estonian */
LANG_EU, /* Basque */ LANG_EU, /* Basque */
LANG_FA, /* Persian */ LANG_FA, /* Persian */
LANG_FF, /* Fulah */ LANG_FF, /* Fulah */
LANG_FI, /* Finnish */ LANG_FI, /* Finnish */
LANG_FO, /* Faroese */ LANG_FO, /* Faroese */
LANG_FR, /* French */ LANG_FR, /* French */
LANG_GA, /* Irish Gaelic */ LANG_GA, /* Irish Gaelic */
LANG_GD, /* Scottish Gaelic */ LANG_GD, /* Scottish Gaelic */
LANG_GL, /* Galician */ LANG_GL, /* Galician */
LANG_GR, /* Gronings */ LANG_GR, /* Gronings */
LANG_GU, /* Gujarati */ LANG_GU, /* Gujarati */
LANG_HE, /* Hebrew */ LANG_HE, /* Hebrew */
LANG_HI, /* Hindi */ LANG_HI, /* Hindi */
LANG_HR, /* Croatian */ LANG_HR, /* Croatian */
LANG_HU, /* Hungarian */ LANG_HU, /* Hungarian */
LANG_HY, /* Armenian */ LANG_HY, /* Armenian */
LANG_I_KLINGON_ROMANIZED, /* Klingon (Romanized) */ LANG_I_KLINGON_ROMANIZED, /* Klingon (Romanized) */
LANG_ID, /* Indonesian */ LANG_ID, /* Indonesian */
LANG_IS, /* Icelandic */ LANG_IS, /* Icelandic */
LANG_IT, /* Italian */ LANG_IT, /* Italian */
LANG_IU, /* Inuktitut */ LANG_IU, /* Inuktitut */
LANG_JA, /* Japanese */ LANG_JA, /* Japanese */
LANG_KA, /* Georgian */ LANG_KA, /* Georgian */
LANG_KAB, /* Kabyle */ LANG_KAB, /* Kabyle */
LANG_KN, /* Kannada */ LANG_KN, /* Kannada */
LANG_KM, /* Khmer */ LANG_KM, /* Khmer */
LANG_KOK_ROMAN, /* Konkani (Roman) */ LANG_KOK_ROMAN, /* Konkani (Roman) */
LANG_KOK, /* Konkani (Devaganari) */ LANG_KOK, /* Konkani (Devaganari) */
LANG_KO, /* Korean */ LANG_KO, /* Korean */
LANG_KS_DEVANAGARI, /* Kashmiri (Devanagari script) */ LANG_KS_DEVANAGARI, /* Kashmiri (Devanagari script) */
LANG_KS, /* Kashmiri (Perso-Arabic script) */ LANG_KS, /* Kashmiri (Perso-Arabic script) */
LANG_KU, /* Kurdish */ LANG_KU, /* Kurdish */
LANG_LB, /* Luxembourgish */ LANG_LB, /* Luxembourgish */
LANG_LG, /* Luganda */ LANG_LG, /* Luganda */
LANG_LT, /* Lithuanian */ LANG_LT, /* Lithuanian */
LANG_LV, /* Latvian */ LANG_LV, /* Latvian */
LANG_MAI, /* Maithili */ LANG_MAI, /* Maithili */
LANG_ML, /* Malayalam */ LANG_ML, /* Malayalam */
LANG_MK, /* Macedonian */ LANG_MK, /* Macedonian */
LANG_MN, /* Mongolian */ LANG_MN, /* Mongolian */
LANG_MNI_BENGALI, /* Manipuri (Bengali script)*/ LANG_MNI_BENGALI, /* Manipuri (Bengali script) */
LANG_MNI_METEI_MAYEK, /* Manipuri (Metei Mayek script) */ LANG_MNI_METEI_MAYEK, /* Manipuri (Metei Mayek script) */
LANG_MR, /* Marath */ LANG_MR, /* Marath */
LANG_MS, /* Malay */ LANG_MS, /* Malay */
LANG_NB, /* Norwegian Bokmal */ LANG_NB, /* Norwegian Bokmal */
LANG_NE, /* Nepali */ LANG_NE, /* Nepali */
LANG_NL, /* Dutch */ LANG_NL, /* Dutch */
LANG_NN, /* Norwegian Nynorsk */ LANG_NN, /* Norwegian Nynorsk */
LANG_NR, /* Ndebele */ LANG_NR, /* Ndebele */
LANG_NSO, /* Northern Sotho */ LANG_NSO, /* Northern Sotho */
LANG_OC, /* Occitan */ LANG_OC, /* Occitan */
LANG_OJ, /* Ojibway */ LANG_OJ, /* Ojibway */
LANG_OR, /* Odia */ LANG_OR, /* Odia */
LANG_PA, /* Punjabi */ LANG_PA, /* Punjabi */
LANG_PL, /* Polish */ LANG_PL, /* Polish */
LANG_PT_BR, /* Portuguese (Brazilian) */ LANG_PT_BR, /* Portuguese (Brazilian) */
LANG_PT, /* Portuguese */ LANG_PT, /* Portuguese */
LANG_RO, /* Romanian */ LANG_RO, /* Romanian */
LANG_RU, /* Russian */ LANG_RU, /* Russian */
LANG_RW, /* Kinyarwanda */ LANG_RW, /* Kinyarwanda */
LANG_SAT_OL_CHIKI, LANG_SAT_OL_CHIKI,
LANG_SAT, /* Santali */ LANG_SAT, /* Santali */
LANG_SA, /* Sanskrit */ LANG_SA, /* Sanskrit */
LANG_SD, /* Sindhi (Perso-Arabic) */ LANG_SD, /* Sindhi (Perso-Arabic) */
LANG_SD_DEVANAGARI, /* Sindhi (Devanagari) */ LANG_SD_DEVANAGARI, /* Sindhi (Devanagari) */
LANG_SHS, /* Shuswap */ LANG_SHS, /* Shuswap */
LANG_SI, /* Sinhala */ LANG_SI, /* Sinhala */
LANG_SK, /* Slovak */ LANG_SK, /* Slovak */
LANG_SL, /* Slovenian */ LANG_SL, /* Slovenian */
LANG_SON, /* Songhay */ LANG_SON, /* Songhay */
LANG_SQ, /* Albanian */ LANG_SQ, /* Albanian */
LANG_SR_LATIN, /* Serbian (latin) */ LANG_SR_LATIN, /* Serbian (latin) */
LANG_SR, /* Serbian (cyrillic) */ LANG_SR, /* Serbian (cyrillic) */
LANG_SU, /* Sundanese */ LANG_SU, /* Sundanese */
LANG_SV, /* Swedish */ LANG_SV, /* Swedish */
LANG_SW, /* Swahili */ LANG_SW, /* Swahili */
LANG_TA, /* Tamil */ LANG_TA, /* Tamil */
LANG_TE, /* Telugu */ LANG_TE, /* Telugu */
LANG_TH, /* Thai */ LANG_TH, /* Thai */
LANG_TL, /* Tagalog */ LANG_TL, /* Tagalog */
LANG_TR, /* Turkish */ LANG_TR, /* Turkish */
LANG_TW, /* Twi */ LANG_TW, /* Twi */
LANG_UK, /* Ukrainian */ LANG_UK, /* Ukrainian */
LANG_UR, /* Urdu */ LANG_UR, /* Urdu */
LANG_VEC, /* Venetian */ LANG_VEC, /* Venetian */
LANG_VE, /* Venda */ LANG_VE, /* Venda */
LANG_VI, /* Vietnamese */ LANG_VI, /* Vietnamese */
LANG_WA, /* Walloon */ LANG_WA, /* Walloon */
LANG_WO, /* Wolof */ LANG_WO, /* Wolof */
LANG_XH, /* Xhosa */ LANG_XH, /* Xhosa */
LANG_ZAM, /* Zapotec (Miahuatlan) */ LANG_ZAM, /* Zapotec (Miahuatlan) */
LANG_ZH_CN, /* Chinese (Simplified) */ LANG_ZH_CN, /* Chinese (Simplified) */
LANG_ZH_TW, /* Chinese (Traditional) */ LANG_ZH_TW, /* Chinese (Traditional) */
LANG_ZU, /* Zulu */ LANG_ZU, /* Zulu */
NUM_LANGS NUM_LANGS
}; };
@ -185,8 +185,8 @@ typedef struct language_to_locale_struct
extern const char *lang_prefixes[NUM_LANGS]; extern const char *lang_prefixes[NUM_LANGS];
extern int need_own_font; extern int need_own_font;
extern int need_right_to_left; // Right-justify extern int need_right_to_left; // Right-justify
extern int need_right_to_left_word; // Words need to be reversed, too! (e.g., Hebrew, but not Arabic) extern int need_right_to_left_word; // Words need to be reversed, too! (e.g., Hebrew, but not Arabic)
extern const char *lang_prefix, *short_lang_prefix; extern const char *lang_prefix, *short_lang_prefix;
extern int num_wished_langs; extern int num_wished_langs;
@ -207,8 +207,9 @@ extern w_langs wished_langs[255];
int get_current_language(void); int get_current_language(void);
int setup_i18n(const char *restrict lang, const char *restrict locale) MUST_CHECK; int setup_i18n(const char *restrict lang, const char *restrict locale) MUST_CHECK;
#ifdef NO_SDLPANGO #ifdef NO_SDLPANGO
int smash_i18n(void) MUST_CHECK; int smash_i18n(void) MUST_CHECK;
#endif #endif
#endif #endif

1766
src/im.c

File diff suppressed because it is too large Load diff

View file

@ -33,15 +33,16 @@
* TYPES * TYPES
*/ */
typedef struct IM_DATA { typedef struct IM_DATA
int lang; /* Language used in sequence translation */ {
wchar_t s[16]; /* Characters that should be displayed */ int lang; /* Language used in sequence translation */
const char* tip_text; /* Tip text, read-only please */ wchar_t s[16]; /* Characters that should be displayed */
const char *tip_text; /* Tip text, read-only please */
/* For use by language-specific im_event_<lang> calls. PRIVATE! */ /* For use by language-specific im_event_<lang> calls. PRIVATE! */
wchar_t buf[8]; /* Buffered characters */ wchar_t buf[8]; /* Buffered characters */
int redraw; /* Redraw this many characters next time */ int redraw; /* Redraw this many characters next time */
int request; /* Event request */ int request; /* Event request */
} IM_DATA; } IM_DATA;
@ -49,9 +50,9 @@ typedef struct IM_DATA {
* FUNCTIONS * FUNCTIONS
*/ */
void im_init(IM_DATA* im, int lang); /* Initialize IM */ void im_init(IM_DATA * im, int lang); /* Initialize IM */
void im_softreset(IM_DATA* im); /* Soft Reset IM */ void im_softreset(IM_DATA * im); /* Soft Reset IM */
int im_read(IM_DATA* im, SDL_Event event); int im_read(IM_DATA * im, SDL_Event event);
#endif /* TUXPAINT_IM_H */ #endif /* TUXPAINT_IM_H */

View file

@ -25,17 +25,16 @@
#include "SDL.h" #include "SDL.h"
const char *SurfacePrint(SDL_Surface *surface, int showDialog); const char *SurfacePrint(SDL_Surface * surface, int showDialog);
int DisplayPageSetup(const SDL_Surface *surface); int DisplayPageSetup(const SDL_Surface * surface);
#ifdef OBJECTIVEC #ifdef OBJECTIVEC
@interface PrintSheetController : NSObject @interface PrintSheetController:NSObject
{ {
bool displayPrintSetupSheet; bool displayPrintSetupSheet;
bool displayPrintSheet; bool displayPrintSheet;
} }
-
@end
#endif OBJECTIVEC -@end
#endif /* OBJECTIVEC */

File diff suppressed because it is too large Load diff

View file

@ -26,41 +26,41 @@ KMOD_ALT An Alt key is down
typedef struct osk_keymap typedef struct osk_keymap
{ {
int keycode; int keycode;
int disable_caps; /* If caps lock should affect this key */ int disable_caps; /* If caps lock should affect this key */
char * plain; /* The default Xkeysym for the keycode */ char *plain; /* The default Xkeysym for the keycode */
char * caps; /* If CapsLock or Shift + key */ char *caps; /* If CapsLock or Shift + key */
char * altgr; /* If AltGr + key */ char *altgr; /* If AltGr + key */
char * shiftaltgr; /* If AltGr + Shift + key */ char *shiftaltgr; /* If AltGr + Shift + key */
} osk_keymap; } osk_keymap;
typedef struct osk_key typedef struct osk_key
{ {
int keycode; /* The code associated to this key. If 0, then it is an empty key. */ int keycode; /* The code associated to this key. If 0, then it is an empty key. */
int row; int row;
int x; int x;
int y; int y;
float width; /* The width in buttons */ float width; /* The width in buttons */
char *plain_label; /* The text that will show the key */ char *plain_label; /* The text that will show the key */
char *top_label; /* The text that will show the key above the plain label. */ char *top_label; /* The text that will show the key above the plain label. */
char *altgr_label; /* The text that will show the key at the right of the plain label */ char *altgr_label; /* The text that will show the key at the right of the plain label */
char *shift_altgr_label; /* The text that will show the key when shift and altgr are activated */ char *shift_altgr_label; /* The text that will show the key when shift and altgr are activated */
int shiftcaps; /* If the value of the key should be shifted when capslock is active */ int shiftcaps; /* If the value of the key should be shifted when capslock is active */
int stick; /* If the key currently affects the others */ int stick; /* If the key currently affects the others */
} osk_key; } osk_key;
typedef struct osk_composenode typedef struct osk_composenode
{ {
wchar_t * keysym; wchar_t *keysym;
wchar_t * result; wchar_t *result;
int size; /* How many childs are there. */ int size; /* How many childs are there. */
struct osk_composenode ** childs; struct osk_composenode **childs;
// struct osk_composenode **parent; // struct osk_composenode **parent;
} osk_composenode; } osk_composenode;
typedef struct keysymdefs typedef struct keysymdefs
{ {
char * mnemo; char *mnemo;
int keysym; int keysym;
int unicode; int unicode;
} keysymdefs; } keysymdefs;
@ -71,11 +71,11 @@ typedef struct osk_layout
int *rows; int *rows;
int width; int width;
int height; int height;
char * fontpath; char *fontpath;
osk_key **keys; osk_key **keys;
osk_keymap *keymap; osk_keymap *keymap;
osk_composenode * composemap; osk_composenode *composemap;
keysymdefs * keysymdefs; keysymdefs *keysymdefs;
unsigned int sizeofkeysymdefs; unsigned int sizeofkeysymdefs;
SDL_Color bgcolor; SDL_Color bgcolor;
SDL_Color fgcolor; SDL_Color fgcolor;
@ -91,56 +91,61 @@ typedef struct osk_keymodifiers
typedef struct osk_kmdf typedef struct osk_kmdf
{ {
osk_key * shift; osk_key *shift;
osk_key * altgr; osk_key *altgr;
osk_key * compose; osk_key *compose;
osk_key * dead; osk_key *dead;
osk_key * dead2; osk_key *dead2;
osk_key * dead3; osk_key *dead3;
osk_key * dead4; osk_key *dead4;
} osk_kmdf; } osk_kmdf;
typedef struct osk_keyboard typedef struct osk_keyboard
{ {
char * name; /* The name of the keyboard */ char *name; /* The name of the keyboard */
char * keyboard_list; /* The names of the keyboards allowed from this one */ char *keyboard_list; /* The names of the keyboards allowed from this one */
SDL_Surface *surface; /* The surface containing the keyboard */ SDL_Surface *surface; /* The surface containing the keyboard */
SDL_Surface *button_up; /* The surfaces containing the buttons */ SDL_Surface *button_up; /* The surfaces containing the buttons */
SDL_Surface *button_down; SDL_Surface *button_down;
SDL_Surface *button_off; SDL_Surface *button_off;
SDL_Surface *button_nav; SDL_Surface *button_nav;
SDL_Surface *button_hold; SDL_Surface *button_hold;
SDL_Surface *oskdel; /* The surfaces containing some symbols for the buttons, delete arrow */ SDL_Surface *oskdel; /* The surfaces containing some symbols for the buttons, delete arrow */
SDL_Surface *osktab; /* Tab arrows */ SDL_Surface *osktab; /* Tab arrows */
SDL_Surface *oskenter; /* Return hook/arrow */ SDL_Surface *oskenter; /* Return hook/arrow */
SDL_Surface *oskcapslock; /* CapsLock */ SDL_Surface *oskcapslock; /* CapsLock */
SDL_Surface *oskshift; /* Shift */ SDL_Surface *oskshift; /* Shift */
int changed; /* If the surface has been modified (painted) */ int changed; /* If the surface has been modified (painted) */
SDL_Rect rect; /* The rectangle that has changed */ SDL_Rect rect; /* The rectangle that has changed */
int recreated; /* If the surface has been deleted and newly created */ int recreated; /* If the surface has been deleted and newly created */
int modifiers; /* The state of Alt, CTRL, Shift, CapsLock, AltGr keys */ int modifiers; /* The state of Alt, CTRL, Shift, CapsLock, AltGr keys */
osk_keymodifiers keymodifiers; /* A shortcurt to find the place of the pressed modifiers */ osk_keymodifiers keymodifiers; /* A shortcurt to find the place of the pressed modifiers */
osk_kmdf kmdf; osk_kmdf kmdf;
osk_layout *layout; /* The layout struct */ osk_layout *layout; /* The layout struct */
char *layout_name[256]; /* The layout name */ char *layout_name[256]; /* The layout name */
TTF_Font * osk_fonty; /* Font */ TTF_Font *osk_fonty; /* Font */
int disable_change; /* If true, stay with the first layout found */ int disable_change; /* If true, stay with the first layout found */
wchar_t * key[256]; /* The text of the key */ wchar_t *key[256]; /* The text of the key */
int keycode; /* The unicode code corresponding to the key */ int keycode; /* The unicode code corresponding to the key */
wchar_t * composed; /* The unicode char found after a sequence of key presses */ wchar_t *composed; /* The unicode char found after a sequence of key presses */
int composed_type; /* 1 if the value stored in composed is yet the unicode value */ int composed_type; /* 1 if the value stored in composed is yet the unicode value */
osk_composenode * composing; /* The node in the middle of a compose sequence */ osk_composenode *composing; /* The node in the middle of a compose sequence */
osk_key * last_key_pressed; /* The last key pressed */ osk_key *last_key_pressed; /* The last key pressed */
} on_screen_keyboard; } on_screen_keyboard;
struct osk_keyboard *osk_create(char *layout_name, SDL_Surface *canvas, SDL_Surface *button_up, SDL_Surface *button_down, SDL_Surface *button_off, SDL_Surface *button_nav, SDL_Surface *button_hold, SDL_Surface *oskdel, SDL_Surface *osktab, SDL_Surface *oskenter, SDL_Surface *oskcapslock, SDL_Surface *oskshift, int disable_change); struct osk_keyboard *osk_create(char *layout_name, SDL_Surface * canvas, SDL_Surface * button_up,
SDL_Surface * button_down, SDL_Surface * button_off, SDL_Surface * button_nav,
SDL_Surface * button_hold, SDL_Surface * oskdel, SDL_Surface * osktab,
SDL_Surface * oskenter, SDL_Surface * oskcapslock, SDL_Surface * oskshift,
int disable_change);
struct osk_layout *osk_load_layout(char *layout_name); struct osk_layout *osk_load_layout(char *layout_name);
void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h, char * layout_buttons, char *layout_labels, char *layout_keycodes); void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h, char *layout_buttons, char *layout_labels,
void osk_reset(on_screen_keyboard *osk); char *layout_keycodes);
struct osk_keyboard * osk_clicked(on_screen_keyboard *keyboard, int x, int y); void osk_reset(on_screen_keyboard * osk);
void osk_released(on_screen_keyboard *osk); struct osk_keyboard *osk_clicked(on_screen_keyboard * keyboard, int x, int y);
void osk_hover(on_screen_keyboard *keyboard, int x, int y); void osk_released(on_screen_keyboard * osk);
void osk_free(on_screen_keyboard *osk); void osk_hover(on_screen_keyboard * keyboard, int x, int y);
void osk_change_layout(on_screen_keyboard *osk); void osk_free(on_screen_keyboard * osk);
void osk_change_layout(on_screen_keyboard * osk);

View file

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

View file

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

View file

@ -33,55 +33,54 @@ int mute;
int use_sound = 1; int use_sound = 1;
static int old_sound[4] = { -1, -1, -1, -1 }; static int old_sound[4] = { -1, -1, -1, -1 };
void playsound(SDL_Surface * screen, int chan, int s, int override, int x, void playsound(SDL_Surface * screen, int chan, int s, int override, int x, int y)
int y)
{ {
#ifndef NOSOUND #ifndef NOSOUND
int left, dist; int left, dist;
if (!mute && use_sound && s != SND_NONE) if (!mute && use_sound && s != SND_NONE)
{
if (override || !Mix_Playing(chan))
{ {
Mix_PlayChannel(chan, sounds[s], 0); if (override || !Mix_Playing(chan))
{
Mix_PlayChannel(chan, sounds[s], 0);
old_sound[chan] = s; old_sound[chan] = s;
}
if (old_sound[chan] == s)
{
if (y == SNDDIST_NEAR)
dist = 0;
else
{
if (y < 0)
y = 0;
else if (y >= screen->h - 1)
y = screen->h - 1;
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
}
if (x == SNDPOS_LEFT)
left = 255 - dist;
else if (x == SNDPOS_CENTER)
left = (255 - dist) / 2;
else if (x == SNDPOS_RIGHT)
left = 0;
else
{
if (x < 0)
x = 0;
else if (x >= screen->w)
x = screen->w - 1;
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
}
Mix_SetPanning(chan, left, (255 - dist) - left);
}
} }
if (old_sound[chan] == s)
{
if (y == SNDDIST_NEAR)
dist = 0;
else
{
if (y < 0)
y = 0;
else if (y >= screen->h - 1)
y = screen->h - 1;
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
}
if (x == SNDPOS_LEFT)
left = 255 - dist;
else if (x == SNDPOS_CENTER)
left = (255 - dist) / 2;
else if (x == SNDPOS_RIGHT)
left = 0;
else
{
if (x < 0)
x = 0;
else if (x >= screen->w)
x = screen->w - 1;
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
}
Mix_SetPanning(chan, left, (255 - dist) - left);
}
}
#endif #endif
} }

View file

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

View file

@ -62,7 +62,7 @@
#include "pixels.h" #include "pixels.h"
#define MARGIN 36 /* Margin to put around image, in points (inch/72) (36pt = 0.5") */ #define MARGIN 36 /* Margin to put around image, in points (inch/72) (36pt = 0.5") */
#define my_min(x,y) ((x < y) ? (x) : (y)) #define my_min(x,y) ((x < y) ? (x) : (y))
@ -78,12 +78,9 @@ static int f2dec(float f)
/* Actually save the PostScript data to the file stream: */ /* Actually save the PostScript data to the file stream: */
int do_ps_save(FILE * fi, int do_ps_save(FILE * fi,
const char *restrict const fname, const char *restrict const fname, SDL_Surface * surf, const char *restrict pprsize, int is_pipe)
SDL_Surface * surf,
const char *restrict pprsize,
int is_pipe)
{ {
const struct paper * ppr; const struct paper *ppr;
int img_w = surf->w; int img_w = surf->w;
int img_h = surf->h; int img_h = surf->h;
int r_img_w, r_img_h; int r_img_w, r_img_h;
@ -94,8 +91,8 @@ int do_ps_save(FILE * fi,
int plane; int plane;
Uint8 r, g, b; Uint8 r, g, b;
char buf[256]; char buf[256];
Uint32(*getpixel) (SDL_Surface *, int, int) =
getpixels[surf->format->BytesPerPixel]; Uint32(*getpixel) (SDL_Surface *, int, int) = getpixels[surf->format->BytesPerPixel];
int printed_img_w, printed_img_h; int printed_img_w, printed_img_h;
time_t t = time(NULL); time_t t = time(NULL);
int rotate; int rotate;
@ -104,40 +101,40 @@ int do_ps_save(FILE * fi,
/* Determine paper size: */ /* Determine paper size: */
paperinit(); // FIXME: Should we do this at startup? -bjk 2007.06.25 paperinit(); // FIXME: Should we do this at startup? -bjk 2007.06.25
if (pprsize == NULL) if (pprsize == NULL)
{
/* User did not request a specific paper size (on command-line or
in config file), ask the system. It will return either their
$PAPER env. var., the value from /etc/papersize, or NULL: */
pprsize = systempapername();
if (pprsize == NULL)
{ {
/* No setting, env. var. or /etc/ file; use the default! */ /* User did not request a specific paper size (on command-line or
in config file), ask the system. It will return either their
$PAPER env. var., the value from /etc/papersize, or NULL: */
pprsize = defaultpapername(); pprsize = systempapername();
if (pprsize == NULL)
{
/* No setting, env. var. or /etc/ file; use the default! */
pprsize = defaultpapername();
#ifdef DEBUG #ifdef DEBUG
printf("Using default paper\n"); printf("Using default paper\n");
#endif #endif
} }
#ifdef DEBUG #ifdef DEBUG
else else
{ {
printf("Using system paper\n"); printf("Using system paper\n");
} }
#endif #endif
} }
#ifdef DEBUG #ifdef DEBUG
else else
{ {
printf("Using user paper\n"); printf("Using user paper\n");
} }
#endif #endif
#ifdef DEBUG #ifdef DEBUG
printf("Using paper size: %s\n", pprsize); printf("Using paper size: %s\n", pprsize);
#endif #endif
@ -151,28 +148,26 @@ int do_ps_save(FILE * fi,
ppr_h = paperpsheight(ppr); ppr_h = paperpsheight(ppr);
#ifdef DEBUG #ifdef DEBUG
printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, (float)ppr_w / 72.0, (float)ppr_h / 72.0);
(float) ppr_w / 72.0, (float) ppr_h / 72.0);
#endif #endif
paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25 paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25
/* Determine whether it's best to rotate the image: */ /* Determine whether it's best to rotate the image: */
if ((ppr_w >= ppr_h && img_w >= img_h) || if ((ppr_w >= ppr_h && img_w >= img_h) || (ppr_w <= ppr_h && img_w <= img_h))
(ppr_w <= ppr_h && img_w <= img_h)) {
{ rotate = 0;
rotate = 0; r_img_w = img_w;
r_img_w = img_w; r_img_h = img_h;
r_img_h = img_h; }
}
else else
{ {
rotate = 1; rotate = 1;
r_img_w = img_h; r_img_w = img_h;
r_img_h = img_w; r_img_h = img_w;
} }
#ifdef DEBUG #ifdef DEBUG
printf("Image is %d x %d\n", img_w, img_h); printf("Image is %d x %d\n", img_w, img_h);
@ -183,15 +178,13 @@ int do_ps_save(FILE * fi,
/* Determine scale: */ /* Determine scale: */
scale = my_min(((float) (ppr_w - (MARGIN * 2)) / (float) r_img_w), scale = my_min(((float)(ppr_w - (MARGIN * 2)) / (float)r_img_w), ((float)(ppr_h - (MARGIN * 2)) / (float)r_img_h));
((float) (ppr_h - (MARGIN * 2)) / (float) r_img_h));
printed_img_w = r_img_w * scale; printed_img_w = r_img_w * scale;
printed_img_h = r_img_h * scale; printed_img_h = r_img_h * scale;
#ifdef DEBUG #ifdef DEBUG
printf("Scaling image by %.2f (to %d x %d)\n", scale, printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w, printed_img_h);
printed_img_w, printed_img_h);
#endif #endif
@ -206,7 +199,7 @@ int do_ps_save(FILE * fi,
/* Begin PostScript output with some useful meta info in comments: */ /* Begin PostScript output with some useful meta info in comments: */
fprintf(fi, "%%!PS-Adobe-2.0 EPSF-2.0\n"); // we need LanguageLevel2 for color fprintf(fi, "%%!PS-Adobe-2.0 EPSF-2.0\n"); // we need LanguageLevel2 for color
fprintf(fi, "%%%%Title: (%s)\n", fname); fprintf(fi, "%%%%Title: (%s)\n", fname);
@ -217,8 +210,7 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%Pages: 1\n"); fprintf(fi, "%%%%Pages: 1\n");
fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int) (ppr_w + 0.5), (int) fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int)(ppr_w + 0.5), (int)(ppr_h + 0.5));
(ppr_h + 0.5));
fprintf(fi, "%%%%EndComments\n"); fprintf(fi, "%%%%EndComments\n");
@ -237,24 +229,20 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%Page: 1 1\n"); fprintf(fi, "%%%%Page: 1 1\n");
fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", ppr_w, ppr_h);
ppr_w, ppr_h);
fprintf(fi, "gsave\n"); fprintf(fi, "gsave\n");
/* 'translate' moves the user space origin to a new position with /* 'translate' moves the user space origin to a new position with
respect to the current page, leaving the orientation of the axes and respect to the current page, leaving the orientation of the axes and
the unit lengths unchanged. */ the unit lengths unchanged. */
fprintf(fi, "%d.%02d %d.%02d translate\n", fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x), f2int(tlate_y), f2dec(tlate_y));
f2int(tlate_x), f2dec(tlate_x),
f2int(tlate_y), f2dec(tlate_y));
/* 'scale' modifies the unit lengths independently along the current /* 'scale' modifies the unit lengths independently along the current
x and y axes, leaving the origin location and the orientation of the x and y axes, leaving the origin location and the orientation of the
axes unchanged. */ axes unchanged. */
fprintf(fi, "%d.%02d %d.%02d scale\n", fprintf(fi, "%d.%02d %d.%02d scale\n",
f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h), f2dec(printed_img_h));
f2int(printed_img_h), f2dec(printed_img_h));
/* Rotate the image */ /* Rotate the image */
if (rotate) if (rotate)
@ -274,23 +262,23 @@ int do_ps_save(FILE * fi,
cur_line_len = 0; cur_line_len = 0;
for (y = 0; y < img_h; y++) for (y = 0; y < img_h; y++)
{
for (plane = 0; plane < 3; plane++)
{ {
for (x = 0; x < img_w; x++) for (plane = 0; plane < 3; plane++)
{
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
cur_line_len++;
if (cur_line_len >= 30)
{ {
fprintf(fi, "\n"); for (x = 0; x < img_w; x++)
cur_line_len = 0; {
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
cur_line_len++;
if (cur_line_len >= 30)
{
fprintf(fi, "\n");
cur_line_len = 0;
}
}
} }
}
} }
}
fprintf(fi, "\n"); fprintf(fi, "\n");
fprintf(fi, "grestore\n"); fprintf(fi, "grestore\n");
@ -299,16 +287,16 @@ int do_ps_save(FILE * fi,
fprintf(fi, "%%%%EOF\n"); fprintf(fi, "%%%%EOF\n");
if (!is_pipe) if (!is_pipe)
{ {
fclose(fi); fclose(fi);
return 1; return 1;
} }
else else
{ {
pid_t child_pid, w; pid_t child_pid, w;
int status; int status;
child_pid = pclose(fi); child_pid = pclose(fi);
/* debug */ /* debug */
/* /*
@ -316,15 +304,18 @@ int do_ps_save(FILE * fi,
printf("errno = %d\n", errno); fflush(stdout); printf("errno = %d\n", errno); fflush(stdout);
*/ */
if (child_pid < 0 || (errno != 0 && errno != EAGAIN)) { /* FIXME: This right? */ if (child_pid < 0 || (errno != 0 && errno != EAGAIN))
return 0; { /* FIXME: This right? */
} else if (child_pid == 0) { return 0;
return 1; }
} else if (child_pid == 0)
{
return 1;
}
do do
{ {
w = waitpid(child_pid, &status, 0); w = waitpid(child_pid, &status, 0);
/* debug */ /* debug */
/* /*
@ -339,15 +330,14 @@ int do_ps_save(FILE * fi,
printf("continued\n"); printf("continued\n");
} }
*/ */
}
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
return 0;
return 1;
} }
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
return 0;
return 1;
}
} }
#endif #endif

View file

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

View file

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

View file

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

View file

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

View file

@ -62,84 +62,84 @@ enum
/* How many sides do they have? */ /* How many sides do they have? */
const int shape_sides[NUM_SHAPES] = { const int shape_sides[NUM_SHAPES] = {
4, /* Square */ 4, /* Square */
4, /* Square */ 4, /* Square */
4, /* Rectangle */ 4, /* Rectangle */
4, /* Rectangle */ 4, /* Rectangle */
72, /* Circle */ 72, /* Circle */
72, /* Circle */ 72, /* Circle */
72, /* Ellipse */ 72, /* Ellipse */
72, /* Ellipse */ 72, /* Ellipse */
3, /* Triangle */ 3, /* Triangle */
3, /* Triangle */ 3, /* Triangle */
5, /* Pentagon */ 5, /* Pentagon */
5, /* Pentagon */ 5, /* Pentagon */
4, /* Rhombus */ 4, /* Rhombus */
4, /* Rhombus */ 4, /* Rhombus */
8, /* Octagon */ 8, /* Octagon */
8, /* Octagon */ 8, /* Octagon */
3, /* 3 points star*/ 3, /* 3 points star */
3, /* 3 points star*/ 3, /* 3 points star */
4, /* 4 points star*/ 4, /* 4 points star */
4, /* 4 points star*/ 4, /* 4 points star */
5, /* 5 points star*/ 5, /* 5 points star */
5 /* 5 points star*/ 5 /* 5 points star */
}; };
/* Which shapes are 1:1 aspect? */ /* Which shapes are 1:1 aspect? */
const int shape_locked[NUM_SHAPES] = { const int shape_locked[NUM_SHAPES] = {
1, /* Square */ 1, /* Square */
1, /* Square */ 1, /* Square */
0, /* Rectangle */ 0, /* Rectangle */
0, /* Rectangle */ 0, /* Rectangle */
1, /* Circle */ 1, /* Circle */
1, /* Circle */ 1, /* Circle */
0, /* Ellipse */ 0, /* Ellipse */
0, /* Ellipse */ 0, /* Ellipse */
0, /* Triangle */ 0, /* Triangle */
0, /* Triangle */ 0, /* Triangle */
0, /* Pentagon */ 0, /* Pentagon */
0, /* Pentagon */ 0, /* Pentagon */
0, /* Rhombus */ 0, /* Rhombus */
0, /* Rhombus */ 0, /* Rhombus */
1, /* Octagon */ 1, /* Octagon */
1, /* Octagon */ 1, /* Octagon */
0, /* 3 points star*/ 0, /* 3 points star */
0, /* 3 points star*/ 0, /* 3 points star */
0, /* 4 points star*/ 0, /* 4 points star */
0, /* 4 points star*/ 0, /* 4 points star */
0, /* 5 points star*/ 0, /* 5 points star */
0 /* 5 points star*/ 0 /* 5 points star */
}; };
/* Which shapes are filled? */ /* Which shapes are filled? */
const int shape_filled[NUM_SHAPES] = { const int shape_filled[NUM_SHAPES] = {
0, /* Square */ 0, /* Square */
1, /* Square */ 1, /* Square */
0, /* Rectangle */ 0, /* Rectangle */
1, /* Rectangle */ 1, /* Rectangle */
0, /* Circle */ 0, /* Circle */
1, /* Circle */ 1, /* Circle */
0, /* Ellipse */ 0, /* Ellipse */
1, /* Ellipse */ 1, /* Ellipse */
0, /* Triangle */ 0, /* Triangle */
1, /* Triangle */ 1, /* Triangle */
0, /* Pentagon */ 0, /* Pentagon */
1, /* Pentagon */ 1, /* Pentagon */
0, /* Rhombus */ 0, /* Rhombus */
1, /* Rhombus */ 1, /* Rhombus */
0, /* Octagon */ 0, /* Octagon */
1, /* Octagon */ 1, /* Octagon */
0, /* 3 points star*/ 0, /* 3 points star */
1, /* 3 points star*/ 1, /* 3 points star */
0, /* 4 points star*/ 0, /* 4 points star */
1, /* 4 points star*/ 1, /* 4 points star */
0, /* 5 points star*/ 0, /* 5 points star */
1 /* 5 points star*/ 1 /* 5 points star */
}; };
@ -147,83 +147,83 @@ const int shape_filled[NUM_SHAPES] = {
/* Initial angles for shapes: */ /* Initial angles for shapes: */
const int shape_init_ang[NUM_SHAPES] = { const int shape_init_ang[NUM_SHAPES] = {
45, /* Square */ 45, /* Square */
45, /* Square */ 45, /* Square */
45, /* Rectangle */ 45, /* Rectangle */
45, /* Rectangle */ 45, /* Rectangle */
0, /* Circle */ 0, /* Circle */
0, /* Circle */ 0, /* Circle */
0, /* Ellipse */ 0, /* Ellipse */
0, /* Ellipse */ 0, /* Ellipse */
210, /* Triangle */ 210, /* Triangle */
210, /* Triangle */ 210, /* Triangle */
162, /* Pentagon */ 162, /* Pentagon */
162, /* Pentagon */ 162, /* Pentagon */
0, /* Rhombus */ 0, /* Rhombus */
0, /* Rhombus */ 0, /* Rhombus */
22, /* Octagon */ 22, /* Octagon */
22, /* Octagon */ 22, /* Octagon */
210, /* 3 points star*/ 210, /* 3 points star */
210, /* 3 points star*/ 210, /* 3 points star */
0, /* 4 points star*/ 0, /* 4 points star */
0, /* 4 points star*/ 0, /* 4 points star */
162, /* 5 points star */ 162, /* 5 points star */
162 /* 5 points star */ 162 /* 5 points star */
}; };
/* Shapes that don't make sense rotating (e.g., circles): */ /* Shapes that don't make sense rotating (e.g., circles): */
const int shape_no_rotate[NUM_SHAPES] = { const int shape_no_rotate[NUM_SHAPES] = {
0, /* Square */ 0, /* Square */
0, /* Square */ 0, /* Square */
0, /* Rectangle */ 0, /* Rectangle */
0, /* Rectangle */ 0, /* Rectangle */
1, /* Circle */ 1, /* Circle */
1, /* Circle */ 1, /* Circle */
0, /* Ellipse */ 0, /* Ellipse */
0, /* Ellipse */ 0, /* Ellipse */
0, /* Triangle */ 0, /* Triangle */
0, /* Triangle */ 0, /* Triangle */
0, /* Pentagon */ 0, /* Pentagon */
0, /* Pentagon */ 0, /* Pentagon */
0, /* Rhombus */ 0, /* Rhombus */
0, /* Rhombus */ 0, /* Rhombus */
0, /* Octagon */ 0, /* Octagon */
0, /* Octagon */ 0, /* Octagon */
0, /* 3 points star */ 0, /* 3 points star */
0, /* 3 points star */ 0, /* 3 points star */
0, /* 4 points star */ 0, /* 4 points star */
0, /* 4 points star */ 0, /* 4 points star */
0, /* 5 points star */ 0, /* 5 points star */
0 /* 5 points star */ 0 /* 5 points star */
}; };
/* Valley of stars in percent of size */ /* Valley of stars in percent of size */
const int shape_valley[NUM_SHAPES] = { const int shape_valley[NUM_SHAPES] = {
100, /* Square */ 100, /* Square */
100, /* Square */ 100, /* Square */
100, /* Rectangle */ 100, /* Rectangle */
100, /* Rectangle */ 100, /* Rectangle */
100, /* Circle */ 100, /* Circle */
100, /* Circle */ 100, /* Circle */
100, /* Ellipse */ 100, /* Ellipse */
100, /* Ellipse */ 100, /* Ellipse */
100, /* Triangle */ 100, /* Triangle */
100, /* Triangle */ 100, /* Triangle */
100, /* Pentagon */ 100, /* Pentagon */
100, /* Pentagon */ 100, /* Pentagon */
100, /* Rhombus */ 100, /* Rhombus */
100, /* Rhombus */ 100, /* Rhombus */
100, /* Octagon */ 100, /* Octagon */
100, /* Octagon */ 100, /* Octagon */
20, /* 3 points star */ 20, /* 3 points star */
20, /* 3 points star */ 20, /* 3 points star */
30, /* 4 points star */ 30, /* 4 points star */
30, /* 4 points star */ 30, /* 4 points star */
35, /* 5 points star */ 35, /* 5 points star */
35 /* 5 points star */ 35 /* 5 points star */
}; };
@ -279,7 +279,6 @@ const char *const shape_names[NUM_SHAPES] = {
// Pentagone star (5 points star) // Pentagone star (5 points star)
gettext_noop("Star") gettext_noop("Star")
}; };
@ -295,10 +294,8 @@ const char *const shape_tips[NUM_SHAPES] = {
gettext_noop("A rectangle has four sides and four right angles."), gettext_noop("A rectangle has four sides and four right angles."),
// Description of a circle // Description of a circle
gettext_noop gettext_noop("A circle is a curve where all points have the same distance from the center."),
("A circle is a curve where all points have the same distance from the center."), gettext_noop("A circle is a curve where all points have the same distance from the center."),
gettext_noop
("A circle is a curve where all points have the same distance from the center."),
// Description of an ellipse // Description of an ellipse
gettext_noop("An ellipse is a stretched circle."), gettext_noop("An ellipse is a stretched circle."),
@ -313,16 +310,12 @@ const char *const shape_tips[NUM_SHAPES] = {
gettext_noop("A pentagon has five sides."), gettext_noop("A pentagon has five sides."),
// Description of a rhombus // Description of a rhombus
gettext_noop gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
("A rhombus has four equal sides, and opposite sides are parallel."), gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
gettext_noop
("A rhombus has four equal sides, and opposite sides are parallel."),
// Description of an octagon // Description of an octagon
gettext_noop gettext_noop("An octagon has eight equal sides."),
("An octagon has eight equal sides."), gettext_noop("An octagon has eight equal sides."),
gettext_noop
("An octagon has eight equal sides."),
gettext_noop("A star with 3 points."), gettext_noop("A star with 3 points."),
gettext_noop("A star with 3 points."), gettext_noop("A star with 3 points."),
@ -330,7 +323,6 @@ const char *const shape_tips[NUM_SHAPES] = {
gettext_noop("A star with 4 points."), gettext_noop("A star with 4 points."),
gettext_noop("A star with 5 points."), gettext_noop("A star with 5 points."),
gettext_noop("A star with 5 points.") gettext_noop("A star with 5 points.")
}; };
@ -359,5 +351,4 @@ const char *const shape_img_fnames[NUM_SHAPES] = {
DATA_PREFIX "images/shapes/star4p_f.png", DATA_PREFIX "images/shapes/star4p_f.png",
DATA_PREFIX "images/shapes/star5p.png", DATA_PREFIX "images/shapes/star5p.png",
DATA_PREFIX "images/shapes/star5p_f.png" DATA_PREFIX "images/shapes/star5p_f.png"
}; };

View file

@ -37,34 +37,34 @@
enum enum
{ {
SND_HARP, /* Begin / New */ SND_HARP, /* Begin / New */
SND_CLICK, /* Tool selections */ SND_CLICK, /* Tool selections */
SND_BLEEP, /* Selector selection */ SND_BLEEP, /* Selector selection */
SND_BUBBLE, /* Color selection */ SND_BUBBLE, /* Color selection */
SND_STAMP, /* Using stamp tool */ SND_STAMP, /* Using stamp tool */
SND_LINE_START, /* Using line tool */ SND_LINE_START, /* Using line tool */
SND_LINE_END, SND_LINE_END,
SND_SCROLL, /* Selector scroll buttons */ SND_SCROLL, /* Selector scroll buttons */
SND_PAINT1, /* Sound while painting */ SND_PAINT1, /* Sound while painting */
SND_PAINT2, SND_PAINT2,
SND_PAINT3, SND_PAINT3,
SND_PAINT4, SND_PAINT4,
SND_ERASER1, /* Sound while erasing */ SND_ERASER1, /* Sound while erasing */
SND_ERASER2, SND_ERASER2,
SND_SAVE, /* Save sound effect */ SND_SAVE, /* Save sound effect */
SND_PROMPT, /* Prompt animation sound effect */ SND_PROMPT, /* Prompt animation sound effect */
SND_FLIP, /* Magic flip */ SND_FLIP, /* Magic flip */
SND_MIRROR, /* Magic mirror */ SND_MIRROR, /* Magic mirror */
SND_KEYCLICK, /* Text tool keyboard click feedback */ SND_KEYCLICK, /* Text tool keyboard click feedback */
SND_KEYCLICKRING, /* Text tool keyboard click feedback with bell ring */ SND_KEYCLICKRING, /* Text tool keyboard click feedback with bell ring */
SND_RETURN, /* Text tool carriage return sound */ SND_RETURN, /* Text tool carriage return sound */
SND_SHRINK, /* Stamp shrink */ SND_SHRINK, /* Stamp shrink */
SND_GROW, /* Stamp grow */ SND_GROW, /* Stamp grow */
SND_ITALIC_ON, /* Italic on */ SND_ITALIC_ON, /* Italic on */
SND_ITALIC_OFF, /* Italic off */ SND_ITALIC_OFF, /* Italic off */
SND_AREYOUSURE, /* "Are you sure?" */ SND_AREYOUSURE, /* "Are you sure?" */
SND_YOUCANNOT, /* "No no no!" */ SND_YOUCANNOT, /* "No no no!" */
SND_TUXOK, /* "Ok" */ SND_TUXOK, /* "Ok" */
SND_THICK, SND_THICK,
SND_THIN, SND_THIN,
NUM_SOUNDS NUM_SOUNDS

View file

@ -121,13 +121,16 @@ const char *const tool_tips[NUM_TOOLS] = {
gettext_noop("Click to start drawing a line. Let go to complete it."), gettext_noop("Click to start drawing a line. Let go to complete it."),
// Shape tool instructions // Shape tool instructions
gettext_noop("Pick a shape. Click to pick the center, drag, then let go when it is the size you want. Move around to rotate it, and click to draw it."), gettext_noop
("Pick a shape. Click to pick the center, drag, then let go when it is the size you want. Move around to rotate it, and click to draw it."),
// Text tool instructions // Text tool instructions
gettext_noop("Choose a style of text. Click on your drawing and you can start typing. Press [Enter] or [Tab] to complete the text."), gettext_noop
("Choose a style of text. Click on your drawing and you can start typing. Press [Enter] or [Tab] to complete the text."),
// Label tool instructions // Label tool instructions
gettext_noop("Choose a style of text. Click on your drawing and you can start typing. Press [Enter] or [Tab] to complete the text. By using the selector button and clicking an existing label, you can move it, edit it and change its text style."), gettext_noop
("Choose a style of text. Click on your drawing and you can start typing. Press [Enter] or [Tab] to complete the text. By using the selector button and clicking an existing label, you can move it, edit it and change its text style."),
// Reserved... // Reserved...
" ", " ",

File diff suppressed because it is too large Load diff

View file

@ -1,128 +1,125 @@
/****************************************************/ /****************************************************/
/* */ /* */
/* For Win32 that lacks Unix direct support. */ /* For Win32 that lacks Unix direct support. */
/* - avoids including "windows.h" */ /* - avoids including "windows.h" */
/* */ /* */
/* Copyright (c) 2002 John Popplewell */ /* Copyright (c) 2002 John Popplewell */
/* john@johnnypops.demon.co.uk */ /* john@johnnypops.demon.co.uk */
/* */ /* */
/* Version 1.0.1 - fixed bug in opendir() */ /* Version 1.0.1 - fixed bug in opendir() */
/* Version 1.0.0 - initial version */ /* Version 1.0.0 - initial version */
/* */ /* */
/****************************************************/ /****************************************************/
/* /*
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* $Id$ */ /* $Id$ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "win32_dirent.h" #include "win32_dirent.h"
#include "debug.h" #include "debug.h"
DIR * opendir(const char *pSpec) DIR * opendir(const char *pSpec)
{ {
char pathname[MAX_PATH + 2]; char pathname[MAX_PATH + 2];
DIR * pDir = calloc(1, sizeof(DIR));
if (!pDir) DIR * pDir = calloc(1, sizeof(DIR));
return NULL; if (!pDir)
strcpy(pathname, pSpec); return NULL;
strcat(pathname, "/*"); strcpy(pathname, pSpec);
pDir->hFind = FindFirstFile(pathname, &pDir->wfd); strcat(pathname, "/*");
if (pDir->hFind == INVALID_HANDLE_VALUE) pDir->hFind = FindFirstFile(pathname, &pDir->wfd);
if (pDir->hFind == INVALID_HANDLE_VALUE)
{
free(pDir); {
pDir = NULL; free(pDir);
} pDir = NULL;
return pDir; }
} return pDir;
void closedir(DIR * pDir) }
{
assert(pDir != NULL); void closedir(DIR * pDir)
free(pDir); {
} struct dirent *readdir(struct DIR *pDir) assert(pDir != NULL);
{ free(pDir);
assert(pDir != NULL); } struct dirent *readdir(struct DIR *pDir)
if (pDir->hFind) {
assert(pDir != NULL);
{ if (pDir->hFind)
strcpy(pDir->de.d_name, (const char *) pDir->wfd.cFileName);
if (!FindNextFile(pDir->hFind, &pDir->wfd)) {
strcpy(pDir->de.d_name, (const char *)pDir->wfd.cFileName);
{ if (!FindNextFile(pDir->hFind, &pDir->wfd))
FindClose(pDir->hFind);
pDir->hFind = NULL; {
} FindClose(pDir->hFind);
return &pDir->de; pDir->hFind = NULL;
} }
return NULL; return &pDir->de;
} }
int alphasort(const void *a, const void *b) return NULL;
{ }
return (strcmp
((*(const struct dirent **) a)->d_name, int alphasort(const void *a, const void *b)
(*(const struct dirent **) b)->d_name)); {
} static int addToList(int i, struct dirent ***namelist, return (strcmp((*(const struct dirent **)a)->d_name, (*(const struct dirent **)b)->d_name));
struct dirent *entry) } static int addToList(int i, struct dirent ***namelist, struct dirent *entry)
{ {
int size; int size;
struct dirent *block; struct dirent *block;
*namelist =
(struct dirent **) realloc((void *) (*namelist), *namelist = (struct dirent **)realloc((void *)(*namelist), (size_t) ((i + 1) * sizeof(struct dirent *)));
(size_t) ((i + 1) * sizeof(struct dirent *))); if (*namelist == NULL)
if (*namelist == NULL) return -1;
return -1; size = (((char *)&entry->d_name) - ((char *)entry)) + strlen(entry->d_name) + 1;
size = block = (struct dirent *)malloc(size);
(((char *) &entry->d_name) - ((char *) entry)) + strlen(entry->d_name) + if (block == NULL)
1; return -1;
block = (struct dirent *) malloc(size); (*namelist)[i] = block;
if (block == NULL) memcpy(block, entry, size);
return -1; return ++i;
(*namelist)[i] = block; }
memcpy(block, entry, size);
return ++i; int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar)
} {
int scandir(const char *dir, struct dirent ***namelist, selectCB select, DIR * pDir;
comparCB compar) int count;
{ struct dirent *entry;
DIR * pDir;
int count; assert((dir != NULL) && (namelist != NULL));
struct dirent *entry; pDir = opendir(dir);
assert((dir != NULL) && (namelist != NULL)); if (!pDir)
pDir = opendir(dir); return -1;
if (!pDir) count = 0;
return -1; while ((entry = readdir(pDir)) != NULL)
count = 0;
while ((entry = readdir(pDir)) != NULL) {
if (select == NULL || (select != NULL && select(entry)))
{ if ((count = addToList(count, namelist, entry)) < 0)
if (select == NULL || (select != NULL && select(entry))) break;
if ((count = addToList(count, namelist, entry)) < 0) }
break; closedir(pDir);
} if (count <= 0)
closedir(pDir); return -1;
if (count <= 0) if (compar != NULL)
return -1; qsort((void *)(*namelist), (size_t) count, sizeof(struct dirent *), compar);
if (compar != NULL) return count;
qsort((void *) (*namelist), (size_t) count, sizeof(struct dirent *), }
compar);
return count;
}

View file

@ -1,73 +1,76 @@
/****************************************************/ /****************************************************/
/* */ /* */
/* For Win32 that lacks Unix direct support. */ /* For Win32 that lacks Unix direct support. */
/* - avoids including "windows.h" */ /* - avoids including "windows.h" */
/* */ /* */
/* Copyright (c) 2002 John Popplewell */ /* Copyright (c) 2002 John Popplewell */
/* john@johnnypops.demon.co.uk */ /* john@johnnypops.demon.co.uk */
/* */ /* */
/****************************************************/ /****************************************************/
/* $Id$ */ /* $Id$ */
typedef long BOOL; typedef long BOOL;
typedef unsigned int DWORD; typedef unsigned int DWORD;
typedef wchar_t TCHAR; typedef wchar_t TCHAR;
typedef void *HANDLE; typedef void *HANDLE;
#define MAX_PATH 256
#define INVALID_HANDLE_VALUE ((HANDLE)(-1)) #define MAX_PATH 256
#define WINAPI __stdcall #define INVALID_HANDLE_VALUE ((HANDLE)(-1))
typedef struct #define WINAPI __stdcall
typedef struct
{ {
DWORD dwLowDateTime; DWORD dwLowDateTime;
DWORD dwHighDateTime; DWORD dwHighDateTime;
} FILETIME; } FILETIME;
typedef struct typedef struct
{ {
DWORD dwFileAttributes; DWORD dwFileAttributes;
FILETIME ftCreationTime; FILETIME ftCreationTime;
FILETIME ftLastAccessTime; FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime; FILETIME ftLastWriteTime;
DWORD nFileSizeHigh; DWORD nFileSizeHigh;
DWORD nFileSizeLow; DWORD nFileSizeLow;
DWORD dwReserved0; DWORD dwReserved0;
DWORD dwReserved1; DWORD dwReserved1;
TCHAR cFileName[MAX_PATH]; TCHAR cFileName[MAX_PATH];
TCHAR cAlternateFileName[14]; TCHAR cAlternateFileName[14];
} WIN32_FIND_DATA; } WIN32_FIND_DATA;
#define FindFirstFile FindFirstFileA
#define FindNextFile FindNextFileA #define FindFirstFile FindFirstFileA
#define FindClose FindClose #define FindNextFile FindNextFileA
#define FindClose FindClose
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" extern "C"
{ {
#endif /* */ #endif /* */
extern HANDLE WINAPI FindFirstFile(const char *, WIN32_FIND_DATA *); extern HANDLE WINAPI FindFirstFile(const char *, WIN32_FIND_DATA *);
extern BOOL WINAPI FindNextFile(HANDLE, WIN32_FIND_DATA *); extern BOOL WINAPI FindNextFile(HANDLE, WIN32_FIND_DATA *);
extern BOOL WINAPI FindClose(HANDLE); extern BOOL WINAPI FindClose(HANDLE);
#ifdef __cplusplus #ifdef __cplusplus
}; };
#endif /* */
struct dirent #endif /* */
struct dirent
{ {
char d_name[MAX_PATH]; char d_name[MAX_PATH];
}; };
typedef struct typedef struct
{ {
WIN32_FIND_DATA wfd; WIN32_FIND_DATA wfd;
HANDLE hFind; HANDLE hFind;
struct dirent de; struct dirent de;
} DIR; } DIR;
extern DIR *opendir(const char *pSpec); extern DIR *opendir(const char *pSpec);
extern void closedir(DIR * pDir); extern void closedir(DIR * pDir);
extern struct dirent *readdir(struct DIR *pDir); extern struct dirent *readdir(struct DIR *pDir);
typedef int (*selectCB) (const struct dirent *); typedef int (*selectCB) (const struct dirent *);
typedef int (*comparCB) (const void *, const void *); typedef int (*comparCB) (const void *, const void *);
extern int alphasort(const void *a, const void *b); extern int alphasort(const void *a, const void *b);
extern int scandir(const char *dir, struct dirent ***namelist, extern int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar);
selectCB select, comparCB compar);

View file

@ -67,20 +67,19 @@ static SDL_Surface *make24bitDIB(SDL_Surface * surf)
surf24 = SDL_ConvertSurface(surf, &pixfmt, SDL_SWSURFACE); surf24 = SDL_ConvertSurface(surf, &pixfmt, SDL_SWSURFACE);
surfDIB = SDL_CreateRGBSurface(SDL_SWSURFACE, surf24->w, surf24->h, 24, surfDIB = SDL_CreateRGBSurface(SDL_SWSURFACE, surf24->w, surf24->h, 24,
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask);
pixfmt.Amask);
linesize = surf24->w * 3; // Flip top2bottom linesize = surf24->w * 3; // Flip top2bottom
dst = surfDIB->pixels; dst = surfDIB->pixels;
src = ((Uint8 *) surf24->pixels) + ((surf24->h - 1) * surf24->pitch); src = ((Uint8 *) surf24->pixels) + ((surf24->h - 1) * surf24->pitch);
for (i = 0; i < surf24->h; ++i) for (i = 0; i < surf24->h; ++i)
{ {
memcpy(dst, src, linesize); memcpy(dst, src, linesize);
src -= surf24->pitch; src -= surf24->pitch;
dst += surfDIB->pitch; dst += surfDIB->pitch;
} }
SDL_FreeSurface(surf24); // Free temp surface SDL_FreeSurface(surf24); // Free temp surface
return surfDIB; return surfDIB;
} }
@ -101,17 +100,16 @@ static int GetDefaultPrinterStrings(char *device, char *driver, char *output)
return 0; return 0;
if (((dev = strtok(buff, ",")) != NULL) && if (((dev = strtok(buff, ",")) != NULL) &&
((drv = strtok(NULL, ", ")) != NULL) && ((drv = strtok(NULL, ", ")) != NULL) && ((out = strtok(NULL, ", ")) != NULL))
((out = strtok(NULL, ", ")) != NULL)) {
{ if (device)
if (device) strcpy(device, dev);
strcpy(device, dev); if (driver)
if (driver) strcpy(driver, drv);
strcpy(driver, drv); if (output)
if (output) strcpy(output, out);
strcpy(output, out); return 1;
return 1; }
}
return 0; return 0;
} }
@ -138,8 +136,7 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
if (!OpenPrinter(device, &hPrinter, NULL)) if (!OpenPrinter(device, &hPrinter, NULL))
goto err_exit; goto err_exit;
sizeof_devmode = (int) DocumentProperties(hWnd, hPrinter, device, sizeof_devmode = (int)DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0);
NULL, NULL, 0);
if (!sizeof_devmode) if (!sizeof_devmode)
goto err_exit; goto err_exit;
@ -152,8 +149,7 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
if (!devmode) if (!devmode)
goto err_exit; goto err_exit;
res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL, res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER);
DM_OUT_BUFFER);
if (res != IDOK) if (res != IDOK)
goto err_exit; goto err_exit;
@ -163,8 +159,7 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
goto err_exit; goto err_exit;
fclose(fp); fclose(fp);
res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode, res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);
DM_IN_BUFFER | DM_OUT_BUFFER);
if (res != IDOK) if (res != IDOK)
goto err_exit; goto err_exit;
@ -185,39 +180,38 @@ err_exit:
} }
static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath, static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath, HANDLE hDevMode)
HANDLE hDevMode)
{ {
FILE *fp = NULL; FILE *fp = NULL;
NOREF(hWnd); NOREF(hWnd);
if ((fp = fopen(filepath, "wb")) != NULL) if ((fp = fopen(filepath, "wb")) != NULL)
{ {
DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode); DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode);
int block_size = devmode->dmSize + devmode->dmDriverExtra; int block_size = devmode->dmSize + devmode->dmDriverExtra;
int block_written; int block_written;
char devname[dmDeviceNameSize]; char devname[dmDeviceNameSize];
strcpy(devname, (const char *) devmode->dmDeviceName); strcpy(devname, (const char *)devmode->dmDeviceName);
fwrite(devname, 1, sizeof(devname), fp); fwrite(devname, 1, sizeof(devname), fp);
block_written = fwrite(devmode, 1, block_size, fp); block_written = fwrite(devmode, 1, block_size, fp);
GlobalUnlock(hDevMode); GlobalUnlock(hDevMode);
fclose(fp); fclose(fp);
return block_size == block_written; return block_size == block_written;
} }
return 0; return 0;
} }
static int FileExists(const char *filepath) static int FileExists(const char *filepath)
{ {
FILE *fp; FILE *fp;
if ((fp = fopen(filepath, "rb")) != NULL) if ((fp = fopen(filepath, "rb")) != NULL)
{ {
fclose(fp); fclose(fp);
return 1; return 1;
} }
return 0; return 0;
} }
static int GetCustomPrinterDC(HWND hWnd, const char *printcfg, int show) static int GetCustomPrinterDC(HWND hWnd, const char *printcfg, int show)
@ -237,23 +231,22 @@ static int GetCustomPrinterDC(HWND hWnd, const char *printcfg, int show)
pd.hDevMode = LoadCustomPrinterHDEVMODE(hWnd, printcfg); pd.hDevMode = LoadCustomPrinterHDEVMODE(hWnd, printcfg);
if (show || !FileExists(printcfg)) if (show || !FileExists(printcfg))
{
if (PrintDlg(&pd))
{ {
hDCprinter = pd.hDC; if (PrintDlg(&pd))
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode); {
hDCprinter = pd.hDC;
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode);
GlobalFree(pd.hDevMode);
return 1;
}
GlobalFree(pd.hDevMode); GlobalFree(pd.hDevMode);
return 1; return 0;
} }
GlobalFree(pd.hDevMode);
return 0;
}
{ {
DEVMODE *devmode = (DEVMODE *) GlobalLock(pd.hDevMode); DEVMODE *devmode = (DEVMODE *) GlobalLock(pd.hDevMode);
hDCprinter = hDCprinter = CreateDC(NULL, (const char *)devmode->dmDeviceName, NULL, devmode);
CreateDC(NULL, (const char *) devmode->dmDeviceName, NULL, devmode);
GlobalUnlock(pd.hDevMode); GlobalUnlock(pd.hDevMode);
GlobalFree(pd.hDevMode); GlobalFree(pd.hDevMode);
} }
@ -276,9 +269,9 @@ static int GetPrinterDC(HWND hWnd, const char *printcfg, int show)
hDCprinter = NULL; hDCprinter = NULL;
if (printcfg) if (printcfg)
{ {
return GetCustomPrinterDC(hWnd, printcfg, show); return GetCustomPrinterDC(hWnd, printcfg, show);
} }
hDCprinter = GetDefaultPrinterDC(); hDCprinter = GetDefaultPrinterDC();
return 1; return 1;
} }
@ -292,8 +285,7 @@ int IsPrinterAvailable(void)
#define STRETCH_TO_FIT 0 #define STRETCH_TO_FIT 0
#define SCALE_TO_FIT 1 #define SCALE_TO_FIT 1
const char *SurfacePrint(SDL_Surface * surf, const char *printcfg, const char *SurfacePrint(SDL_Surface * surf, const char *printcfg, int showdialog)
int showdialog)
{ {
const char *res = NULL; const char *res = NULL;
HWND hWnd; HWND hWnd;
@ -316,10 +308,10 @@ const char *SurfacePrint(SDL_Surface * surf, const char *printcfg,
hWnd = wminfo.window; hWnd = wminfo.window;
if (!GetPrinterDC(hWnd, printcfg, showdialog)) if (!GetPrinterDC(hWnd, printcfg, showdialog))
{ {
ShowWindow(hWnd, SW_SHOWNORMAL); ShowWindow(hWnd, SW_SHOWNORMAL);
return NULL; return NULL;
} }
if (!hDCprinter) if (!hDCprinter)
return "win32_print: GetPrinterDC() failed."; return "win32_print: GetPrinterDC() failed.";
@ -334,26 +326,26 @@ const char *SurfacePrint(SDL_Surface * surf, const char *printcfg,
nError = StartDoc(hDCprinter, &di); nError = StartDoc(hDCprinter, &di);
if (nError == SP_ERROR) if (nError == SP_ERROR)
{ {
res = "win32_print: StartDoc() failed."; res = "win32_print: StartDoc() failed.";
goto error; goto error;
} }
nError = StartPage(hDCprinter); nError = StartPage(hDCprinter);
if (nError <= 0) if (nError <= 0)
{ {
res = "win32_print: StartPage() failed."; res = "win32_print: StartPage() failed.";
goto error; goto error;
} }
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
surf24 = make24bitDIB(surf); surf24 = make24bitDIB(surf);
if (!surf24) if (!surf24)
{ {
res = "win32_print: make24bitDIB() failed."; res = "win32_print: make24bitDIB() failed.";
goto error; goto error;
} }
memset(&bmih, 0, sizeof(bmih)); memset(&bmih, 0, sizeof(bmih));
bmih.biSize = sizeof(bmih); bmih.biSize = sizeof(bmih);
@ -363,104 +355,105 @@ const char *SurfacePrint(SDL_Surface * surf, const char *printcfg,
bmih.biWidth = surf24->w; bmih.biWidth = surf24->w;
bmih.biHeight = surf24->h; bmih.biHeight = surf24->h;
pageWidth = GetDeviceCaps(hDCprinter, HORZRES); pageWidth = GetDeviceCaps(hDCprinter, HORZRES);
pageHeight = GetDeviceCaps(hDCprinter, VERTRES); pageHeight = GetDeviceCaps(hDCprinter, VERTRES);
sX = GetDeviceCaps(hDCprinter, LOGPIXELSX); sX = GetDeviceCaps(hDCprinter, LOGPIXELSX);
sY = GetDeviceCaps(hDCprinter, LOGPIXELSY); sY = GetDeviceCaps(hDCprinter, LOGPIXELSY);
switch (scaling) switch (scaling)
{
case STRETCH_TO_FIT:
{ {
case STRETCH_TO_FIT:
{
/* stretches x and y dimensions independently to fit the page */ /* stretches x and y dimensions independently to fit the page */
/* doesn't preserve image aspect-ratio */ /* doesn't preserve image aspect-ratio */
rcDst.top = 0; rcDst.left = 0; rcDst.top = 0;
rcDst.bottom = pageHeight; rcDst.right = pageWidth; rcDst.left = 0;
rcDst.bottom = pageHeight;
rcDst.right = pageWidth;
break; break;
} }
case SCALE_TO_FIT: case SCALE_TO_FIT:
{ {
/* maximises image size on the page */ /* maximises image size on the page */
/* preserves aspect-ratio, alignment is top and center */ /* preserves aspect-ratio, alignment is top and center */
int width = bmih.biWidth; int width = bmih.biWidth;
int height = bmih.biHeight; int height = bmih.biHeight;
if (width < pageWidth && height < pageHeight) if (width < pageWidth && height < pageHeight)
{ {
float dW = (float)pageWidth / width; float dW = (float)pageWidth / width;
float dH = (float)pageHeight / height; float dH = (float)pageHeight / height;
if (dW < dH) if (dW < dH)
{ {
width = pageWidth; width = pageWidth;
height = (int)((height * dW * (sY/sX)) + 0.5f); height = (int)((height * dW * (sY / sX)) + 0.5f);
} }
else else
{ {
width = (int)((width * dH * (sX/sY)) + 0.5f); width = (int)((width * dH * (sX / sY)) + 0.5f);
height = pageHeight; height = pageHeight;
} }
} }
if (width > pageWidth) if (width > pageWidth)
{ {
height= height*width/pageWidth; height = height * width / pageWidth;
width = pageWidth; width = pageWidth;
} }
if (height > pageHeight) if (height > pageHeight)
{ {
width= width*height/pageHeight; width = width * height / pageHeight;
height = pageHeight; height = pageHeight;
} }
rcDst.top = 0; rcDst.top = 0;
rcDst.left = (pageWidth-width)/2; rcDst.left = (pageWidth - width) / 2;
rcDst.bottom = rcDst.top+height; rcDst.bottom = rcDst.top + height;
rcDst.right = rcDst.left+width; rcDst.right = rcDst.left + width;
break; break;
} }
default: default:
res = "win32_print: invalid scaling option."; res = "win32_print: invalid scaling option.";
goto error; goto error;
} }
hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS); hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS);
if (hDCCaps & RC_PALETTE) if (hDCCaps & RC_PALETTE)
{
res = "win32_print: printer context requires palette.";
goto error;
}
if (hDCCaps & RC_STRETCHDIB)
{
SetStretchBltMode(hDCprinter, COLORONCOLOR);
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
rcDst.right - rcDst.left,
rcDst.bottom - rcDst.top,
0, 0, bmih.biWidth, bmih.biHeight,
surf24->pixels, (BITMAPINFO *) & bmih,
DIB_RGB_COLORS, SRCCOPY);
if (nError == GDI_ERROR)
{ {
res = "win32_print: StretchDIBits() failed."; res = "win32_print: printer context requires palette.";
goto error; goto error;
} }
}
if (hDCCaps & RC_STRETCHDIB)
{
SetStretchBltMode(hDCprinter, COLORONCOLOR);
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
rcDst.right - rcDst.left,
rcDst.bottom - rcDst.top,
0, 0, bmih.biWidth, bmih.biHeight,
surf24->pixels, (BITMAPINFO *) & bmih, DIB_RGB_COLORS, SRCCOPY);
if (nError == GDI_ERROR)
{
res = "win32_print: StretchDIBits() failed.";
goto error;
}
}
else else
{ {
res = "win32_print: StretchDIBits() not available."; res = "win32_print: StretchDIBits() not available.";
goto error; goto error;
} }
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
nError = EndPage(hDCprinter); nError = EndPage(hDCprinter);
if (nError <= 0) if (nError <= 0)
{ {
res = "win32_print: EndPage() failed."; res = "win32_print: EndPage() failed.";
goto error; goto error;
} }
EndDoc(hDCprinter); EndDoc(hDCprinter);
@ -482,8 +475,7 @@ error:
/* /*
Read access to Windows Registry Read access to Windows Registry
*/ */
static HRESULT ReadRegistry(const char *key, const char *option, char *value, static HRESULT ReadRegistry(const char *key, const char *option, char *value, int size)
int size)
{ {
LONG res; LONG res;
HKEY hKey = NULL; HKEY hKey = NULL;
@ -491,9 +483,7 @@ static HRESULT ReadRegistry(const char *key, const char *option, char *value,
res = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey); res = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
if (res != ERROR_SUCCESS) if (res != ERROR_SUCCESS)
goto err_exit; goto err_exit;
res = res = RegQueryValueEx(hKey, option, NULL, NULL, (LPBYTE) value, (LPDWORD) & size);
RegQueryValueEx(hKey, option, NULL, NULL, (LPBYTE) value,
(LPDWORD) & size);
if (res != ERROR_SUCCESS) if (res != ERROR_SUCCESS)
goto err_exit; goto err_exit;
res = ERROR_SUCCESS; res = ERROR_SUCCESS;
@ -529,18 +519,17 @@ char *GetDefaultSaveDir(const char *suffix)
{ {
char prefix[MAX_PATH]; char prefix[MAX_PATH];
char path[2 * MAX_PATH]; char path[2 * MAX_PATH];
const char *key = const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *option = "AppData"; const char *option = "AppData";
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (SUCCEEDED(hr = ReadRegistry(key, option, prefix, sizeof(prefix)))) if (SUCCEEDED(hr = ReadRegistry(key, option, prefix, sizeof(prefix))))
{ {
remove_slash(prefix); remove_slash(prefix);
snprintf(path, sizeof(path), "%s/%s", prefix, suffix); snprintf(path, sizeof(path), "%s/%s", prefix, suffix);
_mkdir(path); _mkdir(path);
return strdup(path); return strdup(path);
} }
return strdup("userdata"); return strdup("userdata");
} }
@ -551,16 +540,15 @@ char *GetDefaultSaveDir(const char *suffix)
char *GetSystemFontDir(void) char *GetSystemFontDir(void)
{ {
char path[MAX_PATH]; char path[MAX_PATH];
const char *key = const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const char *option = "Fonts"; const char *option = "Fonts";
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path)))) if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path))))
{ {
remove_slash(path); remove_slash(path);
return strdup(path); return strdup(path);
} }
return strdup("C:\\WINDOWS\\FONTS"); return strdup("C:\\WINDOWS\\FONTS");
} }
@ -573,9 +561,9 @@ static char *GetUserTempDir(void)
char *temp = getenv("TEMP"); char *temp = getenv("TEMP");
if (!temp) if (!temp)
{ {
temp = "userdata"; temp = "userdata";
} }
return strdup(temp); return strdup(temp);
} }
@ -594,27 +582,27 @@ char *get_temp_fname(const char *const name)
*/ */
static HHOOK g_hKeyboardHook = NULL; static HHOOK g_hKeyboardHook = NULL;
static int g_bWindowActive = 0; static int g_bWindowActive = 0;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{ {
int bEatKeystroke = 0; int bEatKeystroke = 0;
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT*)lParam; KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *) lParam;
if (nCode < 0 || nCode != HC_ACTION) if (nCode < 0 || nCode != HC_ACTION)
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam); return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
switch (wParam) switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
{ {
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)); case WM_KEYDOWN:
break; case WM_KEYUP:
{
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN));
break;
}
} }
}
if (bEatKeystroke)
if(bEatKeystroke)
return 1; return 1;
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam); return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
} }
@ -640,5 +628,3 @@ void SetActivationState(int state)
{ {
g_bWindowActive = state; g_bWindowActive = state;
} }

View file

@ -15,8 +15,7 @@
#endif #endif
/* if printcfg is NULL, uses the default printer */ /* if printcfg is NULL, uses the default printer */
extern const char *SurfacePrint(SDL_Surface * surf, extern const char *SurfacePrint(SDL_Surface * surf, const char *printcfg, int showdialog);
const char *printcfg, int showdialog);
extern int IsPrinterAvailable(void); extern int IsPrinterAvailable(void);
/* additional windows functions requiring <windows.h> */ /* additional windows functions requiring <windows.h> */
@ -25,8 +24,8 @@ extern char *GetSystemFontDir(void);
extern char *get_temp_fname(const char *const name); extern char *get_temp_fname(const char *const name);
/* keyboard hooking functions */ /* keyboard hooking functions */
extern int InstallKeyboardHook(void); extern int InstallKeyboardHook(void);
extern int RemoveKeyboardHook(void); extern int RemoveKeyboardHook(void);
extern void SetActivationState(int state); extern void SetActivationState(int state);
#endif #endif