X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fjuggle.c;h=7634d3e5f11720a62c15e29ee7c5f3969d17ba67;hp=6288bd08743a31aedda862f77b83a3d747369b07;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/juggle.c b/hacks/juggle.c index 6288bd08..7634d3e5 100644 --- a/hacks/juggle.c +++ b/hacks/juggle.c @@ -130,26 +130,18 @@ static const char sccsid[] = "@(#)juggle.c 5.10 2003/09/02 xlockmore"; #undef MEMTEST #ifdef STANDALONE -#define MODE_juggle -#define PROGCLASS "Juggle" -#define HACK_INIT init_juggle -#define HACK_DRAW draw_juggle -#define HACK_RESHAPE reshape_juggle -#define _no_HACK_FREE release_juggle -#define juggle_opts xlockmore_opts -#define DEFAULTS "*delay: 10000 \n" \ -"*count: 200 \n" \ -"*cycles: 1000 \n" \ -"*ncolors: 32 \n" \ -"*font: -*-times-bold-r-normal-*-180-*\n" -#undef SMOOTH_COLORS -#include "xlockmore.h" /* in xscreensaver distribution */ -#define MI_DELAY(MI) ((MI)->pause) -# ifndef MI_DEPTH -# define MI_DEPTH MI_WIN_DEPTH -# endif +# define MODE_juggle +# define DEFAULTS "*delay: 10000 \n" \ + "*count: 200 \n" \ + "*cycles: 1000 \n" \ + "*ncolors: 32 \n" \ + "*font: -*-times-bold-r-normal-*-180-*\n" +# define refresh_juggle 0 +# define juggle_handle_event 0 +# undef SMOOTH_COLORS +# include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -#include "xlock.h" /* in xlockmore distribution */ +# include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ #ifdef MODE_juggle @@ -163,7 +155,7 @@ static const char sccsid[] = "@(#)juggle.c 5.10 2003/09/02 xlockmore"; } #endif -#define DEF_PATTERN "." /* All patterns */ +#define DEF_PATTERN "random" /* All patterns */ #define DEF_TAIL "1" /* No trace */ #ifdef UNI /* Maybe a ROLA BOLA would be at a better angle for viewing */ @@ -259,7 +251,7 @@ static OptionStruct desc[] = { "-only", "Turn off all objects but the named one." }, }; -ModeSpecOpt juggle_opts = +ENTRYPOINT ModeSpecOpt juggle_opts = { XtNumber(opts), opts, XtNumber(vars), vars, desc }; #ifdef USE_MODULES @@ -273,14 +265,7 @@ ModStruct juggle_description = { #endif #ifdef USE_XVMSUTILS -#include -#endif -#if HAVE_SYS_TIME_H -#include -#else -#if HAVE_SYS_SELECT_H -#include -#endif +# include #endif /* Note: All "lengths" are scaled by sp->scale = MI_HEIGHT/480. All @@ -488,29 +473,6 @@ typedef struct trajectory { } Trajectory; -/* Jugglestruct: per-screen global data. The master Wander, Object - * and Trajectory lists are anchored here. */ -typedef struct { - double scale; - Wander *wander; - double cx; - double Gr; - Trajectory *head; - Arm arm[2][2]; - char *pattern; - int count; - int num_balls; - time_t begintime; /* should make 'time' usable for at least 48 days - on a 32-bit machine */ - unsigned long time; /* millisecond timer*/ - ObjType objtypes; - Object *objects; -} jugglestruct; - -static jugglestruct *juggles = (jugglestruct *) NULL; - -static XFontStruct *mode_font = None; - /******************* * Pattern Library * *******************/ @@ -524,7 +486,9 @@ typedef struct { /* Patterns should be given in Adam notation so the generator can concatenate them safely. Null descriptions are ok. Height notation will be displayed automatically. */ -static patternstruct portfolio[] = { +/* Can't const this because it is qsorted. This *should* be reentrant, + I think... */ +static /*const*/ patternstruct portfolio[] = { {"[+2 1]", /* +3 1 */ "Typical 2 ball juggler"}, {"[2 0]", /* 4 0 */ "2 in 1 hand"}, {"[2 0 1]", /* 5 0 1 */}, @@ -609,13 +573,39 @@ static patternstruct portfolio[] = { }; + + typedef struct { int start; int number; } PatternIndex; -static struct { +struct patternindex { int minballs; int maxballs; PatternIndex index[XtNumber(portfolio)]; -} patternindex; +}; + + +/* Jugglestruct: per-screen global data. The master Wander, Object + * and Trajectory lists are anchored here. */ +typedef struct { + double scale; + Wander *wander; + double cx; + double Gr; + Trajectory *head; + Arm arm[2][2]; + char *pattern; + int count; + int num_balls; + time_t begintime; /* should make 'time' usable for at least 48 days + on a 32-bit machine */ + unsigned long time; /* millisecond timer*/ + ObjType objtypes; + Object *objects; + struct patternindex patternindex; + XFontStruct *mode_font; +} jugglestruct; + +static jugglestruct *juggles = (jugglestruct *) NULL; /******************* * list management * @@ -697,6 +687,10 @@ free_juggle(jugglestruct *sp) { free(sp->pattern); sp->pattern = NULL; } + if (sp->mode_font!=None) { + XFreeFontInfo(NULL,sp->mode_font,1); + sp->mode_font = None; + } } static Bool @@ -1697,6 +1691,7 @@ static int get_num_balls(const char *j) int balls = 0; const char *p; int h = 0; + if (!j) abort(); for (p = j; *p; p++) { if (*p >= '0' && *p <='9') { /* digit */ h = 10*h + (*p - '0'); @@ -2299,8 +2294,8 @@ show_bball(ModeInfo *mi, unsigned long color, Trace *s) **************************************************************************/ -void -release_juggle(ModeInfo * mi) +ENTRYPOINT void +release_juggle (ModeInfo * mi) { if (juggles != NULL) { int screen; @@ -2310,10 +2305,6 @@ release_juggle(ModeInfo * mi) free(juggles); juggles = (jugglestruct *) NULL; } - if (mode_font!=None) { - XFreeFontInfo(NULL,mode_font,1); - mode_font = None; - } } /* FIXME: refill_juggle currently just appends new throws to the @@ -2364,10 +2355,10 @@ refill_juggle(ModeInfo * mi) default: break; /* NO-OP */ } - if (new_balls < patternindex.minballs) { + if (new_balls < sp->patternindex.minballs) { new_balls += 2; } - if (new_balls > patternindex.maxballs) { + if (new_balls > sp->patternindex.maxballs) { new_balls -= 2; } if (new_balls < sp->num_balls) { @@ -2378,10 +2369,10 @@ refill_juggle(ModeInfo * mi) } count += t; - if (NRAND(2) && patternindex.index[sp->num_balls].number) { + if (NRAND(2) && sp->patternindex.index[sp->num_balls].number) { /* Pick from PortFolio */ - int p = patternindex.index[sp->num_balls].start + - NRAND(patternindex.index[sp->num_balls].number); + int p = sp->patternindex.index[sp->num_balls].start + + NRAND(sp->patternindex.index[sp->num_balls].number); if (!program(mi, portfolio[p].pattern, portfolio[p].name, t)) return; } else { @@ -2450,7 +2441,8 @@ refill_juggle(ModeInfo * mi) if(MI_IS_DEBUG(mi)) dump(sp); #endif } -void + +static void change_juggle(ModeInfo * mi) { jugglestruct *sp = NULL; @@ -2482,21 +2474,25 @@ change_juggle(ModeInfo * mi) } -#ifdef STANDALONE -/* Used by xscreensaver. xlock just uses init_juggle */ -void -reshape_juggle(ModeInfo * mi, int width, int height) -{ - init_juggle(mi); -} -#endif - -void -init_juggle(ModeInfo * mi) +ENTRYPOINT void +init_juggle (ModeInfo * mi) { - jugglestruct *sp; + jugglestruct *sp = 0; int i; + if (juggles == NULL) { /* First-time initialisation */ + + /* allocate jugglestruct */ + if ((juggles = + (jugglestruct *)calloc(MI_NUM_SCREENS(mi), + sizeof (jugglestruct))) == NULL) { + release_juggle(mi); + return; + } + } + + sp = &juggles[MI_SCREEN(mi)]; + if (only && *only && strcmp(only, " ")) { balls = clubs = torches = knives = rings = bballs = False; if (!strcasecmp (only, "balls")) balls = True; @@ -2515,53 +2511,7 @@ init_juggle(ModeInfo * mi) } } - if (pattern != NULL && *pattern == '.') { - pattern = NULL; - } - if (pattern == NULL && patternindex.maxballs == 0) { - /* pattern list needs indexing */ - int nelements = XtNumber(portfolio); - int numpat = 0; - - /* sort according to number of balls */ - qsort((void*)portfolio, nelements, - sizeof(portfolio[1]), compare_num_balls); - - /* last pattern has most balls */ - patternindex.maxballs = get_num_balls(portfolio[nelements - 1].pattern); - /* run through sorted list, indexing start of each group - and number in group */ - patternindex.maxballs = 1; - for (i = 0; i < nelements; i++) { - int b = get_num_balls(portfolio[i].pattern); - if (b > patternindex.maxballs) { - patternindex.index[patternindex.maxballs].number = numpat; - if(numpat == 0) patternindex.minballs = b; - patternindex.maxballs = b; - numpat = 1; - patternindex.index[patternindex.maxballs].start = i; - } else { - numpat++; - } - } - patternindex.index[patternindex.maxballs].number = numpat; - } - - /* Clean up the Screen. Don't use MI_CLEARWINDOW(mi), since we may - only be resizing and then we won't all those special effects. */ - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); - - if (juggles == NULL) { /* First-time initialisation */ - - /* allocate jugglestruct */ - if ((juggles = - (jugglestruct *)calloc(MI_NUM_SCREENS(mi), - sizeof (jugglestruct))) == NULL) { - release_juggle(mi); - return; - } - - sp = &juggles[MI_SCREEN(mi)]; + if (sp->head == 0) { /* first time initializing this juggler */ sp->count = ABS(MI_COUNT(mi)); if (sp->count == 0) @@ -2569,9 +2519,9 @@ init_juggle(ModeInfo * mi) /* record start time */ sp->begintime = time(NULL); - if(patternindex.maxballs > 0) { - sp->num_balls = patternindex.minballs + - NRAND(patternindex.maxballs - patternindex.minballs); + if(sp->patternindex.maxballs > 0) { + sp->num_balls = sp->patternindex.minballs + + NRAND(sp->patternindex.maxballs - sp->patternindex.minballs); } show_figure(mi, MI_WHITE_PIXEL(mi), True); /* Draw figure. Also discovers @@ -2610,28 +2560,72 @@ init_juggle(ModeInfo * mi) sp->pattern = strdup(""); /* Initialise saved pattern with free-able memory */ + } + + sp = &juggles[MI_SCREEN(mi)]; - /* Set up programme */ - change_juggle(mi); + if (pattern && + (!*pattern || + !strcasecmp (pattern, ".") || + !strcasecmp (pattern, "random"))) + pattern = NULL; + if (pattern == NULL && sp->patternindex.maxballs == 0) { + /* pattern list needs indexing */ + int nelements = XtNumber(portfolio); + int numpat = 0; + + /* sort according to number of balls */ + qsort((void*)portfolio, nelements, + sizeof(portfolio[1]), compare_num_balls); + + /* last pattern has most balls */ + sp->patternindex.maxballs = get_num_balls(portfolio[nelements - 1].pattern); + /* run through sorted list, indexing start of each group + and number in group */ + sp->patternindex.maxballs = 1; + for (i = 0; i < nelements; i++) { + int b = get_num_balls(portfolio[i].pattern); + if (b > sp->patternindex.maxballs) { + sp->patternindex.index[sp->patternindex.maxballs].number = numpat; + if(numpat == 0) sp->patternindex.minballs = b; + sp->patternindex.maxballs = b; + numpat = 1; + sp->patternindex.index[sp->patternindex.maxballs].start = i; + } else { + numpat++; + } + } + sp->patternindex.index[sp->patternindex.maxballs].number = numpat; } + /* Set up programme */ + change_juggle(mi); + + /* Clean up the Screen. Don't use MI_CLEARWINDOW(mi), since we may + only be resizing and then we won't all those special effects. */ + XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + /* Only put things here that won't interrupt the programme during a window resize */ - sp = &juggles[MI_SCREEN(mi)]; - /* Use MIN so that users can resize in interesting ways, eg narrow windows for tall patterns, etc */ sp->scale = MIN(MI_HEIGHT(mi)/480.0, MI_WIDTH(mi)/160.0); - if(describe && mode_font == None) { /* Check to see if there's room to describe patterns. */ - mode_font = XQueryFont(MI_DISPLAY(mi), XGContextFromGC(MI_GC(mi))); + if(describe && !sp->mode_font) { /* Check to see if there's room to describe patterns. */ + sp->mode_font = XQueryFont(MI_DISPLAY(mi), XGContextFromGC(MI_GC(mi))); } } -void -draw_juggle(ModeInfo * mi) +ENTRYPOINT void +reshape_juggle (ModeInfo * mi, int width, int height) +{ + init_juggle(mi); +} + +ENTRYPOINT void +draw_juggle (ModeInfo * mi) { Trajectory *traj = NULL; Object *o = NULL; @@ -2646,6 +2640,13 @@ draw_juggle(ModeInfo * mi) MI_IS_DRAWN(mi) = True; +#ifdef HAVE_COCOA + /* Don't worry about flicker, trust Quartz's double-buffering. + This is a fast fix for the pixel-turds I can't track down... + */ + XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); +#endif + /* Update timer */ if (real) { struct timeval tv; @@ -2778,8 +2779,13 @@ draw_juggle(ModeInfo * mi) if(pattern != NULL && strcmp(sp->pattern, pattern) != 0 ) { /* Erase old name */ XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); +# if 0 XDrawString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), 0, 20, sp->pattern, strlen(sp->pattern)); +# else + XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + 0, 0, MI_WIDTH(mi), 25); +# endif free(sp->pattern); sp->pattern = strdup(pattern); @@ -2788,12 +2794,12 @@ draw_juggle(ModeInfo * mi) MI_SCREEN(mi), sp->pattern); } } - if(mode_font != None && - XTextWidth(mode_font, sp->pattern, strlen(sp->pattern)) < MI_WIDTH(mi)) { + if(sp->mode_font != None && + XTextWidth(sp->mode_font, sp->pattern, strlen(sp->pattern)) < MI_WIDTH(mi)) { /* Redraw once a cycle, in case it's obscured or it changed */ XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); - XDrawString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), - 0, 20, sp->pattern, strlen(sp->pattern)); + XDrawImageString(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + 0, 20, sp->pattern, strlen(sp->pattern)); } #ifdef MEMTEST @@ -2809,4 +2815,6 @@ draw_juggle(ModeInfo * mi) } } +XSCREENSAVER_MODULE ("Juggle", juggle) + #endif /* MODE_juggle */