1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2006 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
19 #if defined(PLATFORM_MSDOS)
31 /* ========================================================================= */
32 /* exported variables */
33 /* ========================================================================= */
35 struct ProgramInfo program;
36 struct OptionInfo options;
37 struct VideoSystemInfo video;
38 struct AudioSystemInfo audio;
40 struct ArtworkInfo artwork;
41 struct JoystickInfo joystick;
42 struct SetupInfo setup;
44 LevelDirTree *leveldir_first_all = NULL;
45 LevelDirTree *leveldir_first = NULL;
46 LevelDirTree *leveldir_current = NULL;
49 struct LevelStats level_stats[MAX_LEVELS];
51 Display *display = NULL;
52 Visual *visual = NULL;
56 DrawWindow *window = NULL;
57 DrawBuffer *backbuffer = NULL;
58 DrawBuffer *drawto = NULL;
60 int button_status = MB_NOT_PRESSED;
61 boolean motion_status = FALSE;
63 int redraw_mask = REDRAW_NONE;
69 /* ========================================================================= */
70 /* init/close functions */
71 /* ========================================================================= */
73 void InitProgramInfo(char *argv0,
74 char *userdata_subdir, char *userdata_subdir_unix,
75 char *program_title, char *window_title, char *icon_title,
76 char *x11_icon_filename, char *x11_iconmask_filename,
77 char *sdl_icon_filename, char *msdos_cursor_filename,
78 char *cookie_prefix, char *filename_prefix,
81 program.command_basepath = getBasePath(argv0);
82 program.command_basename = getBaseName(argv0);
84 program.userdata_subdir = userdata_subdir;
85 program.userdata_subdir_unix = userdata_subdir_unix;
86 program.userdata_path = getUserGameDataDir();
88 program.program_title = program_title;
89 program.window_title = window_title;
90 program.icon_title = icon_title;
92 program.x11_icon_filename = x11_icon_filename;
93 program.x11_iconmask_filename = x11_iconmask_filename;
94 program.sdl_icon_filename = sdl_icon_filename;
95 program.msdos_cursor_filename = msdos_cursor_filename;
97 program.cookie_prefix = cookie_prefix;
98 program.filename_prefix = filename_prefix;
100 program.version_major = VERSION_MAJOR(program_version);
101 program.version_minor = VERSION_MINOR(program_version);
102 program.version_patch = VERSION_PATCH(program_version);
104 program.error_filename = getErrorFilename(ERROR_BASENAME);
105 program.error_file = stderr;
108 void InitExitFunction(void (*exit_function)(int))
110 program.exit_function = exit_function;
112 /* set signal handlers to custom exit function */
113 signal(SIGINT, exit_function);
114 signal(SIGTERM, exit_function);
116 #if defined(TARGET_SDL)
117 /* set exit function to automatically cleanup SDL stuff after exit() */
122 void InitPlatformDependentStuff(void)
124 #if defined(PLATFORM_MSDOS)
128 #if defined(PLATFORM_MACOSX)
129 updateUserGameDataDir();
132 #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
136 #if defined(TARGET_SDL)
137 if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
138 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
144 void ClosePlatformDependentStuff(void)
146 #if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
150 #if defined(PLATFORM_MSDOS)
155 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
156 int real_sx, int real_sy,
157 int full_sxsize, int full_sysize,
158 Bitmap *field_save_buffer)
164 gfx.real_sx = real_sx;
165 gfx.real_sy = real_sy;
166 gfx.full_sxsize = full_sxsize;
167 gfx.full_sysize = full_sysize;
169 gfx.field_save_buffer = field_save_buffer;
172 gfx.background_bitmap = NULL;
173 gfx.background_bitmap_mask = REDRAW_NONE;
176 SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
177 SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
180 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
188 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
196 void InitGfxWindowInfo(int win_xsize, int win_ysize)
198 gfx.win_xsize = win_xsize;
199 gfx.win_ysize = win_ysize;
202 gfx.background_bitmap_mask = REDRAW_NONE;
204 ReCreateBitmap(&gfx.background_bitmap, win_xsize, win_ysize, DEFAULT_DEPTH);
208 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
210 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
211 /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
212 gfx.scrollbuffer_width = scrollbuffer_width;
213 gfx.scrollbuffer_height = scrollbuffer_height;
216 void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height)
218 gfx.clipping_enabled = enabled;
221 gfx.clip_width = width;
222 gfx.clip_height = height;
225 void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void))
227 gfx.draw_busy_anim_function = draw_busy_anim_function;
230 void InitGfxCustomArtworkInfo()
232 gfx.override_level_graphics = FALSE;
233 gfx.override_level_sounds = FALSE;
234 gfx.override_level_music = FALSE;
236 gfx.draw_init_text = TRUE;
239 void SetDrawDeactivationMask(int draw_deactivation_mask)
241 gfx.draw_deactivation_mask = draw_deactivation_mask;
244 void SetDrawBackgroundMask(int draw_background_mask)
246 gfx.draw_background_mask = draw_background_mask;
251 static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
252 int dest_x, int dest_y, int width, int height)
254 int bitmap_xsize = width;
255 int bitmap_ysize = height;
256 int tile_xsize = tile->width;
257 int tile_ysize = tile->height;
258 int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
259 int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
262 for (y = 0; y < tile_ysteps; y++)
264 for (x = 0; x < tile_xsteps; x++)
266 int draw_x = dest_x + x * tile_xsize;
267 int draw_y = dest_y + y * tile_ysize;
268 int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
269 int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
271 BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
276 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
278 if (background_bitmap_tile != NULL)
279 gfx.background_bitmap_mask |= mask;
281 gfx.background_bitmap_mask &= ~mask;
284 if (gfx.background_bitmap == NULL)
285 gfx.background_bitmap = CreateBitmap(video.width, video.height,
289 if (background_bitmap_tile == NULL) /* empty background requested */
292 if (mask == REDRAW_ALL)
293 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
294 0, 0, video.width, video.height);
295 else if (mask == REDRAW_FIELD)
296 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
297 gfx.real_sx, gfx.real_sy,
298 gfx.full_sxsize, gfx.full_sysize);
299 else if (mask == REDRAW_DOOR_1)
301 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
303 gfx.dxsize, gfx.dysize);
309 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
311 if (background_bitmap_tile != NULL)
312 gfx.background_bitmap_mask |= mask;
314 gfx.background_bitmap_mask &= ~mask;
317 if (gfx.background_bitmap == NULL)
318 gfx.background_bitmap = CreateBitmap(video.width, video.height,
322 if (background_bitmap_tile == NULL) /* empty background requested */
325 if (mask == REDRAW_ALL)
326 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
327 0, 0, video.width, video.height);
328 else if (mask == REDRAW_FIELD)
329 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
330 gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize);
331 else if (mask == REDRAW_DOOR_1)
333 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
334 gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize);
340 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
342 /* remove every mask before setting mask for window */
343 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
344 SetBackgroundBitmap(NULL, 0xffff); /* !!! FIX THIS !!! */
345 SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
348 void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
350 /* remove window area mask before setting mask for main area */
351 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
352 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
353 SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
356 void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
358 /* remove window area mask before setting mask for door area */
359 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
360 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
361 SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
365 /* ========================================================================= */
366 /* video functions */
367 /* ========================================================================= */
369 inline static int GetRealDepth(int depth)
371 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
374 inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
375 int width, int height, Pixel color)
377 #if defined(TARGET_SDL)
378 SDLFillRectangle(bitmap, x, y, width, height, color);
380 X11FillRectangle(bitmap, x, y, width, height, color);
384 inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
385 int src_x, int src_y, int width, int height,
386 int dst_x, int dst_y, int mask_mode)
388 #if defined(TARGET_SDL)
389 SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
390 dst_x, dst_y, mask_mode);
392 X11CopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
393 dst_x, dst_y, mask_mode);
397 void InitVideoDisplay(void)
399 #if defined(TARGET_SDL)
400 SDLInitVideoDisplay();
402 X11InitVideoDisplay();
406 void CloseVideoDisplay(void)
408 KeyboardAutoRepeatOn();
410 #if defined(TARGET_SDL)
411 SDL_QuitSubSystem(SDL_INIT_VIDEO);
414 XCloseDisplay(display);
418 void InitVideoBuffer(int width, int height, int depth, boolean fullscreen)
421 video.height = height;
422 video.depth = GetRealDepth(depth);
424 video.fullscreen_available = FULLSCREEN_STATUS;
425 video.fullscreen_enabled = FALSE;
427 video.fullscreen_mode_current = NULL;
428 video.fullscreen_modes = NULL;
431 #if defined(TARGET_SDL)
432 SDLInitVideoBuffer(&backbuffer, &window, fullscreen);
434 X11InitVideoBuffer(&backbuffer, &window);
440 inline static void FreeBitmapPointers(Bitmap *bitmap)
445 #if defined(TARGET_SDL)
446 SDLFreeBitmapPointers(bitmap);
448 X11FreeBitmapPointers(bitmap);
451 checked_free(bitmap->source_filename);
452 bitmap->source_filename = NULL;
455 inline static void TransferBitmapPointers(Bitmap *src_bitmap,
458 if (src_bitmap == NULL || dst_bitmap == NULL)
461 FreeBitmapPointers(dst_bitmap);
463 *dst_bitmap = *src_bitmap;
466 void FreeBitmap(Bitmap *bitmap)
471 FreeBitmapPointers(bitmap);
476 Bitmap *CreateBitmapStruct(void)
478 #if defined(TARGET_SDL)
479 return checked_calloc(sizeof(struct SDLSurfaceInfo));
481 return checked_calloc(sizeof(struct X11DrawableInfo));
485 Bitmap *CreateBitmap(int width, int height, int depth)
487 Bitmap *new_bitmap = CreateBitmapStruct();
488 int real_width = MAX(1, width); /* prevent zero bitmap width */
489 int real_height = MAX(1, height); /* prevent zero bitmap height */
490 int real_depth = GetRealDepth(depth);
492 #if defined(TARGET_SDL)
493 SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
495 X11CreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
498 new_bitmap->width = real_width;
499 new_bitmap->height = real_height;
504 void ReCreateBitmap(Bitmap **bitmap, int width, int height, int depth)
506 Bitmap *new_bitmap = CreateBitmap(width, height, depth);
510 *bitmap = new_bitmap;
514 TransferBitmapPointers(new_bitmap, *bitmap);
519 void CloseWindow(DrawWindow *window)
521 #if defined(TARGET_X11)
522 X11CloseWindow(window);
526 inline static boolean CheckDrawingArea(int x, int y, int width, int height,
529 if (draw_mask == REDRAW_NONE)
532 if (draw_mask & REDRAW_ALL)
535 if ((draw_mask & REDRAW_FIELD) &&
536 x >= gfx.real_sx && x < gfx.real_sx + gfx.full_sxsize)
539 if ((draw_mask & REDRAW_DOOR_1) &&
540 x >= gfx.dx && y < gfx.dy + gfx.dysize)
543 if ((draw_mask & REDRAW_DOOR_2) &&
544 x >= gfx.dx && y >= gfx.vy)
550 boolean DrawingDeactivated(int x, int y, int width, int height)
552 return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask);
555 boolean DrawingOnBackground(int x, int y)
557 return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) &&
558 CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
561 static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y,
562 int *width, int *height, boolean is_dest)
565 int clip_x, clip_y, clip_width, clip_height;
567 if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */
569 clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width);
570 clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height);
571 clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x);
572 clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y);
578 clip_width = bitmap->width;
579 clip_height = bitmap->height;
582 /* skip if rectangle completely outside bitmap */
584 if (*x + *width <= clip_x ||
585 *y + *height <= clip_y ||
586 *x >= clip_x + clip_width ||
587 *y >= clip_y + clip_height)
590 /* clip if rectangle overlaps bitmap */
594 *width -= clip_x - *x;
597 else if (*x + *width > clip_x + clip_width)
599 *width = clip_x + clip_width - *x;
604 *height -= clip_y - *y;
607 else if (*y + *height > clip_y + clip_height)
609 *height = clip_y + clip_height - *y;
616 /* skip if rectangle completely outside bitmap */
618 if (*x + *width <= 0 ||
620 *x >= bitmap->width ||
621 *y >= bitmap->height)
624 /* clip if rectangle overlaps bitmap */
631 else if (*x + *width > bitmap->width)
633 *width = bitmap->width - *x;
641 else if (*y + *height > bitmap->height)
643 *height = bitmap->height - *y;
650 void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
651 int src_x, int src_y, int width, int height,
652 int dst_x, int dst_y)
654 int dst_x_unclipped = dst_x;
655 int dst_y_unclipped = dst_y;
657 if (DrawingDeactivated(dst_x, dst_y, width, height))
661 if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) ||
662 !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE))
665 /* source x/y might need adjustment if destination x/y was clipped top/left */
666 src_x += dst_x - dst_x_unclipped;
667 src_y += dst_y - dst_y_unclipped;
670 /* skip if rectangle starts outside bitmap */
671 if (src_x >= src_bitmap->width ||
672 src_y >= src_bitmap->height ||
673 dst_x >= dst_bitmap->width ||
674 dst_y >= dst_bitmap->height)
677 /* clip if rectangle overlaps bitmap */
678 if (src_x + width > src_bitmap->width)
679 width = src_bitmap->width - src_x;
680 if (src_y + height > src_bitmap->height)
681 height = src_bitmap->height - src_y;
682 if (dst_x + width > dst_bitmap->width)
683 width = dst_bitmap->width - dst_x;
684 if (dst_y + height > dst_bitmap->height)
685 height = dst_bitmap->height - dst_y;
689 /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
690 /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
691 but is already fixed in SVN and should therefore finally be fixed with
692 the next official SDL release, which is probably version 1.2.14.) */
694 /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
695 #if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
696 if (src_bitmap == dst_bitmap)
698 /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
700 /* needed when blitting directly to same bitmap -- should not be needed with
701 recent SDL libraries, but apparently does not work in 1.2.11 directly */
703 static Bitmap *tmp_bitmap = NULL;
704 static int tmp_bitmap_xsize = 0;
705 static int tmp_bitmap_ysize = 0;
707 /* start with largest static bitmaps for initial bitmap size ... */
708 if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
710 tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
711 tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
714 /* ... and allow for later re-adjustments due to custom artwork bitmaps */
715 if (src_bitmap->width > tmp_bitmap_xsize ||
716 src_bitmap->height > tmp_bitmap_ysize)
718 tmp_bitmap_xsize = MAX(tmp_bitmap_xsize, src_bitmap->width);
719 tmp_bitmap_ysize = MAX(tmp_bitmap_ysize, src_bitmap->height);
721 FreeBitmap(tmp_bitmap);
726 if (tmp_bitmap == NULL)
727 tmp_bitmap = CreateBitmap(tmp_bitmap_xsize, tmp_bitmap_ysize,
730 sysCopyArea(src_bitmap, tmp_bitmap,
731 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
732 sysCopyArea(tmp_bitmap, dst_bitmap,
733 dst_x, dst_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
742 if (dst_x < gfx.sx + gfx.sxsize)
743 printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n",
744 FrameCounter, dst_x, dst_y, width, height);
747 sysCopyArea(src_bitmap, dst_bitmap,
748 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
751 void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap,
752 int src_x, int src_y, int src_width, int src_height,
753 int dst_x, int dst_y, int dst_width, int dst_height)
755 int src_xsize = (src_width == 0 ? src_bitmap->width : src_width);
756 int src_ysize = (src_height == 0 ? src_bitmap->height : src_height);
757 int dst_xsize = dst_width;
758 int dst_ysize = dst_height;
759 int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize;
760 int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize;
763 for (y = 0; y < src_ysteps; y++)
765 for (x = 0; x < src_xsteps; x++)
767 int draw_x = dst_x + x * src_xsize;
768 int draw_y = dst_y + y * src_ysize;
769 int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize);
770 int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize);
772 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize,
778 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
779 int fade_mode, int fade_delay, int post_delay,
780 void (*draw_border_function)(void))
783 /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */
784 if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE))
788 #if defined(TARGET_SDL)
789 SDLFadeRectangle(bitmap_cross, x, y, width, height,
790 fade_mode, fade_delay, post_delay, draw_border_function);
792 X11FadeRectangle(bitmap_cross, x, y, width, height,
793 fade_mode, fade_delay, post_delay, draw_border_function);
797 void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height,
800 if (DrawingDeactivated(x, y, width, height))
804 if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE))
807 /* skip if rectangle starts outside bitmap */
808 if (x >= bitmap->width ||
812 /* clip if rectangle overlaps bitmap */
813 if (x + width > bitmap->width)
814 width = bitmap->width - x;
815 if (y + height > bitmap->height)
816 height = bitmap->height - y;
819 sysFillRectangle(bitmap, x, y, width, height, color);
822 void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
824 FillRectangle(bitmap, x, y, width, height, BLACK_PIXEL);
827 void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
828 int width, int height)
830 if (DrawingOnBackground(x, y))
831 BlitBitmap(gfx.background_bitmap, bitmap, x, y, width, height, x, y);
833 ClearRectangle(bitmap, x, y, width, height);
836 void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
838 #if defined(TARGET_X11)
841 bitmap->clip_gc = clip_gc;
842 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
847 void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
849 #if defined(TARGET_X11)
852 bitmap->clip_gc = clip_gc;
853 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
858 void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
859 int src_x, int src_y, int width, int height,
860 int dst_x, int dst_y)
862 if (DrawingDeactivated(dst_x, dst_y, width, height))
865 sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
866 dst_x, dst_y, BLIT_MASKED);
869 void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap,
870 int src_x, int src_y, int width, int height,
871 int dst_x, int dst_y)
873 if (DrawingOnBackground(dst_x, dst_y))
875 /* draw background */
876 BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
879 /* draw foreground */
880 SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
881 dst_x - src_x, dst_y - src_y);
882 BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
886 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
890 void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y,
893 #if defined(TARGET_SDL)
894 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
896 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
900 void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
903 #if defined(TARGET_SDL)
904 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
906 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
910 #if !defined(TARGET_X11_NATIVE)
911 void DrawLine(Bitmap *bitmap, int from_x, int from_y,
912 int to_x, int to_y, Pixel pixel, int line_width)
916 for (x = 0; x < line_width; x++)
918 for (y = 0; y < line_width; y++)
920 int dx = x - line_width / 2;
921 int dy = y - line_width / 2;
923 if ((x == 0 && y == 0) ||
924 (x == 0 && y == line_width - 1) ||
925 (x == line_width - 1 && y == 0) ||
926 (x == line_width - 1 && y == line_width - 1))
929 #if defined(TARGET_SDL)
931 from_x + dx, from_y + dy, to_x + dx, to_y + dy, pixel);
932 #elif defined(TARGET_ALLEGRO)
933 AllegroDrawLine(bitmap->drawable, from_x + dx, from_y + dy,
934 to_x + dx, to_y + dy, pixel);
941 void DrawLines(Bitmap *bitmap, struct XY *points, int num_points, Pixel pixel)
943 #if !defined(TARGET_X11_NATIVE)
947 for (i = 0; i < num_points - 1; i++)
948 DrawLine(bitmap, points[i].x, points[i].y,
949 points[i + 1].x, points[i + 1].y, pixel, line_width);
952 SDLDrawLines(bitmap->surface, points, num_points, pixel);
955 XSetForeground(display, bitmap->line_gc[1], pixel);
956 XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
957 (XPoint *)points, num_points, CoordModeOrigin);
961 Pixel GetPixel(Bitmap *bitmap, int x, int y)
963 if (x < 0 || x >= bitmap->width ||
964 y < 0 || y >= bitmap->height)
967 #if defined(TARGET_SDL)
968 return SDLGetPixel(bitmap, x, y);
969 #elif defined(TARGET_ALLEGRO)
970 return AllegroGetPixel(bitmap->drawable, x, y);
972 return X11GetPixel(bitmap, x, y);
976 Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
977 unsigned int color_g, unsigned int color_b)
979 #if defined(TARGET_SDL)
980 return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
981 #elif defined(TARGET_ALLEGRO)
982 return AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
984 return X11GetPixelFromRGB(color_r, color_g, color_b);
988 Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
990 unsigned int color_r = (color >> 16) & 0xff;
991 unsigned int color_g = (color >> 8) & 0xff;
992 unsigned int color_b = (color >> 0) & 0xff;
994 return GetPixelFromRGB(bitmap, color_r, color_g, color_b);
997 /* execute all pending screen drawing operations */
998 void FlushDisplay(void)
1005 /* execute and wait for all pending screen drawing operations */
1006 void SyncDisplay(void)
1009 XSync(display, FALSE);
1013 void KeyboardAutoRepeatOn(void)
1015 #if defined(TARGET_SDL)
1016 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
1017 SDL_DEFAULT_REPEAT_INTERVAL / 2);
1018 SDL_EnableUNICODE(1);
1021 XAutoRepeatOn(display);
1025 void KeyboardAutoRepeatOff(void)
1027 #if defined(TARGET_SDL)
1028 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
1029 SDL_EnableUNICODE(0);
1032 XAutoRepeatOff(display);
1036 boolean PointerInWindow(DrawWindow *window)
1038 #if defined(TARGET_SDL)
1046 /* if XQueryPointer() returns False, the pointer
1047 is not on the same screen as the specified window */
1048 return XQueryPointer(display, window->drawable, &root, &child,
1049 &root_x, &root_y, &win_x, &win_y, &mask);
1053 boolean SetVideoMode(boolean fullscreen)
1055 #if defined(TARGET_SDL)
1056 return SDLSetVideoMode(&backbuffer, fullscreen);
1058 boolean success = TRUE;
1060 if (fullscreen && video.fullscreen_available)
1062 Error(ERR_WARN, "fullscreen not available in X11 version");
1064 /* display error message only once */
1065 video.fullscreen_available = FALSE;
1074 boolean ChangeVideoModeIfNeeded(boolean fullscreen)
1076 #if defined(TARGET_SDL)
1077 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
1078 (!fullscreen && video.fullscreen_enabled))
1079 fullscreen = SetVideoMode(fullscreen);
1085 Bitmap *LoadImage(char *filename)
1089 #if defined(TARGET_SDL)
1090 new_bitmap = SDLLoadImage(filename);
1092 new_bitmap = X11LoadImage(filename);
1096 new_bitmap->source_filename = getStringCopy(filename);
1101 Bitmap *LoadCustomImage(char *basename)
1103 char *filename = getCustomImageFilename(basename);
1106 if (filename == NULL)
1107 Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
1109 if ((new_bitmap = LoadImage(filename)) == NULL)
1110 Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
1115 void ReloadCustomImage(Bitmap *bitmap, char *basename)
1117 char *filename = getCustomImageFilename(basename);
1120 if (filename == NULL) /* (should never happen) */
1122 Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
1126 if (strEqual(filename, bitmap->source_filename))
1128 /* The old and new image are the same (have the same filename and path).
1129 This usually means that this image does not exist in this graphic set
1130 and a fallback to the existing image is done. */
1135 if ((new_bitmap = LoadImage(filename)) == NULL)
1137 Error(ERR_WARN, "LoadImage() failed: %s", GetError());
1141 if (bitmap->width != new_bitmap->width ||
1142 bitmap->height != new_bitmap->height)
1144 Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
1146 FreeBitmap(new_bitmap);
1150 TransferBitmapPointers(new_bitmap, bitmap);
1154 Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
1156 Bitmap *dst_bitmap = CreateBitmap(zoom_width, zoom_height, DEFAULT_DEPTH);
1158 #if defined(TARGET_SDL)
1159 SDLZoomBitmap(src_bitmap, dst_bitmap);
1161 X11ZoomBitmap(src_bitmap, dst_bitmap);
1167 static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
1168 boolean create_small_bitmaps)
1172 Bitmap *tmp_bitmap_1;
1173 Bitmap *tmp_bitmap_2;
1174 Bitmap *tmp_bitmap_4;
1175 Bitmap *tmp_bitmap_8;
1176 Bitmap *tmp_bitmap_16;
1177 Bitmap *tmp_bitmap_32;
1178 int width_1, height_1;
1179 int width_2, height_2;
1180 int width_4, height_4;
1181 int width_8, height_8;
1182 int width_16, height_16;
1184 int width_32, height_32;
1186 int new_width, new_height;
1188 /* calculate new image dimensions for normal sized image */
1189 width_1 = old_bitmap->width * zoom_factor;
1190 height_1 = old_bitmap->height * zoom_factor;
1192 /* get image with normal size (this might require scaling up) */
1193 if (zoom_factor != 1)
1194 tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
1196 tmp_bitmap_1 = old_bitmap;
1198 /* this is only needed to make compilers happy */
1199 tmp_bitmap_2 = NULL;
1200 tmp_bitmap_4 = NULL;
1201 tmp_bitmap_8 = NULL;
1202 tmp_bitmap_16 = NULL;
1203 tmp_bitmap_32 = NULL;
1205 if (create_small_bitmaps)
1207 /* calculate new image dimensions for small images */
1208 width_2 = width_1 / 2;
1209 height_2 = height_1 / 2;
1210 width_4 = width_1 / 4;
1211 height_4 = height_1 / 4;
1212 width_8 = width_1 / 8;
1213 height_8 = height_1 / 8;
1214 width_16 = width_1 / 16;
1215 height_16 = height_1 / 16;
1217 width_32 = width_1 / 32;
1218 height_32 = height_1 / 32;
1221 UPDATE_BUSY_STATE();
1223 /* get image with 1/2 of normal size (for use in the level editor) */
1224 if (zoom_factor != 2)
1225 tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
1227 tmp_bitmap_2 = old_bitmap;
1229 UPDATE_BUSY_STATE();
1231 /* get image with 1/4 of normal size (for use in the level editor) */
1232 if (zoom_factor != 4)
1233 tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2);
1235 tmp_bitmap_4 = old_bitmap;
1237 UPDATE_BUSY_STATE();
1239 /* get image with 1/8 of normal size (for use on the preview screen) */
1240 if (zoom_factor != 8)
1241 tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2);
1243 tmp_bitmap_8 = old_bitmap;
1245 UPDATE_BUSY_STATE();
1247 /* get image with 1/16 of normal size (for use on the preview screen) */
1248 if (zoom_factor != 16)
1249 tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2);
1251 tmp_bitmap_16 = old_bitmap;
1253 UPDATE_BUSY_STATE();
1255 /* get image with 1/32 of normal size (for use on the preview screen) */
1256 if (zoom_factor != 32)
1257 tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2);
1259 tmp_bitmap_32 = old_bitmap;
1261 UPDATE_BUSY_STATE();
1265 /* if image was scaled up, create new clipmask for normal size image */
1266 if (zoom_factor != 1)
1268 #if defined(TARGET_X11)
1269 if (old_bitmap->clip_mask)
1270 XFreePixmap(display, old_bitmap->clip_mask);
1272 old_bitmap->clip_mask =
1273 Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
1275 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1277 SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
1279 if (old_bitmap->surface_masked)
1280 SDL_FreeSurface(old_bitmap->surface_masked);
1282 SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
1283 SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
1284 if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
1285 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1286 SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
1291 if (create_small_bitmaps)
1293 new_width = width_1;
1294 new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
1296 new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
1298 BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
1299 BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
1301 BlitBitmap(tmp_bitmap_4, new_bitmap, 0, 0, width_1 / 4, height_1 / 4,
1302 width_1 / 2, height_1);
1303 BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
1304 3 * width_1 / 4, height_1);
1305 BlitBitmap(tmp_bitmap_16, new_bitmap, 0, 0, width_1 / 16, height_1 / 16,
1306 7 * width_1 / 8, height_1);
1307 BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32,
1308 15 * width_1 / 16, height_1);
1310 UPDATE_BUSY_STATE();
1314 new_width = width_1;
1315 new_height = height_1;
1317 new_bitmap = tmp_bitmap_1; /* directly use tmp_bitmap_1 as new bitmap */
1320 if (create_small_bitmaps)
1322 /* if no small bitmaps created, tmp_bitmap_1 is used as new bitmap now */
1323 if (zoom_factor != 1)
1324 FreeBitmap(tmp_bitmap_1);
1326 if (zoom_factor != 2)
1327 FreeBitmap(tmp_bitmap_2);
1329 if (zoom_factor != 4)
1330 FreeBitmap(tmp_bitmap_4);
1332 if (zoom_factor != 8)
1333 FreeBitmap(tmp_bitmap_8);
1335 if (zoom_factor != 16)
1336 FreeBitmap(tmp_bitmap_16);
1338 if (zoom_factor != 32)
1339 FreeBitmap(tmp_bitmap_32);
1342 /* replace image with extended image (containing 1/1, 1/2, 1/4, 1/8 size) */
1343 #if defined(TARGET_SDL)
1344 swap_bitmap.surface = old_bitmap->surface;
1345 old_bitmap->surface = new_bitmap->surface;
1346 new_bitmap->surface = swap_bitmap.surface;
1348 swap_bitmap.drawable = old_bitmap->drawable;
1349 old_bitmap->drawable = new_bitmap->drawable;
1350 new_bitmap->drawable = swap_bitmap.drawable;
1353 old_bitmap->width = new_bitmap->width;
1354 old_bitmap->height = new_bitmap->height;
1357 /* this replaces all blit masks created when loading -- maybe optimize this */
1359 #if defined(TARGET_X11)
1360 if (old_bitmap->clip_mask)
1361 XFreePixmap(display, old_bitmap->clip_mask);
1363 old_bitmap->clip_mask =
1364 Pixmap_to_Mask(old_bitmap->drawable, new_width, new_height);
1366 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1368 SDL_Surface *old_surface = old_bitmap->surface;
1370 if (old_bitmap->surface_masked)
1371 SDL_FreeSurface(old_bitmap->surface_masked);
1373 SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
1374 SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
1375 if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
1376 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1377 SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */
1382 UPDATE_BUSY_STATE();
1384 FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */
1387 void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
1389 CreateScaledBitmaps(old_bitmap, zoom_factor, TRUE);
1392 void ScaleBitmap(Bitmap *old_bitmap, int zoom_factor)
1394 CreateScaledBitmaps(old_bitmap, zoom_factor, FALSE);
1398 /* ------------------------------------------------------------------------- */
1399 /* mouse pointer functions */
1400 /* ------------------------------------------------------------------------- */
1402 #if !defined(PLATFORM_MSDOS)
1403 #define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
1404 /* XPM image definitions */
1405 static const char *cursor_image_none[] =
1407 /* width height num_colors chars_per_pixel */
1436 #if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
1437 static const char *cursor_image_dot[] =
1439 /* width height num_colors chars_per_pixel */
1468 static const char **cursor_image_playfield = cursor_image_dot;
1470 /* some people complained about a "white dot" on the screen and thought it
1471 was a graphical error... OK, let's just remove the whole pointer :-) */
1472 static const char **cursor_image_playfield = cursor_image_none;
1475 #if defined(TARGET_SDL)
1476 static const int cursor_bit_order = BIT_ORDER_MSB;
1477 #elif defined(TARGET_X11_NATIVE)
1478 static const int cursor_bit_order = BIT_ORDER_LSB;
1481 static struct MouseCursorInfo *get_cursor_from_image(const char **image)
1483 struct MouseCursorInfo *cursor;
1484 boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
1485 int header_lines = 4;
1488 cursor = checked_calloc(sizeof(struct MouseCursorInfo));
1490 sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
1493 for (y = 0; y < cursor->width; y++)
1495 for (x = 0; x < cursor->height; x++)
1498 int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
1503 cursor->data[i] = cursor->mask[i] = 0;
1506 switch (image[header_lines + y][x])
1509 cursor->data[i] |= bit_mask;
1510 cursor->mask[i] |= bit_mask;
1514 cursor->mask[i] |= bit_mask;
1523 sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
1527 #endif /* !PLATFORM_MSDOS */
1529 void SetMouseCursor(int mode)
1531 #if !defined(PLATFORM_MSDOS)
1532 static struct MouseCursorInfo *cursor_none = NULL;
1533 static struct MouseCursorInfo *cursor_playfield = NULL;
1534 struct MouseCursorInfo *cursor_new;
1536 if (cursor_none == NULL)
1537 cursor_none = get_cursor_from_image(cursor_image_none);
1539 if (cursor_playfield == NULL)
1540 cursor_playfield = get_cursor_from_image(cursor_image_playfield);
1542 cursor_new = (mode == CURSOR_DEFAULT ? NULL :
1543 mode == CURSOR_NONE ? cursor_none :
1544 mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
1546 #if defined(TARGET_SDL)
1547 SDLSetMouseCursor(cursor_new);
1548 #elif defined(TARGET_X11_NATIVE)
1549 X11SetMouseCursor(cursor_new);
1555 /* ========================================================================= */
1556 /* audio functions */
1557 /* ========================================================================= */
1559 void OpenAudio(void)
1561 /* always start with reliable default values */
1562 audio.sound_available = FALSE;
1563 audio.music_available = FALSE;
1564 audio.loops_available = FALSE;
1566 audio.sound_enabled = FALSE;
1567 audio.sound_deactivated = FALSE;
1569 audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
1570 audio.mixer_pid = 0;
1571 audio.device_name = NULL;
1572 audio.device_fd = -1;
1574 audio.num_channels = 0;
1575 audio.music_channel = 0;
1576 audio.first_sound_channel = 0;
1578 #if defined(TARGET_SDL)
1580 #elif defined(PLATFORM_UNIX)
1582 #elif defined(PLATFORM_MSDOS)
1587 void CloseAudio(void)
1589 #if defined(TARGET_SDL)
1591 #elif defined(PLATFORM_UNIX)
1593 #elif defined(PLATFORM_MSDOS)
1597 audio.sound_enabled = FALSE;
1600 void SetAudioMode(boolean enabled)
1602 if (!audio.sound_available)
1605 audio.sound_enabled = enabled;
1609 /* ========================================================================= */
1610 /* event functions */
1611 /* ========================================================================= */
1613 void InitEventFilter(EventFilter filter_function)
1615 #if defined(TARGET_SDL)
1616 /* set event filter to filter out certain events */
1617 SDL_SetEventFilter(filter_function);
1621 boolean PendingEvent(void)
1623 #if defined(TARGET_SDL)
1624 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
1626 return (XPending(display) ? TRUE : FALSE);
1630 void NextEvent(Event *event)
1632 #if defined(TARGET_SDL)
1633 SDLNextEvent(event);
1635 XNextEvent(display, event);
1639 void PeekEvent(Event *event)
1641 #if defined(TARGET_SDL)
1642 SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
1644 XPeekEvent(display, event);
1648 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
1650 #if defined(TARGET_SDL)
1653 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
1654 (int)event->keysym.unicode,
1655 (int)event->keysym.sym,
1656 (int)SDL_GetModState());
1659 if (with_modifiers &&
1660 event->keysym.unicode > 0x0000 &&
1661 event->keysym.unicode < 0x2000)
1662 return event->keysym.unicode;
1664 return event->keysym.sym;
1669 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
1670 (int)XLookupKeysym(event, event->state),
1671 (int)XLookupKeysym(event, 0));
1675 return XLookupKeysym(event, event->state);
1677 return XLookupKeysym(event, 0);
1681 KeyMod HandleKeyModState(Key key, int key_status)
1683 static KeyMod current_modifiers = KMOD_None;
1685 if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
1687 KeyMod new_modifier = KMOD_None;
1692 new_modifier = KMOD_Shift_L;
1695 new_modifier = KMOD_Shift_R;
1697 case KSYM_Control_L:
1698 new_modifier = KMOD_Control_L;
1700 case KSYM_Control_R:
1701 new_modifier = KMOD_Control_R;
1704 new_modifier = KMOD_Meta_L;
1707 new_modifier = KMOD_Meta_R;
1710 new_modifier = KMOD_Alt_L;
1713 new_modifier = KMOD_Alt_R;
1719 if (key_status == KEY_PRESSED)
1720 current_modifiers |= new_modifier;
1722 current_modifiers &= ~new_modifier;
1725 return current_modifiers;
1728 KeyMod GetKeyModState()
1730 #if defined(TARGET_SDL)
1731 return (KeyMod)SDL_GetModState();
1733 return HandleKeyModState(KSYM_UNDEFINED, 0);
1737 KeyMod GetKeyModStateFromEvents()
1739 /* always use key modifier state as tracked from key events (this is needed
1740 if the modifier key event was injected into the event queue, but the key
1741 was not really pressed on keyboard -- SDL_GetModState() seems to directly
1742 query the keys as held pressed on the keyboard) -- this case is currently
1743 only used to filter out clipboard insert events from "True X-Mouse" tool */
1745 return HandleKeyModState(KSYM_UNDEFINED, 0);
1748 boolean CheckCloseWindowEvent(ClientMessageEvent *event)
1750 if (event->type != EVENT_CLIENTMESSAGE)
1753 #if defined(TARGET_SDL)
1754 return TRUE; /* the only possible message here is SDL_QUIT */
1755 #elif defined(PLATFORM_UNIX)
1756 if ((event->window == window->drawable) &&
1757 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
1765 /* ========================================================================= */
1766 /* joystick functions */
1767 /* ========================================================================= */
1769 void InitJoysticks()
1773 #if defined(NO_JOYSTICK)
1774 return; /* joysticks generally deactivated by compile-time directive */
1777 /* always start with reliable default values */
1778 joystick.status = JOYSTICK_NOT_AVAILABLE;
1779 for (i = 0; i < MAX_PLAYERS; i++)
1780 joystick.fd[i] = -1; /* joystick device closed */
1782 #if defined(TARGET_SDL)
1784 #elif defined(PLATFORM_UNIX)
1785 UnixInitJoysticks();
1786 #elif defined(PLATFORM_MSDOS)
1787 MSDOSInitJoysticks();
1791 for (i = 0; i < MAX_PLAYERS; i++)
1792 printf("::: Joystick for player %d: %d\n", i, joystick.fd[i]);
1796 boolean ReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1798 #if defined(TARGET_SDL)
1799 return SDLReadJoystick(nr, x, y, b1, b2);
1800 #elif defined(PLATFORM_UNIX)
1801 return UnixReadJoystick(nr, x, y, b1, b2);
1802 #elif defined(PLATFORM_MSDOS)
1803 return MSDOSReadJoystick(nr, x, y, b1, b2);