]> code.ossystems Code Review - openembedded-core.git/commitdiff
pong-clock: Add
authorRichard Purdie <richard@openedhand.com>
Thu, 5 Jul 2007 21:38:42 +0000 (21:38 +0000)
committerRichard Purdie <richard@openedhand.com>
Thu, 5 Jul 2007 21:38:42 +0000 (21:38 +0000)
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@2119 311d38ba-8fff-0310-9ca6-ca027cbcb966

meta/packages/pong-clock/pong-clock/pong-clock-no-flicker.c [new file with mode: 0644]
meta/packages/pong-clock/pong-clock_1.0.bb [new file with mode: 0644]

diff --git a/meta/packages/pong-clock/pong-clock/pong-clock-no-flicker.c b/meta/packages/pong-clock/pong-clock/pong-clock-no-flicker.c
new file mode 100644 (file)
index 0000000..41cebc5
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Pong Clock - A clock that plays pong. 
+ *             See http://mocoloco.com/archives/001766.php for the inspiration.
+ *
+ * Copyright (C) 2005 Matthew Allum
+ *
+ * Author: Matthew Allum mallum@openedhand.com
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+/* Tweak values for different hw setups */
+
+#define FPS          50
+#define RESX         40
+#define RESY         40
+#define TO_MISS_SECS 55
+#define BALLDX       16
+#define BALLDY       4
+
+
+typedef struct PongClock
+{
+  Display *xdpy;
+  int      xscreen;
+  Window   xwin, xwin_root;
+  Pixmap   backbuffer;
+  GC       xgc;
+  int      xwin_width, xwin_height;
+  int      pixelw, pixelh;
+
+  int      ball_x, ball_y, ball_dx, ball_dy;
+  int      bata_y, batb_y;
+  Bool     bata_to_miss, batb_to_miss;
+
+} 
+PongClock;
+
+void
+get_time(int *hour, int *min, int *sec)
+{
+  struct timeval   tv;
+  struct tm       *localTime = NULL; 
+  time_t           actualTime;
+
+  gettimeofday(&tv, 0);
+  actualTime = tv.tv_sec;
+  localTime = localtime(&actualTime);
+
+  if (hour)
+    *hour = localTime->tm_hour;
+  
+  if (min)
+    *min  = localTime->tm_min;
+
+  if (sec)
+    *sec  = localTime->tm_sec;
+}
+
+void
+draw_rect (PongClock *pong_clock, 
+          int        x,
+          int        y,
+          int        width,
+          int        height)
+{
+  XFillRectangle (pong_clock->xdpy,
+                 pong_clock->backbuffer,
+                 pong_clock->xgc,
+                 x * pong_clock->pixelw,
+                 y * pong_clock->pixelh,
+                 width * pong_clock->pixelw,
+                 height * pong_clock->pixelh);
+}
+
+void
+draw_field (PongClock *pong_clock)
+{
+  int i;
+
+  draw_rect (pong_clock, 0, 0, RESX+1, 1);  
+  draw_rect (pong_clock, 0, RESY-1, RESX+1, 1);  
+
+  for (i=0; i < RESY/2; i++)
+    draw_rect (pong_clock, (RESX/2)-1, i*2, 2, 1);  
+}
+
+void
+draw_digit (PongClock *pong_clock, 
+           int        x,
+           int        y,
+           int        digit)
+{
+  int digits[] = { 0x1f8c63f, 0x1f21086, 0x1f0fe1f, 0x1f87e1f, 0x1087e31,
+                  0x1f87c3f, 0x1f8fc3f, 0x84421f,  0x1f8fe3f, 0x1087e3f };
+
+  XRectangle rects[5*5];
+  int i,j,k;
+
+  i = 0;
+
+  for (k=0; k<5; k++) 
+    for (j=0; j<5; j++)        
+      if (digits[digit] & (1 << ((k*5)+j)))
+       {
+         rects[i].x      = (x + j) * pong_clock->pixelw; 
+         rects[i].y      = (y + k) * pong_clock->pixelh; 
+         rects[i].width  = pong_clock->pixelw;
+         rects[i].height = pong_clock->pixelh;  
+         i++;
+       }
+
+  XFillRectangles (pong_clock->xdpy,
+                  pong_clock->backbuffer,
+                  pong_clock->xgc,
+                  rects, i);
+} 
+
+void
+draw_time (PongClock *pong_clock)
+{
+  int hour, min;
+
+  get_time(&hour, &min, NULL);
+
+  draw_digit (pong_clock, 
+             (RESX/2) - 14,
+             5,
+             hour / 10 );
+
+  draw_digit (pong_clock, 
+             (RESX/2) - 8,
+             5,
+             hour % 10 );
+
+  draw_digit (pong_clock, 
+             (RESX/2) + 3,
+             5,
+             min / 10 );
+
+  draw_digit (pong_clock, 
+             (RESX/2) + 9,
+             5,
+             min % 10 );
+}
+
+void
+draw_bat_and_ball (PongClock *pong_clock)
+{
+  /* ball */
+
+  XFillRectangle (pong_clock->xdpy,
+                 pong_clock->backbuffer,
+                 pong_clock->xgc,
+                 pong_clock->ball_x,
+                 pong_clock->ball_y,
+                 pong_clock->pixelw,
+                 pong_clock->pixelh);
+
+  /* bat a */
+
+  XFillRectangle (pong_clock->xdpy,
+                 pong_clock->backbuffer,
+                 pong_clock->xgc,
+                 0,
+                 pong_clock->bata_y - (2 * pong_clock->pixelh),
+                 pong_clock->pixelw,
+                 pong_clock->pixelh * 5);
+
+  /* bat b */
+
+  XFillRectangle (pong_clock->xdpy,
+                 pong_clock->backbuffer,
+                 pong_clock->xgc,
+                 (pong_clock->xwin_width - pong_clock->pixelw),
+                 pong_clock->batb_y - (2 * pong_clock->pixelh),
+                 pong_clock->pixelw,
+                 pong_clock->pixelh * 5);
+
+}
+
+void
+update_state (PongClock *pong_clock)
+{
+  int sec, min, hour;
+
+  get_time(&hour, &min, &sec);
+
+  /* Check ball is on field and no ones dues to miss a shot.
+  */
+  if ( (pong_clock->ball_x < 0 && !pong_clock->bata_to_miss) 
+      || (pong_clock->ball_x > (pong_clock->xwin_width - pong_clock->pixelw)
+         && !pong_clock->batb_to_miss) )
+    pong_clock->ball_dx *= -1;
+
+  if ((pong_clock->ball_y < pong_clock->pixelh)
+      || pong_clock->ball_y > (pong_clock->xwin_height - (2*pong_clock->pixelh)))
+    pong_clock->ball_dy *= -1; 
+
+  pong_clock->ball_x += pong_clock->ball_dx;
+  pong_clock->ball_y += pong_clock->ball_dy;
+
+  /* Set up someone to miss if we getting close to an hour or min. 
+   */
+  if (sec > TO_MISS_SECS)
+    {
+      if (min == 59)
+       pong_clock->batb_to_miss = True;        
+      else
+       pong_clock->bata_to_miss = True;
+    }
+  else
+    {
+      /* Reset the game */
+      if (pong_clock->bata_to_miss)
+       {
+         pong_clock->bata_to_miss = False;
+         pong_clock->ball_y = pong_clock->bata_y; 
+         pong_clock->ball_x = pong_clock->pixelw; 
+         pong_clock->ball_dx *= -1;
+       }
+
+      if (pong_clock->batb_to_miss)
+       {
+         pong_clock->batb_to_miss = False;
+         pong_clock->ball_y = pong_clock->batb_y; 
+         pong_clock->ball_x = pong_clock->xwin_width - pong_clock->pixelw;
+         pong_clock->ball_dx *= -1; 
+       }
+    }
+
+  /* Keep bats on field and only move in not setup to miss */
+  if (pong_clock->ball_y >= (3*pong_clock->pixelh)
+      && pong_clock->ball_y <=  (pong_clock->xwin_height - (5*pong_clock->pixelh)))
+  {
+    if (!pong_clock->batb_to_miss) 
+      pong_clock->batb_y = pong_clock->ball_y;
+
+    if (!pong_clock->bata_to_miss)
+      pong_clock->bata_y = pong_clock->ball_y;
+  }
+}
+
+void
+draw_frame (PongClock *pong_clock)
+{
+  update_state (pong_clock);
+
+  /* Clear playfield */
+  XSetForeground (pong_clock->xdpy,
+                 pong_clock->xgc,
+                 BlackPixel(pong_clock->xdpy, 
+                            pong_clock->xscreen));
+
+  XFillRectangle (pong_clock->xdpy,
+                 pong_clock->backbuffer,
+                 pong_clock->xgc,
+                 0, 0,
+                 pong_clock->xwin_width, 
+                 pong_clock->xwin_height);
+
+  XSetForeground (pong_clock->xdpy,
+                 pong_clock->xgc,
+                 WhitePixel(pong_clock->xdpy, 
+                            pong_clock->xscreen));
+
+  draw_field (pong_clock);
+
+  draw_time (pong_clock);
+
+  draw_bat_and_ball (pong_clock);
+
+  /* flip 'backbuffer' */
+  XSetWindowBackgroundPixmap (pong_clock->xdpy, 
+                             pong_clock->xwin,
+                             pong_clock->backbuffer);
+  XClearWindow(pong_clock->xdpy, pong_clock->xwin);
+
+  XSync(pong_clock->xdpy, False);
+}
+
+int
+main (int argc, char **argv)
+{
+  XGCValues  gcv;
+  Atom       atoms_WINDOW_STATE, atoms_WINDOW_STATE_FULLSCREEN;
+  PongClock *pong_clock;
+
+  pong_clock = malloc(sizeof(PongClock));
+  memset(pong_clock, 0, sizeof(PongClock));
+
+  if ((pong_clock->xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
+    fprintf(stderr, "Cannot connect to X server on display %s.",
+           getenv("DISPLAY"));
+    exit(-1);
+  }
+
+  pong_clock->xscreen     = DefaultScreen(pong_clock->xdpy);
+  pong_clock->xwin_root   = DefaultRootWindow(pong_clock->xdpy);
+  pong_clock->xwin_width  = DisplayWidth(pong_clock->xdpy, 
+                                        pong_clock->xscreen);
+  pong_clock->xwin_height = DisplayHeight(pong_clock->xdpy, 
+                                         pong_clock->xscreen);
+
+  pong_clock->pixelw  = pong_clock->xwin_width  / RESX;
+  pong_clock->pixelh  = pong_clock->xwin_height / RESY;
+
+  pong_clock->ball_x = 0; 
+  pong_clock->ball_y = pong_clock->xwin_height / 2; 
+
+  pong_clock->ball_dx = BALLDX; 
+  pong_clock->ball_dy = BALLDY; 
+
+  pong_clock->batb_y = pong_clock->bata_y = pong_clock->ball_y;
+
+  gcv.background = BlackPixel(pong_clock->xdpy, 
+                             pong_clock->xscreen);
+  gcv.foreground = WhitePixel(pong_clock->xdpy, 
+                             pong_clock->xscreen);
+  gcv.graphics_exposures = False;
+
+  pong_clock->xgc = XCreateGC (pong_clock->xdpy, pong_clock->xwin_root, 
+                              GCForeground|GCBackground|GCGraphicsExposures,
+                              &gcv);
+
+  atoms_WINDOW_STATE
+    = XInternAtom(pong_clock->xdpy, "_NET_WM_STATE",False);
+  atoms_WINDOW_STATE_FULLSCREEN
+    = XInternAtom(pong_clock->xdpy, "_NET_WM_STATE_FULLSCREEN",False);
+
+  pong_clock->xwin = XCreateSimpleWindow(pong_clock->xdpy, 
+                                        pong_clock->xwin_root, 
+                                        0, 0,
+                                        pong_clock->xwin_width, 
+                                        pong_clock->xwin_height, 
+                                        0,
+                                        WhitePixel(pong_clock->xdpy, 
+                                                   pong_clock->xscreen),
+                                        BlackPixel(pong_clock->xdpy, 
+                                                   pong_clock->xscreen));
+
+  pong_clock->backbuffer = XCreatePixmap(pong_clock->xdpy, 
+                                        pong_clock->xwin_root,
+                                        pong_clock->xwin_width, 
+                                        pong_clock->xwin_height, 
+                                        DefaultDepth(pong_clock->xdpy, 
+                                                     pong_clock->xscreen));
+
+  XSelectInput(pong_clock->xdpy, pong_clock->xwin, KeyPressMask);
+  
+
+  /* Set the hints for fullscreen */
+  XChangeProperty(pong_clock->xdpy, 
+                 pong_clock->xwin, 
+                 atoms_WINDOW_STATE, 
+                 XA_ATOM, 
+                 32, 
+                 PropModeReplace, 
+                 (unsigned char *) &atoms_WINDOW_STATE_FULLSCREEN, 1);
+
+  XMapWindow(pong_clock->xdpy, pong_clock->xwin);
+  
+  while (True) 
+    {
+      struct timeval timeout;
+      XEvent         xev;
+
+      timeout.tv_sec  = 0;
+      timeout.tv_usec = 1000000 / FPS; 
+      select (0, NULL, NULL, NULL, &timeout);
+
+      draw_frame (pong_clock);
+
+      XFlush(pong_clock->xdpy);
+
+      if (XPending(pong_clock->xdpy))
+       {
+         if (XCheckMaskEvent(pong_clock->xdpy, 
+                             KeyPressMask,
+                             &xev))
+           exit(-1);
+       }
+    }
+}
diff --git a/meta/packages/pong-clock/pong-clock_1.0.bb b/meta/packages/pong-clock/pong-clock_1.0.bb
new file mode 100644 (file)
index 0000000..3bbab7d
--- /dev/null
@@ -0,0 +1,15 @@
+DESCRIPTION = "A clock combined with a game of pong"
+LICENCE = "GPLv2"
+
+SRC_URI = "file://pong-clock-no-flicker.c"
+
+S = "${WORKDIR}"
+
+do_compile () {
+       ${CC} -o pong-clock pong-clock-no-flicker.c `pkg-config --cflags --libs x11 xau xdmcp`
+}
+
+do_install () {
+       install -d ${D}${bindir}
+       install -m 0755 pong-clock ${D}${bindir}
+}
\ No newline at end of file