From http://www.jwz.org/xscreensaver/xscreensaver-5.39.tar.gz
[xscreensaver] / hacks / pacman.c
index 4eda4590c4e9a4354806b6390fbd03b81aa69d03..f7282fdd0d4601ec471cdccc5f21126386fd47e1 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* pacman --- Mr. Pacman and his ghost friends */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)pacman.c     5.00 2000/11/01 xlockmore";
-
 #endif
 
 /*-
@@ -48,21 +47,18 @@ static const char sccsid[] = "@(#)pacman.c  5.00 2000/11/01 xlockmore";
 
 #ifdef STANDALONE
 #      define MODE_pacman
-#      define PROGCLASS "Pacman"
-#      define HACK_INIT init_pacman
-#      define HACK_DRAW draw_pacman
-#      define pacman_opts xlockmore_opts
-#      define DEFAULTS "*delay: 10000 \n" \
-                                       "*size: 0 \n" \
-                                       "*ncolors: 6 \n" \
+#      define DEFAULTS "*delay:   10000 \n" \
+                                       "*size:    0     \n" \
+                                       "*ncolors: 6     \n" \
+                                       "*fpsTop: true   \n" \
+                                       "*fpsSolid: true \n" \
 
 #      define UNIFORM_COLORS
 #      define BRIGHT_COLORS
-
-#include <assert.h>
-#include <string.h>
-
+#      define release_pacman 0
+#   define pacman_handle_event 0
 #      include "xlockmore.h"   /* in xscreensaver distribution */
+#   include <assert.h>
 #else /* STANDALONE */
 #      include "xlock.h"       /* in xlockmore distribution */
 #endif /* STANDALONE */
@@ -72,65 +68,10 @@ static const char sccsid[] = "@(#)pacman.c  5.00 2000/11/01 xlockmore";
 #include "pacman.h"
 #include "pacman_ai.h"
 #include "pacman_level.h"
-
-#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM)
-#define USE_PIXMAP
-#include "xpm-pixmap.h"
-#else
-#if defined(USE_PIXMAP)
-#undef USE_PIXMAP
-#endif
-#endif
-
-#if defined(USE_PIXMAP)
-# include "images/pacman/ghost-u1.xpm"
-# include "images/pacman/ghost-u2.xpm"
-# include "images/pacman/ghost-r1.xpm"
-# include "images/pacman/ghost-r2.xpm"
-# include "images/pacman/ghost-l1.xpm"
-# include "images/pacman/ghost-l2.xpm"
-# include "images/pacman/ghost-d1.xpm"
-# include "images/pacman/ghost-d2.xpm"
-/* Used to clean up the dust left by wag. */
-# include "images/pacman/ghost-mask.xpm"
-# include "images/pacman/pacman-u1.xpm"
-# include "images/pacman/pacman-u2.xpm"
-# include "images/pacman/pacman-r1.xpm"
-# include "images/pacman/pacman-r2.xpm"
-# include "images/pacman/pacman-l1.xpm"
-# include "images/pacman/pacman-l2.xpm"
-# include "images/pacman/pacman-d1.xpm"
-# include "images/pacman/pacman-d2.xpm"
-# include "images/pacman/pacman-0.xpm"
-# include "images/pacman/ghost-s1.xpm"
-# include "images/pacman/ghost-s2.xpm"
-# include "images/pacman/ghost-sf1.xpm"
-# include "images/pacman/ghost-sf2.xpm"
-# include "images/pacman/eyes-l.xpm"
-# include "images/pacman/eyes-r.xpm"
-# include "images/pacman/eyes-u.xpm"
-# include "images/pacman/eyes-d.xpm"
-# include "images/pacman/pacman-ds1.xpm"
-# include "images/pacman/pacman-ds2.xpm"
-# include "images/pacman/pacman-ds3.xpm"
-# include "images/pacman/pacman-ds4.xpm"
-# include "images/pacman/pacman-ds5.xpm"
-# include "images/pacman/pacman-ds6.xpm"
-# include "images/pacman/pacman-ds7.xpm"
-# include "images/pacman/pacman-ds8.xpm"
-#endif
-
-static const struct
-{
-    int dx, dy;
-} dirvecs[DIRVECS] = { {
--1, 0}, {
-0, 1}, {
-1, 0}, {
-0, -1}};
+#include "images/gen/pacman_png.h"
 
 #ifdef DISABLE_INTERACTIVE
-ModeSpecOpt pacman_opts = {
+ENTRYPOINT ModeSpecOpt pacman_opts = {
     0,
     (XrmOptionDescRec *) NULL,
     0,
@@ -144,14 +85,14 @@ static XrmOptionDescRec opts[] = {
 };
 
 static argtype vars[] = {
-    {&trackmouse, "trackmouse", "TrackMouse", DEF_TRACKMOUSE, t_Bool}
+    {&pacman_trackmouse, "trackmouse", "TrackMouse", DEF_TRACKMOUSE, t_Bool}
 };
 
 static OptionStruct desc[] = {
     {"-/+trackmouse", "turn on/off the tracking of the mouse"}
 };
 
-ModeSpecOpt pacman_opts =
+ENTRYPOINT ModeSpecOpt pacman_opts =
     { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars,
 desc };
 #endif
@@ -161,27 +102,28 @@ ModStruct pacman_description = {
     "pacman",                   /* *cmdline_arg; */
     "init_pacman",              /* *init_name; */
     "draw_pacman",              /* *callback_name; */
-    "release_pacman",           /* *release_name; */
+    (char *) NULL,              /* *release_name; */
     "refresh_pacman",           /* *refresh_name; */
     "change_pacman",            /* *change_name; */
-    (char *) NULL,              /* *unused_name; */
+    "free_pacman",              /* *free_name; */
     &pacman_opts,               /* *msopts */
     10000, 4, 1, 0, 64, 1.0, "", "Shows Pacman(tm)", 0, NULL
 };
 
 #endif
 
-Bool trackmouse;
-pacmangamestruct *pacmangames = (pacmangamestruct *) NULL;
-
+Bool pacman_trackmouse;
+pacmangamestruct *pacman_games = (pacmangamestruct *) NULL;
 
 static void repopulate (ModeInfo * mi);
 static void drawlevel (ModeInfo * mi);
 
 
-static void
-free_pacman (Display * display, pacmangamestruct * pp)
+ENTRYPOINT void
+free_pacman (ModeInfo * mi)
 {
+    Display * display = MI_DISPLAY (mi);
+    pacmangamestruct * pp = &pacman_games[MI_SCREEN (mi)];
     int dir, mouth, i, j, k;
 
     if (pp->ghosts != NULL) {
@@ -215,10 +157,10 @@ free_pacman (Display * display, pacmangamestruct * pp)
 static void
 reset_level (ModeInfo * mi, int n, int pac_init)
 {
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     unsigned int ghost;
 
-    MI_CLEARWINDOW (mi);
+    XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
     drawlevel (mi);
 
     pp->gamestate = GHOST_DANGER;
@@ -265,9 +207,9 @@ reset_level (ModeInfo * mi, int n, int pac_init)
         pp->ghosts[ghost].delta.y = 0;
         pp->ghosts[ghost].flash_scared = False;
         pp->ghosts[ghost].wait_pos = False;
-        ghost_update (pp, &(pp->ghosts[ghost]));
+        pacman_ghost_update (pp, &(pp->ghosts[ghost]));
     }
-    pac_update (mi, pp, &(pp->pacman));
+    pacman_update (mi, pp, &(pp->pacman));
 }
 
 static int
@@ -290,11 +232,9 @@ check_death (ModeInfo * mi, pacmangamestruct * pp)
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
     unsigned int ghost;
-    int alldead;
 
     if (pp->pacman.aistate == ps_dieing) return;
 
-    alldead = 1;
     for (ghost = 0; ghost < pp->nghosts; ghost++) {
 
         /* The ghost have to be scared before you can kill them */
@@ -320,20 +260,16 @@ check_death (ModeInfo * mi, pacmangamestruct * pp)
             }
             continue;
         }
-        
-        alldead = 0;
     }
-    
-
 }
 
 /* Resets state of ghosts + pacman.  Creates a new level, draws that level. */
 static void
 repopulate (ModeInfo * mi)
 {
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     pp->pacman.deaths = 0;
-    reset_level (mi, createnewlevel (mi), True);
+    reset_level (mi, pacman_createnewlevel (pp), True);
     check_death (mi, pp);
 }
 
@@ -342,7 +278,7 @@ static void
 setwallcolor (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
 
     if (MI_NPIXELS (mi) > 2)
         XSetForeground (display, pp->stippledGC, MI_PIXEL (mi, BLUE));
@@ -355,7 +291,7 @@ static void
 setdotcolor (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
 
     XSetForeground (display, pp->stippledGC, MI_WHITE_PIXEL (mi));
 }
@@ -364,7 +300,7 @@ static void
 cleardotcolor (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
 
     XSetForeground (display, pp->stippledGC, MI_BLACK_PIXEL (mi));
 }
@@ -375,12 +311,12 @@ draw_position (ModeInfo * mi, int x, int y, int color)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     XFontStruct *font = NULL;
     char *f_name = "-*-utopia-*-r-*-*-*-600-*-*-p-*-*-*";
     char *s = NULL;
 
-    font = XLoadQueryFont (display, f_name);
+    font = load_font_retry (display, f_name);
     assert (font != NULL);
 
     s = (char *) malloc (256);
@@ -398,12 +334,12 @@ draw_number (ModeInfo * mi, int x, int y, int num, int color)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     XFontStruct *font = NULL;
     char *f_name = "-*-utopia-*-r-*-*-*-600-*-*-p-*-*-*";
     char *s = NULL;
 
-    font = XLoadQueryFont (display, f_name);
+    font = load_font_retry (display, f_name);
     assert (font != NULL);
 
     s = (char *) malloc (256);
@@ -426,7 +362,7 @@ draw_grid (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     int h = MI_HEIGHT (mi);
     int w = MI_WIDTH (mi);
     int y = 0;
@@ -450,11 +386,11 @@ draw_string (ModeInfo * mi, int x, int y, char *s, int color)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     XFontStruct *font = NULL;
     char *f_name = "-*-utopia-*-r-*-*-*-600-*-*-p-*-*-*";
 
-    font = XLoadQueryFont (display, f_name);
+    font = load_font_retry (display, f_name);
     assert (font != NULL);
 
     assert (s != NULL);
@@ -502,7 +438,7 @@ print_ghost_stats (ModeInfo *mi, ghoststruct *g , int ghost_num)
 static void
 print_pac_stats ( ModeInfo *mi, pacmanstruct *pac )
 {
-    static char last_pac_stat[1024] = "\0";
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     char s[1024];
     sprintf (s, "Pacman, Deaths: %d", pac->deaths );
     switch ( pac->aistate ){
@@ -522,9 +458,9 @@ print_pac_stats ( ModeInfo *mi, pacmanstruct *pac )
         sprintf(s, "%s ps_dieing",s );
         break;
     }
-    draw_string ( mi, 0, 200, last_pac_stat, 0x000000);
+    draw_string ( mi, 0, 200, pp->last_pac_stat, 0x000000);
     draw_string ( mi, 0, 200, s, 0xff0000);
-    strcpy(last_pac_stat, s );
+    strcpy(pp->last_pac_stat, s );
 }
 
 #endif
@@ -536,7 +472,7 @@ print_pac_stats ( ModeInfo *mi, pacmanstruct *pac )
 static void
 dot_rc_to_pixel (ModeInfo * mi, int *x, int *y)
 {
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     *x = (pp->xs * *x) +
         (pp->xs / 2) - (pp->xs > 32 ? (pp->xs / 16) : 1) + pp->xb;
     *y = (pp->ys * *y) +
@@ -549,9 +485,9 @@ dot_rc_to_pixel (ModeInfo * mi, int *x, int *y)
 static void
 dot_width_height (ModeInfo *mi, int *w, int *h)
 {
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     if (pp->xs > 32){
-        *w = *h = (pp->xs / 32 );
+        *w = *h = (pp->xs / 16 );
     }else {
         *w = *h = 1;
     }
@@ -623,7 +559,9 @@ drawlevelblock (ModeInfo * mi, pacmangamestruct * pp,
     if (pp->ys % 2 == 1)
         dy = -1;
 
+#ifndef HAVE_JWXYZ
     XSetFillStyle (display, pp->stippledGC, FillSolid);
+#endif /* !HAVE_JWXYZ */
     XSetLineAttributes (display, pp->stippledGC, pp->wallwidth,
                         LineSolid, CapRound, JoinMiter);
 
@@ -731,7 +669,7 @@ drawlevelblock (ModeInfo * mi, pacmangamestruct * pp,
 static void
 drawlevel (ModeInfo * mi)
 {
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     unsigned int x, y;
 
     for (y = 0; y < LEVHEIGHT; y++)
@@ -756,22 +694,16 @@ drawlevel (ModeInfo * mi)
 
 
 /* Draws the pacman sprite, removing the previous location. */
-#if defined(USE_PIXMAP)
 
 static void
 draw_pacman_sprite (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     unsigned int dir = 0;
     int old_mask_dir = 0;
     int old_mask_mouth = 0;
-    static int mouth = 0;
-    static int mouth_delay = 0;
-    static int open_mouth = 0;
-    static int death_frame = 0;
-    static int death_delay = 0;
     Pixmap old_mask, new_mask;
     Pixmap pacman;
 
@@ -792,42 +724,42 @@ draw_pacman_sprite (ModeInfo * mi)
     dir = (ABS (pp->pacman.cfactor) * (2 - pp->pacman.cfactor) +
            ABS (pp->pacman.rfactor) * (1 + pp->pacman.rfactor)) % 4;
 
-    if (mouth_delay == MAX_MOUTH_DELAY) {
-        if (mouth == (MAXMOUTH - 1) || mouth == 0) {
-            open_mouth = !open_mouth;
+    if (pp->pm_mouth_delay == MAX_MOUTH_DELAY) {
+        if (pp->pm_mouth == (MAXMOUTH - 1) || pp->pm_mouth == 0) {
+            pp->pm_open_mouth = !pp->pm_open_mouth;
         }
-        open_mouth ? mouth++ : mouth--;
-        mouth_delay = 0;
+        pp->pm_open_mouth ? pp->pm_mouth++ : pp->pm_mouth--;
+        pp->pm_mouth_delay = 0;
     }
     else {
-        mouth_delay++;
+        pp->pm_mouth_delay++;
     }
     
     if (pp->pacman.aistate == ps_dieing){
-        if (death_frame >= PAC_DEATH_FRAMES) {
+        if (pp->pm_death_frame >= PAC_DEATH_FRAMES) {
             pp->pacman.aistate = ps_eating;
-            death_frame = 0;
-            death_delay = 0;
+            pp->pm_death_frame = 0;
+            pp->pm_death_delay = 0;
             reset_level (mi, 0, False);
             return;
         }
         else {
             old_mask   = pp->pacmanMask[0][0];
             new_mask   = pp->pacmanMask[0][0];
-            pacman     = pp->pacman_ds[death_frame];
-            if (death_delay == MAX_DEATH_DELAY){
-                death_frame++;
-                death_delay = 0;
+            pacman     = pp->pacman_ds[pp->pm_death_frame];
+            if (pp->pm_death_delay == MAX_DEATH_DELAY){
+                pp->pm_death_frame++;
+                pp->pm_death_delay = 0;
             }
             else{
-                death_delay++;
+                pp->pm_death_delay++;
             }
         }
     }
     else{
         old_mask = pp->pacmanMask[old_mask_dir][old_mask_mouth];
-        new_mask = pp->pacmanMask[dir][mouth];
-        pacman   = pp->pacmanPixmap[dir][mouth];
+        new_mask = pp->pacmanMask[dir][pp->pm_mouth];
+        pacman   = pp->pacmanPixmap[dir][pp->pm_mouth];
     }
 
     XSetForeground (display, pp->stippledGC, MI_BLACK_PIXEL (mi));
@@ -848,8 +780,6 @@ draw_pacman_sprite (ModeInfo * mi)
         pp->pacman.oldcf = pp->pacman.cf;
         pp->pacman.oldrf = pp->pacman.rf;
     }
-    old_mask_dir = dir;
-    old_mask_mouth = mouth;
 }
 
 #if 0
@@ -876,10 +806,8 @@ draw_ghost_sprite (ModeInfo * mi, const unsigned ghost)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
-    static int wag = 0;
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
 #define MAX_WAG_COUNT 50
-    static int wag_count = 0;
     unsigned int dir = 0;
     unsigned int fs  = 0; /*flash scared*/
     Pixmap g_pix; /*ghost pixmap*/
@@ -895,7 +823,7 @@ draw_ghost_sprite (ModeInfo * mi, const unsigned ghost)
     /* Choose the pixmap */
     switch (pp->ghosts[ghost].aistate){
     case hiding:
-        g_pix = pp->s_ghostPixmap[fs][wag];
+        g_pix = pp->s_ghostPixmap[fs][pp->gh_wag];
         break;
     case goingin:
         g_pix = pp->ghostEyes[dir];
@@ -917,7 +845,7 @@ draw_ghost_sprite (ModeInfo * mi, const unsigned ghost)
                 
         break;
     default:
-        g_pix = pp->ghostPixmap[ghost][dir][wag];
+        g_pix = pp->ghostPixmap[ghost][dir][pp->gh_wag];
     }
 
     pp->ghosts[ghost].cf =
@@ -966,151 +894,20 @@ draw_ghost_sprite (ModeInfo * mi, const unsigned ghost)
     if (pp->pacman.aistate != ps_dieing) {
         pp->ghosts[ghost].oldcf = pp->ghosts[ghost].cf;
         pp->ghosts[ghost].oldrf = pp->ghosts[ghost].rf;
-        if (wag_count++ == MAX_WAG_COUNT) {
-            wag = !wag;
-            wag_count = 0;
+        if (pp->gh_wag_count++ == MAX_WAG_COUNT) {
+            pp->gh_wag = !pp->gh_wag;
+            pp->gh_wag_count = 0;
         }
     }
 }
 
-#else /* USE_PIXMAP */
-
-/* Draws the pacman sprite, removing the previous location. */
-static void
-draw_pacman_sprite (ModeInfo * mi)
-{
-    Display *display = MI_DISPLAY (mi);
-    Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
-    unsigned int dir;
-
-    pp->pacman.cf = pp->pacman.col * pp->xs + pp->pacman.delta.x *
-        pp->pacman.cfactor + pp->xb + pp->spritedx;
-    pp->pacman.rf = pp->pacman.row * pp->ys + pp->pacman.delta.y *
-        pp->pacman.rfactor + pp->yb + pp->spritedy;
-
-    dir = (ABS (pp->pacman.cfactor) * (2 - pp->pacman.cfactor) +
-           ABS (pp->pacman.rfactor) * (1 + pp->pacman.rfactor)) % 4;
-
-    XSetForeground (display, pp->stippledGC, MI_BLACK_PIXEL (mi));
-    if (pp->pacman.oldcf != NOWHERE && pp->pacman.oldrf != NOWHERE) {
-#ifdef FLASH
-        XFillRectangle (display, window, pp->stippledGC,
-                        pp->pacman.oldcf, pp->pacman.oldrf,
-                        pp->spritexs, pp->spriteys);
-#else
-        ERASE_IMAGE (display, window, pp->stippledGC,
-                     pp->pacman.cf, pp->pacman.rf,
-                     pp->pacman.oldcf, pp->pacman.oldrf,
-                     pp->spritexs, pp->spriteys);
-#endif
-    }
-
-    XSetTSOrigin (display, pp->stippledGC, pp->pacman.cf, pp->pacman.rf);
-    if (MI_NPIXELS (mi) > 2)
-        XSetForeground (display, pp->stippledGC, MI_PIXEL (mi, YELLOW));
-    else
-        XSetForeground (display, pp->stippledGC, MI_WHITE_PIXEL (mi));
-
-    XSetStipple (display, pp->stippledGC,
-                 pp->pacmanPixmap[dir][pp->pacman.mouthstage]);
-#ifdef FLASH
-    XSetFillStyle (display, pp->stippledGC, FillStippled);
-#else
-    XSetFillStyle (display, pp->stippledGC, FillOpaqueStippled);
-#endif
-    if (pp->xs < 2 || pp->ys < 2)
-        XDrawPoint (display, window, pp->stippledGC,
-                    pp->pacman.cf, pp->pacman.rf);
-    else
-        XFillRectangle (display, window, pp->stippledGC,
-                        pp->pacman.cf, pp->pacman.rf,
-                        pp->spritexs, pp->spriteys);
-    pp->pacman.mouthstage += pp->pacman.mouthdirection;
-    if ((pp->pacman.mouthstage >= MAXMOUTH) || (pp->pacman.mouthstage < 0)) {
-        pp->pacman.mouthdirection *= -1;
-        pp->pacman.mouthstage += pp->pacman.mouthdirection * 2;
-    }
-    pp->pacman.oldcf = pp->pacman.cf;
-    pp->pacman.oldrf = pp->pacman.rf;
-}
-
-/* Draws a ghost sprite, removing the previous sprite and restores the level. */
-static void
-draw_ghost_sprite (ModeInfo * mi, const unsigned ghost)
-{
-    Display *display = MI_DISPLAY (mi);
-    Window window = MI_WINDOW (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
-
-    pp->ghosts[ghost].cf =
-        pp->ghosts[ghost].col * pp->xs + pp->ghosts[ghost].delta.x *
-        pp->ghosts[ghost].cfactor + pp->xb + pp->spritedx;
-    pp->ghosts[ghost].rf =
-        pp->ghosts[ghost].row * pp->ys + pp->ghosts[ghost].delta.y *
-        pp->ghosts[ghost].rfactor + pp->yb + pp->spritedy;
-
-    XSetForeground (display, pp->stippledGC, MI_BLACK_PIXEL (mi));
-    XFillRectangle (display,
-                    window,
-                    pp->stippledGC,
-                    pp->ghosts[ghost].cf,
-                    pp->ghosts[ghost].rf, pp->spritexs, pp->spriteys);
-
-    if (pp->ghosts[ghost].oldcf != NOWHERE ||
-        pp->ghosts[ghost].oldrf != NOWHERE) {
-#ifdef FLASH
-        XFillRectangle (display, window,
-                        pp->stippledGC, pp->ghosts[ghost].oldcf,
-                        pp->ghosts[ghost].oldrf, pp->spritexs, pp->spriteys);
-#else
-        ERASE_IMAGE (display, window, pp->stippledGC,
-                     pp->ghosts[ghost].cf, pp->ghosts[ghost].rf,
-                     pp->ghosts[ghost].oldcf, pp->ghosts[ghost].oldrf,
-                     pp->spritexs, pp->spriteys);
-#endif
-    }
-
-    drawlevelblock (mi, pp,
-                    (unsigned int) pp->ghosts[ghost].col,
-                    (unsigned int) pp->ghosts[ghost].row);
-
-    XSetTSOrigin (display, pp->stippledGC,
-                  pp->ghosts[ghost].cf, pp->ghosts[ghost].rf);
-
-    if (MI_NPIXELS (mi) > 2)
-        XSetForeground (display, pp->stippledGC, MI_PIXEL (mi, GREEN));
-    else
-        XSetForeground (display, pp->stippledGC, MI_WHITE_PIXEL (mi));
-
-    XSetStipple (display, pp->stippledGC, pp->ghostPixmap[0][0][0]);
-
-#ifdef FLASH
-    XSetFillStyle (display, pp->stippledGC, FillStippled);
-#else
-    XSetFillStyle (display, pp->stippledGC, FillOpaqueStippled);
-#endif
-    if (pp->xs < 2 || pp->ys < 2)
-        XDrawPoint (display, window, pp->stippledGC,
-                    pp->ghosts[ghost].cf, pp->ghosts[ghost].rf);
-    else
-        XFillRectangle (display,
-                        window,
-                        pp->stippledGC,
-                        pp->ghosts[ghost].cf,
-                        pp->ghosts[ghost].rf, pp->spritexs, pp->spriteys);
-
-    pp->ghosts[ghost].oldcf = pp->ghosts[ghost].cf;
-    pp->ghosts[ghost].oldrf = pp->ghosts[ghost].rf;
-}
-#endif /* USE_PIXMAP */
 
 static int
 ghost_over (ModeInfo * mi, int x, int y)
 {
     int ghost = 0;
     int ret = False;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     dot_rc_to_pixel (mi, &x, &y);
     for (ghost = 0; ghost < pp->nghosts; ghost++) {
         if ((pp->ghosts[ghost].cf <= x
@@ -1129,24 +926,22 @@ static void
 flash_bonus_dots (ModeInfo * mi)
 {
 #define MAX_FLASH_COUNT 25
-    static int flash_count = 0;
-    static int on = 0;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     int i, x, y;
     for (i = 0; i < NUM_BONUS_DOTS; i++) {
-        if (!bonus_dot_eaten (i)) {
-            bonus_dot_pos (i, &x, &y);
+        if (!pacman_bonus_dot_eaten (pp, i)) {
+            pacman_bonus_dot_pos (pp, i, &x, &y);
             if (ghost_over (mi, x, y))
                 continue;
-            if (on)
+            if (pp->bd_on)
                 draw_bonus_dot (mi, pp, x, y);
             else
                 clear_bonus_dot (mi, pp, x, y);
         }
     }
-    if (flash_count-- == 0) {
-        flash_count = MAX_FLASH_COUNT;
-        on = !on;
+    if (pp->bd_flash_count-- == 0) {
+        pp->bd_flash_count = MAX_FLASH_COUNT;
+        pp->bd_on = !pp->bd_on;
     }
 }
 
@@ -1158,10 +953,10 @@ ate_bonus_dot (ModeInfo * mi)
      */
     unsigned int ret = 0;
     int idx = 0;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
-    if (is_bonus_dot (pp->pacman.col, pp->pacman.row, &idx)) {
-        ret = !bonus_dot_eaten (idx);
-        eat_bonus_dot (idx);
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
+    if (pacman_is_bonus_dot (pp, pp->pacman.col, pp->pacman.row, &idx)) {
+        ret = !pacman_bonus_dot_eaten (pp, idx);
+        pacman_eat_bonus_dot (pp, idx);
     }
     return ret;
 }
@@ -1170,7 +965,7 @@ static void
 ghost_scared (ModeInfo * mi)
 {
     unsigned int ghost;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     for (ghost = 0; ghost < pp->nghosts; ghost++) {
         if (pp->ghosts[ghost].aistate == goingin || 
             pp->ghosts[ghost].aistate == goingout ||
@@ -1186,7 +981,7 @@ static void
 ghost_not_scared (ModeInfo * mi)
 {
     unsigned int ghost;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     for (ghost = 0; ghost < pp->nghosts; ghost++){
         if (pp->ghosts[ghost].aistate == goingin ||
             pp->ghosts[ghost].aistate == goingout ||
@@ -1202,7 +997,7 @@ static void
 ghost_flash_scared (ModeInfo * mi)
 {
     unsigned int ghost;
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     for (ghost = 0; ghost < pp->nghosts; ghost++)
         pp->ghosts[ghost].flash_scared = !pp->ghosts[ghost].flash_scared;
 }
@@ -1215,12 +1010,8 @@ pacman_tick (ModeInfo * mi)
 #define START_FLASH 200
 #define FLASH_COUNT 25
 
-    Display *display = MI_DISPLAY (mi);
-    pacmangamestruct *pp = &pacmangames[MI_SCREEN (mi)];
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
     unsigned int ghost;
-    static int ghost_scared_timer = 0;
-    static int flash_timer = 0;
-    static PacmanState old_pac_state = chasing;
 #if 0
     draw_grid (mi);
 #endif
@@ -1236,19 +1027,19 @@ pacman_tick (ModeInfo * mi)
     draw_pacman_sprite (mi);
     flash_bonus_dots (mi);
     if (ate_bonus_dot (mi)) {
-        ghost_scared_timer = (random () % 100) + DEFAULT_SCARED_TIME;
+        pp->ghost_scared_timer = (random () % 100) + DEFAULT_SCARED_TIME;
         ghost_scared (mi);
     }
 
-    if (ghost_scared_timer > 0) {
-        if (--ghost_scared_timer == 0)
+    if (pp->ghost_scared_timer > 0) {
+        if (--pp->ghost_scared_timer == 0)
             ghost_not_scared (mi);
-        else if (ghost_scared_timer <= START_FLASH) {
-            if (flash_timer <= 0) {
-                flash_timer = FLASH_COUNT;
+        else if (pp->ghost_scared_timer <= START_FLASH) {
+            if (pp->flash_timer <= 0) {
+                pp->flash_timer = FLASH_COUNT;
                 ghost_flash_scared (mi);
             }
-            flash_timer--;
+            pp->flash_timer--;
         }
     }
 
@@ -1261,20 +1052,17 @@ pacman_tick (ModeInfo * mi)
     if (pp->dotsleft == 0 )
         repopulate (mi);
     else if (pp->pacman.deaths >= 3){
-        if (old_pac_state == ps_dieing && pp->pacman.aistate != ps_dieing)
+        if (pp->old_pac_state == ps_dieing && pp->pacman.aistate != ps_dieing)
             repopulate (mi);
     }
 
-    old_pac_state = pp->pacman.aistate;
-
-    (void) XFlush (display);
+    pp->old_pac_state = pp->pacman.aistate;
 }
 \f
 
 /* CODE TO LOAD AND SCALE THE PIXMAPS
  */
 
-#if defined(USE_PIXMAP)
 /*  Grabbed the scaling routine off of usenet. 
  *  Changed it so that the information specific 
  *  to the source pixmap does not have to be a parameter.
@@ -1323,240 +1111,160 @@ scale_pixmap (Display ** dpy, GC gc, Pixmap source, int dwidth, int dheight)
     end = dheight * yscale;
     /* Scale height of temp into dest pixmap */
     for (i = 0; i <= end; i += yscale)
-        XCopyArea (*dpy, temp, dest, gc, 0, i, swidth, 1, 0, j++);
+        XCopyArea (*dpy, temp, dest, gc, 0, i, dwidth, 1, 0, j++);
 
     XFreePixmap (*dpy, temp);
     return (Pixmap) dest;
 }
 
-static void
-pacman_fail (char *s)
+static Pixmap
+subpixmap (Display *dpy, Window window, Pixmap src,
+           int w, int h, int y, int depth)
 {
-    fprintf (stderr, "%s: %s\n", progname, s);
-    exit (1);
+    XGCValues gcv;
+    Pixmap dest = XCreatePixmap (dpy, window, w, h, depth);
+    GC gc = XCreateGC (dpy, src, 0, &gcv);
+    XCopyArea (dpy, src, dest, gc, 0, y, w, h, 0, 0);
+    XFreeGC (dpy, gc);
+    return dest;
 }
 
+
 /* Load the ghost pixmaps and their mask. */
 static void
-load_ghost_pixmaps (Display ** dpy, Window window, pacmangamestruct ** ps)
+load_pixmaps (Display ** dpy, Window window, pacmangamestruct ** ps)
 {
     pacmangamestruct *pp = *ps;
     Display *display = *dpy;
-    static char *colors[] = {
-        ".     c #FF0000",     /*Red */
-        ".  c #00FFDE",         /*Blue */
-        ".  c #FFB847",         /*Orange */
-        ".  c #FFB8DE",         /*Pink */
-    };
-
-    static char **bits[] = {
-        ghost_u1_xpm, ghost_u2_xpm, ghost_r1_xpm, ghost_r2_xpm,
-        ghost_d1_xpm, ghost_d2_xpm, ghost_l1_xpm, ghost_l2_xpm
-    };
-    static char **s_bits[] = {
-        ghost_s1_xpm, ghost_s2_xpm,
-        ghost_sf1_xpm, ghost_sf2_xpm
-    };
-    static char **e_bits[] = {
-        eyes_u_xpm, eyes_r_xpm, eyes_d_xpm, eyes_l_xpm
-    };
-        
-    int i, j, k, m;
-    int w = pp->spritexs;
-    int h = pp->spriteys;
+    Pixmap sprites, sprites_mask;
+    int i, j, k, m, sw, sh, srcy;
+/*    int w = pp->spritexs;
+    int h = pp->spriteys;*/
     GC gc = 0;
-    Pixmap temp;
+/*    Pixmap temp;*/
+    XGCValues gcv;
+    XWindowAttributes xgwa;
+
+    XGetWindowAttributes (display, window, &xgwa);
+
+    sprites = image_data_to_pixmap (display, window,
+                                    pacman_png, sizeof(pacman_png), &sw, &sh,
+                                    &sprites_mask);
+    if (!sprites || !sprites_mask) abort();
+
+    srcy = 0;
+
+    gc = XCreateGC (display, sprites_mask, 0, &gcv);
+
+    pp->ghostMask = subpixmap (display, window, sprites_mask,
+                               sw, sw, srcy, 1);
+    pp->ghostMask = scale_pixmap (&display, gc, pp->ghostMask,
+                                  pp->spritexs, pp->spriteys);
 
     for (i = 0; i < 4; i++) {
         m = 0;
         for (j = 0; j < MAXGDIR; j++) {
             for (k = 0; k < MAXGWAG; k++) {
-                bits[m][2] = colors[i];
                 pp->ghostPixmap[i][j][k] =
-                    xpm_data_to_pixmap (display, window, bits[m], &w, &h,
-                                        &pp->ghostMask);
-
-                if (!pp->ghostPixmap[i][j][k])
-                    pacman_fail ("Cannot load ghost images");
-
+                    subpixmap (display, window, sprites, sw, sw, srcy,
+                               xgwa.depth);
                 pp->ghostPixmap[i][j][k] =
                     scale_pixmap (&display, pp->stippledGC,
                                   pp->ghostPixmap[i][j][k], pp->spritexs,
                                   pp->spriteys);
-
-                if (!pp->ghostPixmap[i][j][k])
-                    pacman_fail ("Cannot scale ghost images");
                 m++;
+                srcy += sw;
+                if (srcy >= sh) abort();
             }
         }
     }
+
     /* load the scared ghost */
     m = 0;
     for (i = 0; i < MAXGFLASH; i++) {
         for (j = 0; j < MAXGWAG; j++) {
             pp->s_ghostPixmap[i][j] =
-                xpm_data_to_pixmap (display, window, s_bits[m++], &w, &h,
-                                    &pp->ghostMask);
-
-            if (!pp->s_ghostPixmap[i][j])
-                pacman_fail ("Cannot Scare Ghost images");
+                subpixmap (display, window, sprites, sw, sw, srcy,
+                           xgwa.depth);
+            m++;
             pp->s_ghostPixmap[i][j] = scale_pixmap (&display, pp->stippledGC,
                                                     pp->s_ghostPixmap[i][j],
                                                     pp->spritexs,
                                                     pp->spriteys);
-
-            if (!pp->s_ghostPixmap[i][j])
-                pacman_fail ("Cannot scale Scared Ghost images");
+            srcy += sw;
+            if (srcy >= sh) abort();
         }
     }
+
     /* load the ghost eyes */
     for (i = 0; i < MAXGDIR; i++) {
         pp->ghostEyes[i] =
-            xpm_data_to_pixmap (display, window, e_bits[i], &w, &h,
-                                &pp->ghostMask);
-
-        if (!pp->ghostEyes[i])
-            pacman_fail ("Cannot open ghost eye images");
-
+            subpixmap (display, window, sprites, sw, sw, srcy, xgwa.depth);
         pp->ghostEyes[i] = scale_pixmap (&display, pp->stippledGC,
                                          pp->ghostEyes[i],
                                          pp->spritexs,
                                          pp->spriteys);
-            
-        if (!pp->ghostEyes[i])
-            pacman_fail ("Cannot open ghost eye images");
+        srcy += sw;
+        if (srcy >= sh) abort();
     }
 
 
-
-    /* We really only need a single mask. This saves the headache of getting the
-     * bottom of the ghost to clip just right. What we'll do is mask
-     * the top portion of the ghost, but the bottom of the ghost will be solid.
-     * I did this by setting the pixels between the fringe of their sheets
-     * to black instead of none. -jeremy
-     */
-    temp = xpm_data_to_pixmap (display, window, ghost_mask_xpm,
-                               &w, &h, &pp->ghostMask);
-
-    if (!temp)
-        pacman_fail ("Cannot load temporary ghost image");
-
-    temp = scale_pixmap (&display, pp->stippledGC,
-                         temp, pp->spritexs, pp->spriteys);
-
-    if (!temp)
-        pacman_fail ("Cannot scale temporary ghost image");
-
-    gc = XCreateGC (display, pp->ghostMask, 0, 0);
-
-    pp->ghostMask = scale_pixmap (&display, gc, pp->ghostMask,
-                                  pp->spritexs, pp->spriteys);
-    XFreePixmap (display, temp);
-}
-
-/* Load the pacman pixmaps and their mask. */
-static void
-load_pacman_pixmaps (Display ** dpy, Window window, pacmangamestruct ** ps)
-{
-    pacmangamestruct *pp = *ps;
-    Display *display = *dpy;
-
-    static char **bits[] = {
-        pacman_0_xpm, pacman_u1_xpm, pacman_u2_xpm,
-        pacman_0_xpm, pacman_r1_xpm, pacman_r2_xpm,
-        pacman_0_xpm, pacman_d1_xpm, pacman_d2_xpm,
-        pacman_0_xpm, pacman_l1_xpm, pacman_l2_xpm
-    };
-    static char **ds_bits[] = {
-        pacman_ds1_xpm, pacman_ds2_xpm, pacman_ds3_xpm, pacman_ds4_xpm,
-        pacman_ds5_xpm, pacman_ds6_xpm, pacman_ds7_xpm, pacman_ds8_xpm
-    };
-
-    int i, j, m;
-    int w = pp->spritexs;
-    int h = pp->spriteys;
-    GC gc = 0;
+    /* Load the pacman pixmaps and their mask. */
 
     m = 0;
     for (i = 0; i < 4; i++) {
         for (j = 0; j < MAXMOUTH; j++) {
             pp->pacmanPixmap[i][j] =
-                xpm_data_to_pixmap (display, window, bits[m++], &w, &h,
-                                    &pp->pacmanMask[i][j]);
-
-            if (!pp->pacmanPixmap[i][j])
-                pacman_fail ("Cannot load pacman pixmap.");
-
+                subpixmap (display, window, sprites, sw, sw, srcy, 
+                           xgwa.depth);
+            pp->pacmanMask[i][j] =
+                subpixmap (display, window, sprites_mask, sw, sw, srcy, 1);
+            m++;
             pp->pacmanPixmap[i][j] = scale_pixmap (&display, pp->stippledGC,
                                                    pp->pacmanPixmap[i][j],
                                                    pp->spritexs,
                                                    pp->spriteys);
-
-            if (!pp->pacmanPixmap[i][j])
-                pacman_fail ("Cannot scale pacman pixmap.");
-
-            if (!gc)
-                gc = XCreateGC (display, pp->pacmanMask[i][j], 0, 0);
-
             pp->pacmanMask[i][j] =
                 scale_pixmap (&display, gc, pp->pacmanMask[i][j],
                               pp->spritexs, pp->spriteys);
+            srcy += sw;
+            if (srcy >= sh) abort();
         }
     }
     
     /* Load pacman death sequence */
     for ( i = 0; i < PAC_DEATH_FRAMES; i++ ){
+        if (srcy > sh - sw) abort();
         pp->pacman_ds[i] = 
-            xpm_data_to_pixmap (display, window, ds_bits[i], &w, &h,
-                                &pp->pacman_ds_mask[i]);
-
-        if (!pp->pacman_ds[i])
-            pacman_fail ("Cannot load pacman death frame.");
+            subpixmap (display, window, sprites, sw, sw, srcy, xgwa.depth);
+        pp->pacman_ds_mask[i] =
+            subpixmap (display, window, sprites_mask, sw, sw, srcy, 1);
         
         pp->pacman_ds[i] = scale_pixmap ( &display, pp->stippledGC,
                                           pp->pacman_ds[i],
                                           pp->spritexs,
                                           pp->spriteys);
-        
-        if (!pp->pacman_ds[i])
-            pacman_fail ("Cannot scale pixmap.");
-
-        if (!gc)
-            gc = XCreateGC (display, pp->pacman_ds_mask[i], 0, 0);
-
         pp->pacman_ds_mask[i] = 
             scale_pixmap (&display, gc, pp->pacman_ds_mask[i],
                           pp->spritexs, pp->spriteys);
+        srcy += sw;
     }
-
 }
-#endif /* USE_PIXMAP */
+
 
 /* Hook function, sets state to initial position. */
-void
+ENTRYPOINT void
 init_pacman (ModeInfo * mi)
 {
     Display *display = MI_DISPLAY (mi);
     Window window = MI_WINDOW (mi);
-    int size = MI_SIZE (mi);
+    long size = MI_SIZE (mi);
     pacmangamestruct *pp;
     XGCValues gcv;
     int i, j, k;
 
-#if (! defined( USE_PIXMAP ))
-    GC fg_gc, bg_gc;
-    XPoint points[9];
-    int dir, mouth;
-#endif
-
-    if (pacmangames == NULL) {
-        if ((pacmangames = (pacmangamestruct *)
-             calloc ((size_t) MI_NUM_SCREENS (mi),
-                     sizeof (pacmangamestruct))) == NULL)
-            return;
-    }
-    pp = &pacmangames[MI_SCREEN (mi)];
+    MI_INIT (mi, pacman_games);
+    pp = &pacman_games[MI_SCREEN (mi)];
 
     pp->width = (unsigned short) MI_WIDTH (mi);
     pp->height = (unsigned short) MI_HEIGHT (mi);
@@ -1584,9 +1292,15 @@ init_pacman (ModeInfo * mi)
     if (size == 0 ||
         MINGRIDSIZE * size > (int) pp->width ||
         MINGRIDSIZE * size > (int) pp->height) {
-
-        pp->ys = pp->xs = MAX (MIN (pp->width / LEVWIDTH,
-                                    pp->height / LEVHEIGHT), 1);
+        double scale = MIN (pp->width / LEVWIDTH, pp->height / LEVHEIGHT);
+
+        if (pp->width > pp->height * 5 ||  /* weird window aspect ratio */
+            pp->height > pp->width * 5)
+            scale = 0.8 * (pp->width / pp->height
+                           ? pp->width / (double) pp->height
+                           : pp->height / (double) pp->width);
+        pp->ys = MAX (scale, 1);
+        pp->xs = pp->ys;
     }
     else {
         if (size < -MINSIZE)
@@ -1604,6 +1318,7 @@ init_pacman (ModeInfo * mi)
         pp->xs = pp->ys;
     }
 
+
     pp->wallwidth = (unsigned int) (pp->xs + pp->ys) >> 4;
     if (pp->wallwidth < 1)
         pp->wallwidth = 1;
@@ -1617,6 +1332,7 @@ init_pacman (ModeInfo * mi)
     pp->spriteys = MAX (pp->ys + (pp->ys >> 1) - 1, 1);
     pp->spritedx = (pp->xs - pp->spritexs) >> 1;
     pp->spritedy = (pp->ys - pp->spriteys) >> 1;
+    pp->old_pac_state = ps_chasing;
 
     if (!pp->stippledGC) {
         gcv.foreground = MI_BLACK_PIXEL (mi);
@@ -1624,112 +1340,16 @@ init_pacman (ModeInfo * mi)
         if ((pp->stippledGC = XCreateGC (display, window,
                                          GCForeground | GCBackground,
                                          &gcv)) == None) {
-            free_pacman (display, pp);
+            free_pacman (mi);
             return;
         }
     }
 
-#if defined(USE_PIXMAP)
-    load_ghost_pixmaps (&display, window, &pp);
-    load_pacman_pixmaps (&display, window, &pp);
-#else
-    if ((pp->ghostPixmap[0][0][0] = XCreatePixmap (display, window,
-                                                   pp->spritexs, pp->spriteys,
-                                                   1)) == None) {
-        free_pacman (display, pp);
-        return;
-    }
-
-    gcv.foreground = 0;
-    gcv.background = 1;
-    if ((bg_gc = XCreateGC (display, pp->ghostPixmap[0][0][0],
-                            GCForeground | GCBackground, &gcv)) == None) {
-        free_pacman (display, pp);
-        return;
-    }
-
-    gcv.foreground = 1;
-    gcv.background = 0;
-    if ((fg_gc = XCreateGC (display, pp->ghostPixmap[0][0][0],
-                            GCForeground | GCBackground, &gcv)) == None) {
-        XFreeGC (display, bg_gc);
-        free_pacman (display, pp);
-        return;
-    }
+#ifdef HAVE_JWXYZ
+    jwxyz_XSetAntiAliasing (display, pp->stippledGC, False);
+#endif
 
-#define SETPOINT(p, xp, yp) p.x = xp; p.y = yp
-
-    /* draw the triangles on the bottom (scalable) */
-    SETPOINT (points[0], 1, pp->spriteys * 5 / 6);
-    SETPOINT (points[1], pp->spritexs / 6, pp->spriteys);
-    SETPOINT (points[2], pp->spritexs / 3, pp->spriteys * 5 / 6);
-    SETPOINT (points[3], pp->spritexs / 2, pp->spriteys);
-    SETPOINT (points[4], pp->spritexs * 2 / 3, pp->spriteys * 5 / 6);
-    SETPOINT (points[5], pp->spritexs * 5 / 6, pp->spriteys);
-    SETPOINT (points[6], pp->spritexs, pp->spriteys * 5 / 6);
-    SETPOINT (points[7], pp->spritexs, pp->spriteys / 2);
-    SETPOINT (points[8], 1, pp->spriteys / 2);
-
-    XFillRectangle (display, pp->ghostPixmap[0][0][0], bg_gc,
-                    0, 0, pp->spritexs, pp->spriteys);
-    XFillArc (display, pp->ghostPixmap[0][0][0], fg_gc,
-              0, 0, pp->spritexs, pp->spriteys, 0, 11520);
-    XFillPolygon (display, pp->ghostPixmap[0][0][0], fg_gc,
-                  points, 9, Nonconvex, CoordModeOrigin);
-    XFreeGC (display, bg_gc);
-    XFreeGC (display, fg_gc);
-
-
-    if (pp->pacmanPixmap[0][0] != None)
-        for (dir = 0; dir < 4; dir++)
-            for (mouth = 0; mouth < MAXMOUTH; mouth++)
-                XFreePixmap (display, pp->pacmanPixmap[dir]
-                             [mouth]);
-
-    for (dir = 0; dir < 4; dir++)
-        for (mouth = 0; mouth < MAXMOUTH; mouth++) {
-            if ((pp->pacmanPixmap[dir][mouth] =
-                 XCreatePixmap (display, MI_WINDOW (mi), pp->spritexs,
-                                pp->spriteys, 1)) == None) {
-                free_pacman (display, pp);
-                return;
-            }
-            gcv.foreground = 1;
-            gcv.background = 0;
-            if ((fg_gc = XCreateGC (display, pp->pacmanPixmap[dir][mouth],
-                                    GCForeground | GCBackground,
-                                    &gcv)) == None) {
-                free_pacman (display, pp);
-                return;
-            }
-            gcv.foreground = 0;
-            gcv.background = 0;
-            if ((bg_gc = XCreateGC (display,
-                                    pp->pacmanPixmap[dir][mouth],
-                                    GCForeground |
-                                    GCBackground, &gcv)) == None) {
-                XFreeGC (display, fg_gc);
-                free_pacman (display, pp);
-                return;
-            }
-            XFillRectangle (display,
-                            pp->pacmanPixmap[dir][mouth], bg_gc,
-                            0, 0, pp->spritexs, pp->spriteys);
-            if (pp->spritexs == 1 && pp->spriteys == 1)
-                XFillRectangle (display,
-                                pp->pacmanPixmap[dir][mouth],
-                                fg_gc, 0, 0, pp->spritexs, pp->spriteys);
-            else
-                XFillArc (display,
-                          pp->pacmanPixmap[dir][mouth],
-                          fg_gc,
-                          0, 0, pp->spritexs, pp->spriteys,
-                          ((90 - dir * 90) + mouth * 5) * 64,
-                          (360 + (-2 * mouth * 5)) * 64);
-            XFreeGC (display, fg_gc);
-            XFreeGC (display, bg_gc);
-        }
-#endif /* USE_PIXMAP */
+    load_pixmaps (&display, window, &pp);
 
     pp->pacman.lastbox = START;
     pp->pacman.mouthdirection = 1;
@@ -1746,27 +1366,27 @@ init_pacman (ModeInfo * mi)
         if ((pp->ghosts = (ghoststruct *) calloc ((size_t) pp->nghosts,
                                                   sizeof (ghoststruct))) ==
             NULL) {
-            free_pacman (display, pp);
+            free_pacman (mi);
             return;
         }
 
     pp->pacman.mouthstage = MAXMOUTH - 1;
 
-    MI_CLEARWINDOW (mi);
+    XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
     repopulate (mi);
 }
 
 /* Callback function called for each tick.  This is the complete machinery of
    everything that moves. */
-void
+ENTRYPOINT void
 draw_pacman (ModeInfo * mi)
 {
     unsigned int g;
     pacmangamestruct *pp;
 
-    if (pacmangames == NULL)
+    if (pacman_games == NULL)
         return;
-    pp = &pacmangames[MI_SCREEN (mi)];
+    pp = &pacman_games[MI_SCREEN (mi)];
     if (pp->ghosts == NULL)
         return;
 
@@ -1776,7 +1396,7 @@ draw_pacman (ModeInfo * mi)
     pp->pacman.delta.y += pp->pacman.err.y != 0 ? pp->incy : 0;
 
     if (pp->pacman.delta.x >= pp->xs && pp->pacman.delta.y >= pp->ys) {
-        pac_update (mi, pp, &(pp->pacman));
+        pacman_update (mi, pp, &(pp->pacman));
         check_death (mi, pp);
         pp->pacman.delta.x = pp->incx;
         pp->pacman.delta.y = pp->incy;
@@ -1795,7 +1415,7 @@ draw_pacman (ModeInfo * mi)
         
         if (pp->ghosts[g].delta.x >= pp->xs &&
             pp->ghosts[g].delta.y >= pp->ys) {
-            ghost_update (pp, &(pp->ghosts[g]));
+            pacman_ghost_update (pp, &(pp->ghosts[g]));
             pp->ghosts[g].delta.x = pp->incx;
             pp->ghosts[g].delta.y = pp->incy;
         }
@@ -1808,34 +1428,40 @@ draw_pacman (ModeInfo * mi)
     pacman_tick (mi);
 }
 
-/* Releases resources. */
-void
-release_pacman (ModeInfo * mi)
-{
-    if (pacmangames != NULL) {
-        int screen;
-
-        for (screen = 0; screen < MI_NUM_SCREENS (mi); screen++)
-            free_pacman (MI_DISPLAY (mi), &pacmangames[screen]);
-        free (pacmangames);
-        pacmangames = (pacmangamestruct *) NULL;
-    }
-}
-
+#ifndef STANDALONE
 /* Refresh current level. */
-void
+ENTRYPOINT void
 refresh_pacman (ModeInfo * mi)
 {
     drawlevel (mi);
     pacman_tick (mi);
 }
+#endif
+
+ENTRYPOINT void
+reshape_pacman(ModeInfo * mi, int width, int height)
+{
+    pacmangamestruct *pp = &pacman_games[MI_SCREEN (mi)];
+    pp->width  = width;
+    pp->height = height;
+    pp->xb = (pp->width  - pp->ncols * pp->xs) >> 1;
+    pp->yb = (pp->height - pp->nrows * pp->ys) >> 1;
+    XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
+    /* repopulate (mi); */
+    drawlevel (mi);
+}
 
+#ifndef STANDALONE
 /* Callback to change level. */
-void
+ENTRYPOINT void
 change_pacman (ModeInfo * mi)
 {
-    MI_CLEARWINDOW (mi);
+    XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
     repopulate (mi);
 }
+#endif /* !STANDALONE */
+
+
+XSCREENSAVER_MODULE ("Pacman", pacman)
 
 #endif /* MODE_pacman */