X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fpong.c;h=021fe1d716c1aff13b1500b851a502572e258a8c;hp=4941ae2803433ca00835dda526f719f970184cc0;hb=488f2fa8fbdbc77e91a70da2962d73af49e6cace;hpb=c8c6deae79b408cffbc88043c766b3bc12cf0f13 diff --git a/hacks/pong.c b/hacks/pong.c index 4941ae28..021fe1d7 100644 --- a/hacks/pong.c +++ b/hacks/pong.c @@ -12,6 +12,16 @@ * Also added gradual acceleration of the ball, shrinking of paddles, and * scorekeeping. * + * Modified by Gereon Steffens to add -clock and -noise + * options. See http://www.burovormkrijgers.nl (ugly flash site, + * navigate to Portfolio/Browse/Misc/Pong Clock) for the hardware implementation + * that gave me the idea. In clock mode, the score reflects the current time, and + * the paddles simply stop moving when it's time for the other side to score. This + * means that the display is only updated a few seconds *after* the minute actually + * changes, but I think this fuzzyness fits well with the display, and since we're + * not displaying seconds, who cares. While I was at it, I added a -noise option + * to control the noisyness of the display. + * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that @@ -65,12 +75,15 @@ struct state { Display *dpy; Window window; + int clock; + Paddle l_paddle; Paddle r_paddle; Ball ball; int bx,by; int m_unit; int paddle_rate; + double noise; analogtv *tv; analogtv_input *inp; @@ -100,6 +113,25 @@ hit_top_bottom(struct state *st) st->by=-st->by; } +static void +reset_score(struct state * st) +{ + if (st->clock) + { + /* init score to current time */ + time_t now = time(0); + struct tm* now_tm = localtime(&now); + + st->r_paddle.score = now_tm->tm_hour; + st->l_paddle.score = now_tm->tm_min; + } + else + { + st->r_paddle.score = 0; + st->l_paddle.score = 0; + } +} + static void new_game(struct state *st) { @@ -119,8 +151,7 @@ new_game(struct state *st) st->r_paddle.wait = 0; st->r_paddle.lock = 0; st->paddle_rate = st->m_unit-1; - st->r_paddle.score = 0; - st->l_paddle.score = 0; + reset_score(st); st->l_paddle.h = PONG_H/4; st->r_paddle.h = PONG_H/4; @@ -167,11 +198,18 @@ hit_paddle(struct state *st) } else { - st->r_paddle.score++; - if (st->r_paddle.score >=10) - new_game(st); - else - start_game(st); + if (st->clock) + { + reset_score(st); + } + else + { + st->r_paddle.score++; + if (st->r_paddle.score >=10) + new_game(st); + else + start_game(st); + } } } @@ -189,11 +227,18 @@ hit_paddle(struct state *st) } else { - st->l_paddle.score++; - if (st->l_paddle.score >= 10) - new_game(st); + if (st->clock) + { + reset_score(st); + } else - start_game(st); + { + st->l_paddle.score++; + if (st->l_paddle.score >= 10) + new_game(st); + else + start_game(st); + } } } } @@ -202,89 +247,230 @@ static void * pong_init (Display *dpy, Window window) { struct state *st = (struct state *) calloc (1, sizeof(*st)); + + int i; + struct { + int w, h; + char *s[10]; + } fonts[2] = { + { /* regular pong font */ + /* If you think we haven't learned anything since the early 70s, + look at this font for a while */ + 4, 6, + { + "****" + "* *" + "* *" + "* *" + "* *" + "****", + + " *" + " *" + " *" + " *" + " *" + " *", + + "****" + " *" + "****" + "* " + "* " + "****", + + "****" + " *" + "****" + " *" + " *" + "****", + + "* *" + "* *" + "****" + " *" + " *" + " *", + + "****" + "* " + "****" + " *" + " *" + "****", + + "****" + "* " + "****" + "* *" + "* *" + "****", + + "****" + " *" + " *" + " *" + " *" + " *", + + "****" + "* *" + "****" + "* *" + "* *" + "****", + + "****" + "* *" + "****" + " *" + " *" + " *" + } + }, + { /* pong clock font - hand-crafted double size looks better */ + 8, 12, + { + "####### " + "####### " + "## ## " + "## ## " + "## ## " + "## ## " + "## ## " + "## ## " + "## ## " + "####### " + "####### ", + + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## ", + + "####### " + "####### " + " ## " + " ## " + "####### " + "####### " + "## " + "## " + "## " + "####### " + "####### ", + + "####### " + "####### " + " ## " + " ## " + "####### " + "####### " + " ## " + " ## " + " ## " + "####### " + "####### ", + + "## ## " + "## ## " + "## ## " + "## ## " + "####### " + "####### " + " ## " + " ## " + " ## " + " ## " + " ## ", + + "####### " + "####### " + "## " + "## " + "####### " + "####### " + " ## " + " ## " + " ## " + "####### " + "####### ", + + "####### " + "####### " + "## " + "## " + "####### " + "####### " + "## ## " + "## ## " + "## ## " + "####### " + "####### ", + + "####### " + "####### " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## " + " ## ", + + "####### " + "####### " + "## ## " + "## ## " + "####### " + "####### " + "## ## " + "## ## " + "## ## " + "####### " + "####### ", + + "####### " + "####### " + "## ## " + "## ## " + "####### " + "####### " + " ## " + " ## " + " ## " + "####### " + "####### " + + } + } + }; + st->dpy = dpy; st->window = window; st->tv=analogtv_allocate(st->dpy, st->window); analogtv_set_defaults(st->tv, ""); - analogtv_make_font(st->dpy, st->window, &st->score_font, - 4, 6, NULL ); - - /* If you think we haven't learned anything since the early 70s, - look at this font for a while */ - analogtv_font_set_char(&st->score_font, '0', - "****" - "* *" - "* *" - "* *" - "* *" - "****"); - analogtv_font_set_char(&st->score_font, '1', - " *" - " *" - " *" - " *" - " *" - " *"); - analogtv_font_set_char(&st->score_font, '2', - "****" - " *" - "****" - "* " - "* " - "****"); - analogtv_font_set_char(&st->score_font, '3', - "****" - " *" - "****" - " *" - " *" - "****"); - analogtv_font_set_char(&st->score_font, '4', - "* *" - "* *" - "****" - " *" - " *" - " *"); - analogtv_font_set_char(&st->score_font, '5', - "****" - "* " - "****" - " *" - " *" - "****"); - analogtv_font_set_char(&st->score_font, '6', - "****" - "* " - "****" - "* *" - "* *" - "****"); - analogtv_font_set_char(&st->score_font, '7', - "****" - " *" - " *" - " *" - " *" - " *"); - analogtv_font_set_char(&st->score_font, '8', - "****" - "* *" - "****" - "* *" - "* *" - "****"); - analogtv_font_set_char(&st->score_font, '9', - "****" - "* *" - "****" - " *" - " *" - " *"); - - st->score_font.y_mult *= 2; - st->score_font.x_mult *= 2; + + st->clock = get_boolean_resource(st->dpy, "clock", "Boolean"); + + analogtv_make_font(st->dpy, st->window, &st->score_font, + fonts[st->clock].w, fonts[st->clock].h, NULL); + + for (i=0; i<10; ++i) + { + analogtv_font_set_char(&st->score_font, '0'+i, fonts[st->clock].s[i]); + } #ifdef OUTPUT_POS printf("screen(%d,%d,%d,%d)\n",0,0,PONG_W,PONG_H); @@ -323,6 +509,16 @@ pong_init (Display *dpy, Window window) st->ball.h = 8; st->m_unit = get_integer_resource (st->dpy, "speed", "Integer"); + st->noise = get_float_resource(st->dpy, "noise", "Float"); + st->clock = get_boolean_resource(st->dpy, "clock", "Boolean"); + + if (!st->clock) + { + st->score_font.y_mult *= 2; + st->score_font.x_mult *= 2; + } + + reset_score(st); start_game(st); @@ -442,17 +638,20 @@ paint_score(struct state *st) { char buf[256]; + char* fmt = (st->clock ? "%02d" : "%d"); + analogtv_draw_solid(st->inp, ANALOGTV_VIS_START, ANALOGTV_VIS_END, ANALOGTV_TOP, ANALOGTV_TOP + 10+ st->score_font.char_h * st->score_font.y_mult, st->field_ntsc); - sprintf(buf, "%d",st->r_paddle.score%256); + + sprintf(buf, fmt ,st->r_paddle.score%256); analogtv_draw_string(st->inp, &st->score_font, buf, ANALOGTV_VIS_START + 130, ANALOGTV_TOP + 8, st->score_ntsc); - sprintf(buf, "%d",st->l_paddle.score%256); + sprintf(buf, fmt, st->l_paddle.score%256); analogtv_draw_string(st->inp, &st->score_font, buf, ANALOGTV_VIS_END - 200, ANALOGTV_TOP + 8, st->score_ntsc); @@ -479,13 +678,34 @@ static unsigned long pong_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; + + if (st->clock) + { + time_t now = time(0); + struct tm* tm_now = localtime(&now); + + if (st->r_paddle.score != tm_now->tm_hour) + { + /* l paddle must score */ + st->r_paddle.wait = 1; + } + else if (st->l_paddle.score != tm_now->tm_min) + { + /* r paddle must score */ + st->l_paddle.wait = 1; + } + } erase_ball(st); st->ball.x += st->bx; st->ball.y += st->by; - if ((random()%40)==0) { - if (st->bx>0) st->bx++; else st->bx--; + if (!st->clock) + { + /* in non-clock mode, occasionally increase ball speed */ + if ((random()%40)==0) { + if (st->bx>0) st->bx++; else st->bx--; + } } if (!st->r_paddle.wait) @@ -517,7 +737,7 @@ pong_draw (Display *dpy, Window window, void *closure) } if (1) paint_ball(st); - analogtv_init_signal(st->tv, 0.04); + analogtv_init_signal(st->tv, st->noise); analogtv_reception_update(&st->reception); analogtv_add_signal(st->tv, &st->reception); analogtv_draw(st->tv); @@ -531,6 +751,8 @@ static const char *pong_defaults [] = { ".background: black", ".foreground: white", "*speed: 6", + "*noise: 0.04", + "*clock: false", ANALOGTV_DEFAULTS "*TVContrast: 150", 0 @@ -538,6 +760,8 @@ static const char *pong_defaults [] = { static XrmOptionDescRec pong_options [] = { { "-speed", ".speed", XrmoptionSepArg, 0 }, + { "-noise", ".noise", XrmoptionSepArg, 0 }, + { "-clock", ".clock", XrmoptionNoArg, "true" }, ANALOGTV_OPTIONS { 0, 0, 0, 0 } }; @@ -564,4 +788,4 @@ pong_free (Display *dpy, Window window, void *closure) free (st); } -XSCREENSAVER_MODULE ("Pong", pong) +XSCREENSAVER_MODULE ("pong", pong)