2 #if defined(TARGET_X11)
4 /* 2000-08-10T18:03:54Z
6 * open X11 display and sound
11 #include <X11/Xutil.h>
12 #include <X11/Xatom.h>
14 #include <X11/Intrinsic.h>
15 #include <X11/keysymdef.h>
19 #include <X11/Xutil.h>
20 #include <X11/Xatom.h>
21 #include <X11/keysym.h>
22 #include <X11/cursorfont.h>
24 #include <sys/types.h>
33 #include "../libgame/platform.h"
34 #include "../libgame/libgame.h"
79 KeyCode northKeyCode[3];
80 KeyCode eastKeyCode[3];
81 KeyCode southKeyCode[3];
82 KeyCode westKeyCode[3];
83 KeyCode fireKeyCode[3];
84 KeyCode escKeyCode[1];
86 char play[SAMPLE_MAX];
88 static int sound_pid = -1;
89 int sound_pipe[2] = { -1, -1 }; /* for communication */
90 short *sound_data[SAMPLE_MAX]; /* pointer to sound data */
91 long sound_length[SAMPLE_MAX]; /* length of sound data */
93 static Screen *defaultScreen;
94 static Visual *defaultVisual;
95 static Colormap defaultColourmap;
96 static Window defaultRootWindow;
97 static unsigned int screenDepth;
98 static unsigned int screenWidth;
99 static unsigned int screenHeight;
100 static unsigned long screenBlackPixel;
101 static unsigned long screenWhitePixel;
104 static XSizeHints sizeHints;
105 static XSetWindowAttributes setWindowAttributes;
106 static XWMHints wmHints;
107 static XVisualInfo visualInfo;
109 static XGCValues gcValues;
111 static Colormap privateColourmap;
112 static Cursor cursor;
113 static XColor *privateColours;
114 static unsigned char *privateFlags;
115 static int privateNumColours;
117 static XColor redColour;
118 static XColor whiteColour;
123 static Bitmap *pcxBitmaps[4];
124 static Bitmap *pcxBitmapsX2[4];
128 static Pixmap xpmPixmaps[4];
129 static Pixmap xpmBitmaps[4];
130 static XpmAttributes xpmAttributes[4];
131 static int xpmGot[4];
134 static int xpmAllocColourFunc(Display *, Colormap, char *, XColor *, void *);
135 static int xpmFreeColoursFunc(Display *, Colormap, unsigned long *, int, void *);
137 static KeyCode keycodes[16];
140 static const char *xpmNames[4] = { "object.xpm", "score.xpm", "sprite.xpm", "title.xpm" };
144 static const char *pcxNames[4] = { "object.pcx", "score.pcx", "sprite.pcx", "title.pcx" };
147 static const int xpmCloseness[4] = { 10000, 10000, 40000, 50000 };
148 static const KeySym keysyms[16] = {
149 XK_Up, XK_KP_Up, XK_r, /* north */
150 XK_Right, XK_KP_Right, XK_g, /* east */
151 XK_Down, XK_KP_Down, XK_f, /* south */
152 XK_Left, XK_KP_Left, XK_d, /* west */
153 XK_Shift_L, XK_Control_R, XK_space, /* fire */
154 XK_Escape /* escape */
156 static const char *sound_names[SAMPLE_MAX] = {
157 "00.blank.au","01.roll.au","02.stone.au","03.nut.au","04.crack.au",
158 "05.bug.au","06.tank.au","07.android.au","08.spring.au","09.slurp.au",
159 "10.eater.au","11.alien.au","12.collect.au","13.diamond.au","14.squash.au",
160 "15.drip.au","16.push.au","17.dirt.au","18.acid.au","19.ball.au",
161 "20.grow.au","21.wonder.au","22.door.au","23.exit.au","24.dynamite.au",
162 "25.tick.au","26.press.au","27.wheel.au","28.boom.au","29.time.au",
165 static const int sound_volume[SAMPLE_MAX] = {
166 20,100,100,100,100,20,20,100,100,100,
167 50,100,100,100,100,100,100,100,100,100,
168 100,20,100,100,100,100,100,20,100,100,
172 static void xdebug(char *msg)
175 XSync(display, False);
176 printf("EM DEBUG: %s\n", msg);
182 char name[MAXNAME+2];
190 display = XOpenDisplay(arg_display);
192 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to open display", strerror(errno));
197 defaultScreen = DefaultScreenOfDisplay(display);
198 defaultVisual = DefaultVisualOfScreen(defaultScreen);
199 defaultColourmap = DefaultColormapOfScreen(defaultScreen);
200 defaultRootWindow = RootWindowOfScreen(defaultScreen);
201 screenDepth = DefaultDepthOfScreen(defaultScreen);
202 screenWidth = WidthOfScreen(defaultScreen);
203 screenHeight = HeightOfScreen(defaultScreen);
204 screenBlackPixel = BlackPixelOfScreen(defaultScreen);
205 screenWhitePixel = WhitePixelOfScreen(defaultScreen);
209 visualInfo.visualid = XVisualIDFromVisual(defaultVisual);
210 dummyptr = XGetVisualInfo(display, VisualIDMask, &visualInfo, &dummyint);
212 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to get visual info", strerror(errno));
215 memcpy(&visualInfo, dummyptr, sizeof(visualInfo));
218 if(visualInfo.class != PseudoColor) {
219 fprintf(stderr, "%s: \"%s\": %s\n", progname, XDisplayName(arg_display), "private colourmap only supported for pseudocolour display");
223 privateColourmap = XCreateColormap(display, defaultRootWindow, defaultVisual, AllocAll);
224 if(privateColourmap == 0) {
225 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create colourmap", strerror(errno));
229 privateNumColours = visualInfo.colormap_size;
231 privateColours = malloc(privateNumColours * sizeof(XColor));
232 if(privateColours == 0) {
233 fprintf(stderr, "%s: %s (%d): %s\n", progname, "malloc failed", privateNumColours * sizeof(XColor), strerror(errno));
236 for(dummyint = 0; dummyint < privateNumColours; dummyint++) privateColours[dummyint].pixel = dummyint;
237 XQueryColors(display, defaultColourmap, privateColours, privateNumColours);
238 XStoreColors(display, privateColourmap, privateColours, privateNumColours);
240 privateFlags = malloc(privateNumColours);
241 if(privateFlags == 0) {
242 fprintf(stderr, "%s: %s (%d): %s\n", progname, "malloc failed", privateNumColours, strerror(errno));
245 memset(privateFlags, 0, privateNumColours);
246 privateFlags[0] = 1; /* first two entries (black and white) are already allocated */
250 sizeHints.flags = PSize | PMinSize | PMaxSize;
251 sizeHints.width = 20 * TILEX;
252 sizeHints.height = 12 * TILEY + SCOREY;
253 sizeHints.min_width = sizeHints.max_width = sizeHints.width;
254 sizeHints.min_height = sizeHints.max_height = sizeHints.height;
256 dummyint = XWMGeometry(display, XScreenNumberOfScreen(defaultScreen), arg_geometry, 0, 2, &sizeHints, &sizeHints.x, &sizeHints.y, &dummyint, &dummyint, &sizeHints.win_gravity);
257 if(dummyint & (XValue | YValue)) sizeHints.flags |= USPosition | PWinGravity;
260 xwindow = XCreateWindow(display, defaultRootWindow, sizeHints.x, sizeHints.y, sizeHints.width, sizeHints.height, 2, screenDepth, InputOutput, CopyFromParent, 0, 0);
262 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to open window", strerror(errno));
266 setWindowAttributes.background_pixel = screenBlackPixel;
267 setWindowAttributes.border_pixel = screenWhitePixel;
268 setWindowAttributes.backing_store = NotUseful;
269 setWindowAttributes.override_redirect = False;
270 setWindowAttributes.event_mask = KeyPressMask | EnterWindowMask | LeaveWindowMask | ExposureMask;
271 setWindowAttributes.colormap = privateColourmap ? privateColourmap : defaultColourmap;
272 XChangeWindowAttributes(display, xwindow, CWBackPixel | CWBorderPixel | CWBackingStore | CWOverrideRedirect | CWEventMask | CWColormap, &setWindowAttributes);
274 XStoreName(display, xwindow, "Emerald Mine");
276 wmHints.flags = InputHint | StateHint;
277 wmHints.input = True;
278 wmHints.initial_state = NormalState;
279 XSetWMHints(display, xwindow, &wmHints);
281 XSetWMNormalHints(display, xwindow, &sizeHints);
283 deleteAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
284 XSetWMProtocols(display, xwindow, &deleteAtom, 1);
286 cursor = XCreateFontCursor(display, XC_trek);
287 if(cursor) XDefineCursor(display, xwindow, cursor);
289 XMapWindow(display, xwindow);
293 for(i = 0; i < 4; i++) {
296 snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_GFX_DIR, xpmNames[i]);
298 snprintf(name, MAXNAME+2, "%s/%s", EM_GFX_DIR, xpmNames[i]);
300 if(name[MAXNAME]) snprintf_overflow("read graphics/ files");
302 xpmAttributes[i].valuemask = XpmColormap | XpmReturnAllocPixels | XpmExactColors | XpmCloseness | XpmAllocColor | XpmFreeColors;
303 xpmAttributes[i].colormap = privateColourmap ? privateColourmap : defaultColourmap;
304 xpmAttributes[i].exactColors = False;
305 xpmAttributes[i].closeness = xpmCloseness[i];
306 xpmAttributes[i].alloc_color = xpmAllocColourFunc;
307 xpmAttributes[i].free_colors = xpmFreeColoursFunc;
308 dummyint = XpmReadFileToPixmap(display, xwindow, name, &xpmPixmaps[i], &xpmBitmaps[i], &xpmAttributes[i]);
310 fprintf(stderr, "%s: \"%s\": \"%s\": %s: %s: %s\n", progname, XDisplayName(arg_display), name, "failed to read xpm", XpmGetErrorString(dummyint), strerror(errno));
317 for(i = 0; i < 4; i++)
320 snprintf(name, MAXNAME+2, "%s/%s", EM_GFX_DIR, pcxNames[i]);
323 snprintf_overflow("read graphics/ files");
325 if ((pcxBitmaps[i] = LoadImage(name)) == NULL)
327 printf("::: LoadImage() failed for file '%s'\n", name);
332 objBitmap = pcxBitmaps[0];
333 botBitmap = pcxBitmaps[1];
334 sprBitmap = pcxBitmaps[2];
335 ttlBitmap = pcxBitmaps[3];
338 objPixmap = xpmPixmaps[0];
339 botPixmap = xpmPixmaps[1];
340 sprPixmap = xpmPixmaps[2];
341 ttlPixmap = xpmPixmaps[3];
342 objmaskBitmap = xpmBitmaps[0];
343 botmaskBitmap = xpmBitmaps[1];
344 sprmaskBitmap = xpmBitmaps[2];
345 ttlmaskBitmap = xpmBitmaps[3];
347 objPixmap = pcxBitmaps[0]->drawable;
348 botPixmap = pcxBitmaps[1]->drawable;
349 sprPixmap = pcxBitmaps[2]->drawable;
350 ttlPixmap = pcxBitmaps[3]->drawable;
351 objmaskBitmap = pcxBitmaps[0]->clip_mask;
352 botmaskBitmap = pcxBitmaps[1]->clip_mask;
353 sprmaskBitmap = pcxBitmaps[2]->clip_mask;
354 ttlmaskBitmap = pcxBitmaps[3]->clip_mask;
358 for (i = 0; i < 4; i++)
362 if ((clip_mask = XCreatePixmap(display, window->drawable,
363 pcxBitmaps[i]->width * 2,
364 pcxBitmaps[i]->height * 2, 1))
367 printf("::: cannot create clip mask");
373 XGCValues clip_gc_values;
374 unsigned long clip_gc_valuemask;
377 clip_gc_values.graphics_exposures = False;
378 clip_gc_valuemask = GCGraphicsExposures;
379 if ((gc = XCreateGC(display, clip_mask,
380 clip_gc_valuemask, &clip_gc_values)) == None)
382 printf("X CreateGC failed\n");
386 XFillRectangle(display, clip_mask, gc, 0, 0,
387 pcxBitmaps[i]->width * 2,
388 pcxBitmaps[i]->height * 2);
395 int src_width = pcxBitmaps[i]->width;
396 int src_height = pcxBitmaps[i]->height;
399 printf("::: %d, %d [%ld -> %ld (%ld)]\n",
400 src_width, src_height,
402 src_ptr + src_width * src_height * 1,
403 src_width * src_height * 1);
407 for (i = src_ptr; i < src_ptr + src_width * src_height * 1; i++)
417 pcxBitmapsX2[i] = ZoomBitmap(pcxBitmaps[i],
418 pcxBitmaps[i]->width * 2,
419 pcxBitmaps[i]->height * 2);
424 printf("::: CREATING NEW CLIPMASKS ...\n");
427 clip_mask = Pixmap_to_Mask(pcxBitmapsX2[i]->drawable,
428 pcxBitmapsX2[i]->width,
429 pcxBitmapsX2[i]->height);
432 printf("::: CREATING NEW CLIPMASKS DONE\n");
435 pcxBitmapsX2[i]->clip_mask = clip_mask;
438 printf("::: %ld, %ld, %ld, %ld, %ld, %ld, %ld\n",
440 pcxBitmaps[i]->clip_mask, pcxBitmapsX2[i]->clip_mask,
441 pcxBitmaps[i]->width, pcxBitmaps[i]->height,
442 pcxBitmapsX2[i]->width, pcxBitmapsX2[i]->height);
446 ZoomPixmap(display, pcxBitmaps[i]->gc,
447 pcxBitmaps[i]->clip_mask, pcxBitmapsX2[i]->clip_mask,
448 pcxBitmaps[i]->width, pcxBitmaps[i]->height,
449 pcxBitmapsX2[i]->width, pcxBitmapsX2[i]->height);
455 objBitmap = pcxBitmapsX2[0];
456 botBitmap = pcxBitmapsX2[1];
457 sprBitmap = pcxBitmapsX2[2];
458 ttlBitmap = pcxBitmapsX2[3];
460 objPixmap = pcxBitmapsX2[0]->drawable;
461 botPixmap = pcxBitmapsX2[1]->drawable;
462 sprPixmap = pcxBitmapsX2[2]->drawable;
463 ttlPixmap = pcxBitmapsX2[3]->drawable;
465 objmaskBitmap = pcxBitmapsX2[0]->clip_mask;
466 botmaskBitmap = pcxBitmapsX2[1]->clip_mask;
467 sprmaskBitmap = pcxBitmapsX2[2]->clip_mask;
468 ttlmaskBitmap = pcxBitmapsX2[3]->clip_mask;
473 screenBitmap = CreateBitmap(22 * TILEX, 14 * TILEY, DEFAULT_DEPTH);
474 scoreBitmap = CreateBitmap(20 * TILEX, SCOREY, DEFAULT_DEPTH);
477 screenPixmap = XCreatePixmap(display, xwindow, 22 * TILEX, 14 * TILEY, screenDepth);
478 if(screenPixmap == 0) {
479 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
483 scorePixmap = XCreatePixmap(display, xwindow, 20 * TILEX, SCOREY, screenDepth);
484 if(scorePixmap == 0) {
485 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
489 spriteBitmap = XCreatePixmap(display, xwindow, TILEX, TILEY, 1);
490 if(spriteBitmap == 0) {
491 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
495 redColour.pixel = screenWhitePixel;
496 whiteColour.pixel = screenBlackPixel;
497 gotRed = (xpmAllocColourFunc(display, privateColourmap ? privateColourmap : defaultColourmap, "red", &redColour, 0) > 0);
498 gotWhite = (xpmAllocColourFunc(display, privateColourmap ? privateColourmap : defaultColourmap, "white", &whiteColour, 0) > 0);
500 gcValues.graphics_exposures = False;
501 screenGC = XCreateGC(display, screenPixmap, GCGraphicsExposures, &gcValues);
503 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
507 gcValues.graphics_exposures = False;
508 scoreGC = XCreateGC(display, scorePixmap, GCGraphicsExposures, &gcValues);
510 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
514 gcValues.function = objmaskBitmap ? GXcopyInverted : sprmaskBitmap ? GXcopy : GXset;
515 gcValues.graphics_exposures = False;
516 spriteGC = XCreateGC(display, spriteBitmap, GCFunction | GCGraphicsExposures, &gcValues);
518 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
522 gcValues.foreground = redColour.pixel;
523 gcValues.background = whiteColour.pixel;
524 gcValues.line_style = LineDoubleDash;
525 gcValues.graphics_exposures = False;
526 antsGC = XCreateGC(display, screenPixmap, GCForeground | GCBackground | GCLineStyle | GCGraphicsExposures, &gcValues);
528 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
532 for(i = 0; i < 16; i++) {
533 keycodes[i] = XKeysymToKeycode(display, keysyms[i]);
535 for(i = 0; i < 3; i++) northKeyCode[i] = keycodes[i + 0];
536 for(i = 0; i < 3; i++) eastKeyCode[i] = keycodes[i + 3];
537 for(i = 0; i < 3; i++) southKeyCode[i] = keycodes[i + 6];
538 for(i = 0; i < 3; i++) westKeyCode[i] = keycodes[i + 9];
539 for(i = 0; i < 3; i++) fireKeyCode[i] = keycodes[i + 12];
540 for(i = 0; i < 1; i++) escKeyCode[i] = keycodes[i + 15];
542 /* ----------------------------------------------------------------- */
546 Bitmap *bm = pcxBitmaps[2];
547 Pixmap clip_mask = bm->clip_mask;
552 int width = bm->width;
553 int height = bm->height;
558 XImage *src_ximage = XGetImage(display, clip_mask, 0, 0,
559 width, height, AllPlanes, ZPixmap);
560 XImage *dst_ximage = XGetImage(display, xwindow, 0, 0,
561 width, height, AllPlanes, ZPixmap);
564 if (src_ximage == NULL)
566 printf("src_ximage failed\n");
570 if (dst_ximage == NULL)
572 printf("dst_ximage failed\n");
576 printf("::: DISPLAY CLIP MASK ...\n");
578 for (x=0; x<width; x++)
580 for (y=0; y<height; y++)
582 unsigned long pixel = XGetPixel(src_ximage, x, y);
584 if (pixel != BlackPixel(display, screen))
585 pixel = WhitePixel(display, screen);
587 XPutPixel(dst_ximage, x, y, pixel);
591 printf("::: DISPLAY CLIP MASK NOW\n");
593 XPutImage(display, xwindow, screenGC, dst_ximage, 0, 0,
594 0, 13 * TILEY, width, height);
596 printf("::: DISPLAY CLIP MASK DONE\n");
601 /* ----------------------------------------------------------------- */
607 XGCValues clip_gc_values;
608 unsigned long clip_gc_valuemask;
614 GC gc = pcxBitmaps[ii]->stored_clip_gc;
616 GC gc = pcxBitmaps[ii]->gc;
619 Pixmap src_pixmap = pcxBitmaps[ii]->clip_mask;
620 Pixmap dst_pixmap = pcxBitmapsX2[ii]->clip_mask;
621 int src_width = pcxBitmaps[ii]->width;
622 int src_height = pcxBitmaps[ii]->height;
623 int dst_width = pcxBitmapsX2[ii]->width;
624 int dst_height = pcxBitmapsX2[ii]->height;
626 XImage *src_ximage, *dst_ximage;
627 byte *src_ptr, *dst_ptr;
632 boolean scale_down = (src_width > dst_width);
635 int zoom_factor = src_width / dst_width; /* currently very limited! */
637 int row_skip, col_skip;
639 printf("::: %d\n", scale_down);
641 xdebug("::: ZOOM STEP 1");
643 clip_gc_values.graphics_exposures = False;
644 clip_gc_valuemask = GCGraphicsExposures;
645 if ((gc = XCreateGC(display, pcxBitmaps[ii]->clip_mask,
646 clip_gc_valuemask, &clip_gc_values)) == None)
648 printf("XCreateGC failed\n");
652 xdebug("::: ZOOM STEP 2");
656 zoom_factor = src_width / dst_width;
658 /* adjust source image size to integer multiple of destination size */
659 src_width = dst_width * zoom_factor;
660 src_height = dst_height * zoom_factor;
664 zoom_factor = dst_width / src_width;
666 /* no adjustment needed when scaling up (some pixels may be left blank) */
669 /* copy source pixmap to temporary image */
670 if ((src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
671 AllPlanes, ZPixmap)) == NULL)
672 Error(ERR_EXIT, "ZoomPixmap(): XGetImage() failed");
674 bits_per_pixel = src_ximage->bits_per_pixel;
675 bytes_per_pixel = (bits_per_pixel + 7) / 8;
677 printf("::: bits_per_pixel == %d\n", bits_per_pixel);
679 if ((dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
680 0, NULL, dst_width, dst_height,
681 8, dst_width * bytes_per_pixel)) == NULL)
682 Error(ERR_EXIT, "ZoomPixmap(): XCreateImage() failed");
685 checked_malloc(dst_width * dst_height * bytes_per_pixel);
686 dst_ximage->byte_order = src_ximage->byte_order;
688 src_ptr = (byte *)src_ximage->data;
689 dst_ptr = (byte *)dst_ximage->data;
693 col_skip = (zoom_factor - 1) * bytes_per_pixel;
694 row_skip = col_skip * src_width;
696 /* scale image down by scaling factor 'zoom_factor' */
697 for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip)
698 for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip)
699 for (i = 0; i < bytes_per_pixel; i++)
700 *dst_ptr++ = *src_ptr++;
704 row_skip = src_width * bytes_per_pixel;
707 printf("::: %d, %d -> %d, %d [%d / %d]\n[%ld -> %ld (%ld)] [%ld -> %ld (%ld)]\n",
708 src_width, src_height,
709 dst_width, dst_height,
710 zoom_factor, bytes_per_pixel,
712 src_ptr + src_width * src_height * bytes_per_pixel,
713 src_width * src_height * bytes_per_pixel,
715 dst_ptr + dst_width * dst_height * bytes_per_pixel,
716 dst_width * dst_height * bytes_per_pixel);
722 for (i = 0; i < src_width * src_height * bytes_per_pixel;
725 byte x = *(byte *)(src_ptr + i);
727 printf("::: %d ...\n", i);
735 /* scale image up by scaling factor 'zoom_factor' */
736 for (y = 0; y < src_height; y++)
738 for (yy = 0; yy < zoom_factor; yy++)
744 printf("::: [%d -> %ld / %ld]\n", y, src_ptr, dst_ptr);
747 for (x = 0; x < src_width; x++)
749 for (xx = 0; xx < zoom_factor; xx++)
750 for (i = 0; i < bytes_per_pixel; i++)
754 printf("::: %d\n", *(src_ptr + i));
757 *dst_ptr++ = *(src_ptr + i);
769 xdebug("::: ZOOM STEP 9");
771 /* copy scaled image to destination pixmap */
772 XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
773 dst_width, dst_height);
775 /* free temporary images */
776 X11DestroyImage(src_ximage);
777 X11DestroyImage(dst_ximage);
780 xdebug("::: ZOOM DONE");
785 /* ----------------------------------------------------------------- */
789 Bitmap *bm = pcxBitmapsX2[2];
790 Pixmap clip_mask = bm->clip_mask;
795 int width = bm->width;
796 int height = bm->height;
801 XImage *src_ximage = XGetImage(display, clip_mask, 0, 0,
802 width, height, AllPlanes, ZPixmap);
803 XImage *dst_ximage = XGetImage(display, xwindow, 0, 0,
804 width, height, AllPlanes, ZPixmap);
807 if (src_ximage == NULL)
809 printf("src_ximage failed\n");
813 if (dst_ximage == NULL)
815 printf("dst_ximage failed\n");
819 printf("::: DISPLAY CLIP MASK ...\n");
821 for (x=0; x<width; x++)
823 for (y=0; y<height; y++)
825 unsigned long pixel = XGetPixel(src_ximage, x, y);
827 if (pixel != BlackPixel(display, screen))
828 pixel = WhitePixel(display, screen);
830 XPutPixel(dst_ximage, x, y, pixel);
834 printf("::: DISPLAY CLIP MASK NOW\n");
836 XPutImage(display, xwindow, screenGC, dst_ximage, 0, 0,
837 0, 13 * TILEY + height, width, height);
839 printf("::: DISPLAY CLIP MASK DONE\n");
844 /* ----------------------------------------------------------------- */
850 printf("::: GET IMAGE ...\n");
852 dst_ximage = XGetImage(display, xwindow, 0, 0,
853 16, 16, AllPlanes, ZPixmap);
854 if (dst_ximage == NULL)
856 printf("dst_ximage failed\n");
860 printf("::: PUT IMAGE ...\n");
862 XPutImage(display, xwindow, screenGC, dst_ximage, 0, 0,
863 0, 13 * TILEY, 10, 10);
865 printf("::: PUT IMAGE DONE\n");
869 /* ----------------------------------------------------------------- */
871 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
872 if(arg_silence == 0) {
873 for(i = 0; i < SAMPLE_MAX; i++) {
876 snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_SND_DIR, sound_names[i]);
878 snprintf(name, MAXNAME+2, "%s/%s", EM_SND_DIR, sound_names[i]);
880 if(name[MAXNAME]) snprintf_overflow("read sounds/ directory");
882 if(read_sample(name, &sound_data[i], &sound_length[i])) return(1);
886 int mult = sound_volume[i] * 65536 / (100 * MIXER_MAX);
887 stop = sound_data[i] + sound_length[i];
888 for(ptr = sound_data[i]; ptr < stop; ptr++) *ptr = (*ptr * mult) / 65536;
892 if(pipe(sound_pipe) == -1) {
893 fprintf(stderr, "%s: %s: %s\n", progname, "unable to create sound pipe", strerror(errno));
897 if(sound_pid == -1) {
898 fprintf(stderr, "%s: %s: %s\n", progname, "unable to fork sound thread", strerror(errno));
901 close(sound_pipe[sound_pid == 0]); sound_pipe[sound_pid == 0] = -1;
902 if(sound_pid == 0) _exit(sound_thread());
903 signal(SIGPIPE, SIG_IGN); /* dont crash if sound process dies */
905 #endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
914 if(sound_pid != -1) {
915 kill(sound_pid, SIGTERM);
916 waitpid(sound_pid, 0, 0);
918 if(sound_pipe[0] != -1) close(sound_pipe[0]);
919 if(sound_pipe[1] != -1) close(sound_pipe[1]);
920 for(i = 0; i < SAMPLE_MAX; i++) if(sound_data[i]) free(sound_data[i]);
923 for(i = 0; i < 4; i++) if(xpmPixmaps[i]) XFreePixmap(display, xpmPixmaps[i]);
924 for(i = 0; i < 4; i++) if(xpmBitmaps[i]) XFreePixmap(display, xpmBitmaps[i]);
925 for(i = 0; i < 4; i++) if(xpmGot[i]) {
926 xpmFreeColoursFunc(display, xpmAttributes[i].colormap, xpmAttributes[i].alloc_pixels, xpmAttributes[i].nalloc_pixels, 0);
927 XpmFreeAttributes(&xpmAttributes[i]);
931 if(gotRed) xpmFreeColoursFunc(display, privateColourmap ? privateColourmap : defaultColourmap, &redColour.pixel, 1, 0);
932 if(gotWhite) xpmFreeColoursFunc(display, privateColourmap ? privateColourmap : defaultColourmap, &whiteColour.pixel, 1, 0);
934 if(screenGC) XFreeGC(display, screenGC);
935 if(scoreGC) XFreeGC(display, scoreGC);
936 if(spriteGC) XFreeGC(display, spriteGC);
937 if(antsGC) XFreeGC(display, antsGC);
938 if(screenPixmap) XFreePixmap(display, screenPixmap);
939 if(scorePixmap) XFreePixmap(display, scorePixmap);
940 if(spriteBitmap) XFreePixmap(display, spriteBitmap);
941 if(xwindow) XDestroyWindow(display, xwindow);
942 if(cursor) XFreeCursor(display, cursor);
943 if(privateColourmap) XFreeColormap(display, privateColourmap);
944 if(privateColours) free(privateColours);
945 if(privateFlags) free(privateFlags);
946 if(display) XCloseDisplay(display);
949 /* ---------------------------------------------------------------------- */
951 void sound_play(void)
953 if(sound_pipe[1] != -1) {
954 if(write(sound_pipe[1], &play, sizeof(play)) == -1) {
955 fprintf(stderr, "%s: %s: %s\n", progname, "write sound", strerror(errno));
956 if(sound_pipe[0] != -1) { close(sound_pipe[0]); sound_pipe[0] = -1; }
957 if(sound_pipe[1] != -1) { close(sound_pipe[1]); sound_pipe[1] = -1; }
960 memset(play, 0, sizeof(play));
963 /* ---------------------------------------------------------------------- */
965 static int xpmAllocColourFunc(Display *display, Colormap colourmap, char *colourname, XColor *xcolour, void *closure)
971 if(colourname) if(XParseColor(display, colourmap, colourname, xcolour) == 0) return(-1); /* invalid name */
972 if(colourmap != privateColourmap) return(XAllocColor(display, colourmap, xcolour) != 0);
974 /* first try to find an exact match */
976 for(i = 0; i < privateNumColours; i++) {
977 if(privateColours[i].red == xcolour->red && privateColours[i].green == xcolour->green && privateColours[i].blue == xcolour->blue) match = i;
980 privateFlags[match] = 1;
981 xcolour->pixel = privateColours[match].pixel;
985 /* then find an unallocated colour that is close to what we want */
988 for(i = 0; i < privateNumColours; i++) {
989 if(privateFlags[i]) continue; /* skip if it is already allocated */
990 r = (privateColours[i].red - xcolour->red) / 256;
991 g = (privateColours[i].green - xcolour->green) / 256;
992 b = (privateColours[i].blue - xcolour->blue) / 256;
993 sum = r * r + g * g + b * b;
1000 privateFlags[match] = 1;
1001 privateColours[match].red = xcolour->red;
1002 privateColours[match].green = xcolour->green;
1003 privateColours[match].blue = xcolour->blue;
1004 XStoreColor(display, colourmap, &privateColours[match]);
1005 xcolour->pixel = privateColours[match].pixel;
1006 return(1); /* found a close match */
1009 /* if all else fails, just find the closest colour and return it */
1012 for(i = 0; i < privateNumColours; i++) {
1013 r = (privateColours[i].red - xcolour->red) / 256;
1014 g = (privateColours[i].green - xcolour->green) / 256;
1015 b = (privateColours[i].blue - xcolour->blue) / 256;
1016 sum = r * r + g * g + b * b;
1023 xcolour->red = privateColours[match].red;
1024 xcolour->green = privateColours[match].green;
1025 xcolour->blue = privateColours[match].blue;
1026 xcolour->pixel = privateColours[match].pixel;
1027 return(1); /* best we could do */
1029 return(0); /* still didnt find one, give up */
1032 static int xpmFreeColoursFunc(Display *display, Colormap colourmap, unsigned long *pixels, int npixels, void *closure)
1034 if(colourmap != privateColourmap) XFreeColors(display, colourmap, pixels, npixels, 0);
1035 return(1); /* non-zero for success */