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;
1183 int width_32, height_32;
1184 int new_width, new_height;
1186 /* calculate new image dimensions for normal sized image */
1187 width_1 = old_bitmap->width * zoom_factor;
1188 height_1 = old_bitmap->height * zoom_factor;
1190 /* get image with normal size (this might require scaling up) */
1191 if (zoom_factor != 1)
1192 tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
1194 tmp_bitmap_1 = old_bitmap;
1196 /* this is only needed to make compilers happy */
1197 tmp_bitmap_2 = NULL;
1198 tmp_bitmap_4 = NULL;
1199 tmp_bitmap_8 = NULL;
1200 tmp_bitmap_16 = NULL;
1201 tmp_bitmap_32 = NULL;
1203 if (create_small_bitmaps)
1205 /* calculate new image dimensions for small images */
1206 width_2 = width_1 / 2;
1207 height_2 = height_1 / 2;
1208 width_4 = width_1 / 4;
1209 height_4 = height_1 / 4;
1210 width_8 = width_1 / 8;
1211 height_8 = height_1 / 8;
1212 width_16 = width_1 / 16;
1213 height_16 = height_1 / 16;
1214 width_32 = width_1 / 32;
1215 height_32 = height_1 / 32;
1217 UPDATE_BUSY_STATE();
1219 /* get image with 1/2 of normal size (for use in the level editor) */
1220 if (zoom_factor != 2)
1221 tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
1223 tmp_bitmap_2 = old_bitmap;
1225 UPDATE_BUSY_STATE();
1227 /* get image with 1/4 of normal size (for use in the level editor) */
1228 if (zoom_factor != 4)
1229 tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2);
1231 tmp_bitmap_4 = old_bitmap;
1233 UPDATE_BUSY_STATE();
1235 /* get image with 1/8 of normal size (for use on the preview screen) */
1236 if (zoom_factor != 8)
1237 tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2);
1239 tmp_bitmap_8 = old_bitmap;
1241 UPDATE_BUSY_STATE();
1243 /* get image with 1/16 of normal size (for use on the preview screen) */
1244 if (zoom_factor != 16)
1245 tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2);
1247 tmp_bitmap_16 = old_bitmap;
1249 UPDATE_BUSY_STATE();
1251 /* get image with 1/32 of normal size (for use on the preview screen) */
1252 if (zoom_factor != 32)
1253 tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2);
1255 tmp_bitmap_32 = old_bitmap;
1257 UPDATE_BUSY_STATE();
1261 /* if image was scaled up, create new clipmask for normal size image */
1262 if (zoom_factor != 1)
1264 #if defined(TARGET_X11)
1265 if (old_bitmap->clip_mask)
1266 XFreePixmap(display, old_bitmap->clip_mask);
1268 old_bitmap->clip_mask =
1269 Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
1271 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1273 SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
1275 if (old_bitmap->surface_masked)
1276 SDL_FreeSurface(old_bitmap->surface_masked);
1278 SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
1279 SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
1280 if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
1281 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1282 SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
1287 if (create_small_bitmaps)
1289 new_width = width_1;
1290 new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
1292 new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
1294 BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
1295 BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
1297 BlitBitmap(tmp_bitmap_4, new_bitmap, 0, 0, width_1 / 4, height_1 / 4,
1298 width_1 / 2, height_1);
1299 BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
1300 3 * width_1 / 4, height_1);
1301 BlitBitmap(tmp_bitmap_16, new_bitmap, 0, 0, width_1 / 16, height_1 / 16,
1302 7 * width_1 / 8, height_1);
1303 BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32,
1304 15 * width_1 / 16, height_1);
1306 UPDATE_BUSY_STATE();
1310 new_width = width_1;
1311 new_height = height_1;
1313 new_bitmap = tmp_bitmap_1; /* directly use tmp_bitmap_1 as new bitmap */
1316 if (create_small_bitmaps)
1318 /* if no small bitmaps created, tmp_bitmap_1 is used as new bitmap now */
1319 if (zoom_factor != 1)
1320 FreeBitmap(tmp_bitmap_1);
1322 if (zoom_factor != 2)
1323 FreeBitmap(tmp_bitmap_2);
1325 if (zoom_factor != 4)
1326 FreeBitmap(tmp_bitmap_4);
1328 if (zoom_factor != 8)
1329 FreeBitmap(tmp_bitmap_8);
1331 if (zoom_factor != 16)
1332 FreeBitmap(tmp_bitmap_16);
1334 if (zoom_factor != 32)
1335 FreeBitmap(tmp_bitmap_32);
1338 /* replace image with extended image (containing 1/1, 1/2, 1/4, 1/8 size) */
1339 #if defined(TARGET_SDL)
1340 swap_bitmap.surface = old_bitmap->surface;
1341 old_bitmap->surface = new_bitmap->surface;
1342 new_bitmap->surface = swap_bitmap.surface;
1344 swap_bitmap.drawable = old_bitmap->drawable;
1345 old_bitmap->drawable = new_bitmap->drawable;
1346 new_bitmap->drawable = swap_bitmap.drawable;
1349 old_bitmap->width = new_bitmap->width;
1350 old_bitmap->height = new_bitmap->height;
1353 /* this replaces all blit masks created when loading -- maybe optimize this */
1355 #if defined(TARGET_X11)
1356 if (old_bitmap->clip_mask)
1357 XFreePixmap(display, old_bitmap->clip_mask);
1359 old_bitmap->clip_mask =
1360 Pixmap_to_Mask(old_bitmap->drawable, new_width, new_height);
1362 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1364 SDL_Surface *old_surface = old_bitmap->surface;
1366 if (old_bitmap->surface_masked)
1367 SDL_FreeSurface(old_bitmap->surface_masked);
1369 SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
1370 SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
1371 if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
1372 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1373 SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */
1378 UPDATE_BUSY_STATE();
1380 FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */
1383 void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
1385 CreateScaledBitmaps(old_bitmap, zoom_factor, TRUE);
1388 void ScaleBitmap(Bitmap *old_bitmap, int zoom_factor)
1390 CreateScaledBitmaps(old_bitmap, zoom_factor, FALSE);
1394 /* ------------------------------------------------------------------------- */
1395 /* mouse pointer functions */
1396 /* ------------------------------------------------------------------------- */
1398 #if !defined(PLATFORM_MSDOS)
1399 #define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
1400 /* XPM image definitions */
1401 static const char *cursor_image_none[] =
1403 /* width height num_colors chars_per_pixel */
1432 #if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
1433 static const char *cursor_image_dot[] =
1435 /* width height num_colors chars_per_pixel */
1464 static const char **cursor_image_playfield = cursor_image_dot;
1466 /* some people complained about a "white dot" on the screen and thought it
1467 was a graphical error... OK, let's just remove the whole pointer :-) */
1468 static const char **cursor_image_playfield = cursor_image_none;
1471 #if defined(TARGET_SDL)
1472 static const int cursor_bit_order = BIT_ORDER_MSB;
1473 #elif defined(TARGET_X11_NATIVE)
1474 static const int cursor_bit_order = BIT_ORDER_LSB;
1477 static struct MouseCursorInfo *get_cursor_from_image(const char **image)
1479 struct MouseCursorInfo *cursor;
1480 boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
1481 int header_lines = 4;
1484 cursor = checked_calloc(sizeof(struct MouseCursorInfo));
1486 sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
1489 for (y = 0; y < cursor->width; y++)
1491 for (x = 0; x < cursor->height; x++)
1494 int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
1499 cursor->data[i] = cursor->mask[i] = 0;
1502 switch (image[header_lines + y][x])
1505 cursor->data[i] |= bit_mask;
1506 cursor->mask[i] |= bit_mask;
1510 cursor->mask[i] |= bit_mask;
1519 sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
1523 #endif /* !PLATFORM_MSDOS */
1525 void SetMouseCursor(int mode)
1527 #if !defined(PLATFORM_MSDOS)
1528 static struct MouseCursorInfo *cursor_none = NULL;
1529 static struct MouseCursorInfo *cursor_playfield = NULL;
1530 struct MouseCursorInfo *cursor_new;
1532 if (cursor_none == NULL)
1533 cursor_none = get_cursor_from_image(cursor_image_none);
1535 if (cursor_playfield == NULL)
1536 cursor_playfield = get_cursor_from_image(cursor_image_playfield);
1538 cursor_new = (mode == CURSOR_DEFAULT ? NULL :
1539 mode == CURSOR_NONE ? cursor_none :
1540 mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
1542 #if defined(TARGET_SDL)
1543 SDLSetMouseCursor(cursor_new);
1544 #elif defined(TARGET_X11_NATIVE)
1545 X11SetMouseCursor(cursor_new);
1551 /* ========================================================================= */
1552 /* audio functions */
1553 /* ========================================================================= */
1555 void OpenAudio(void)
1557 /* always start with reliable default values */
1558 audio.sound_available = FALSE;
1559 audio.music_available = FALSE;
1560 audio.loops_available = FALSE;
1562 audio.sound_enabled = FALSE;
1563 audio.sound_deactivated = FALSE;
1565 audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
1566 audio.mixer_pid = 0;
1567 audio.device_name = NULL;
1568 audio.device_fd = -1;
1570 audio.num_channels = 0;
1571 audio.music_channel = 0;
1572 audio.first_sound_channel = 0;
1574 #if defined(TARGET_SDL)
1576 #elif defined(PLATFORM_UNIX)
1578 #elif defined(PLATFORM_MSDOS)
1583 void CloseAudio(void)
1585 #if defined(TARGET_SDL)
1587 #elif defined(PLATFORM_UNIX)
1589 #elif defined(PLATFORM_MSDOS)
1593 audio.sound_enabled = FALSE;
1596 void SetAudioMode(boolean enabled)
1598 if (!audio.sound_available)
1601 audio.sound_enabled = enabled;
1605 /* ========================================================================= */
1606 /* event functions */
1607 /* ========================================================================= */
1609 void InitEventFilter(EventFilter filter_function)
1611 #if defined(TARGET_SDL)
1612 /* set event filter to filter out certain events */
1613 SDL_SetEventFilter(filter_function);
1617 boolean PendingEvent(void)
1619 #if defined(TARGET_SDL)
1620 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
1622 return (XPending(display) ? TRUE : FALSE);
1626 void NextEvent(Event *event)
1628 #if defined(TARGET_SDL)
1629 SDLNextEvent(event);
1631 XNextEvent(display, event);
1635 void PeekEvent(Event *event)
1637 #if defined(TARGET_SDL)
1638 SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
1640 XPeekEvent(display, event);
1644 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
1646 #if defined(TARGET_SDL)
1649 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
1650 (int)event->keysym.unicode,
1651 (int)event->keysym.sym,
1652 (int)SDL_GetModState());
1655 if (with_modifiers &&
1656 event->keysym.unicode > 0x0000 &&
1657 event->keysym.unicode < 0x2000)
1658 return event->keysym.unicode;
1660 return event->keysym.sym;
1665 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
1666 (int)XLookupKeysym(event, event->state),
1667 (int)XLookupKeysym(event, 0));
1671 return XLookupKeysym(event, event->state);
1673 return XLookupKeysym(event, 0);
1677 KeyMod HandleKeyModState(Key key, int key_status)
1679 static KeyMod current_modifiers = KMOD_None;
1681 if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
1683 KeyMod new_modifier = KMOD_None;
1688 new_modifier = KMOD_Shift_L;
1691 new_modifier = KMOD_Shift_R;
1693 case KSYM_Control_L:
1694 new_modifier = KMOD_Control_L;
1696 case KSYM_Control_R:
1697 new_modifier = KMOD_Control_R;
1700 new_modifier = KMOD_Meta_L;
1703 new_modifier = KMOD_Meta_R;
1706 new_modifier = KMOD_Alt_L;
1709 new_modifier = KMOD_Alt_R;
1715 if (key_status == KEY_PRESSED)
1716 current_modifiers |= new_modifier;
1718 current_modifiers &= ~new_modifier;
1721 return current_modifiers;
1724 KeyMod GetKeyModState()
1726 #if defined(TARGET_SDL)
1727 return (KeyMod)SDL_GetModState();
1729 return HandleKeyModState(KSYM_UNDEFINED, 0);
1733 KeyMod GetKeyModStateFromEvents()
1735 /* always use key modifier state as tracked from key events (this is needed
1736 if the modifier key event was injected into the event queue, but the key
1737 was not really pressed on keyboard -- SDL_GetModState() seems to directly
1738 query the keys as held pressed on the keyboard) -- this case is currently
1739 only used to filter out clipboard insert events from "True X-Mouse" tool */
1741 return HandleKeyModState(KSYM_UNDEFINED, 0);
1744 boolean CheckCloseWindowEvent(ClientMessageEvent *event)
1746 if (event->type != EVENT_CLIENTMESSAGE)
1749 #if defined(TARGET_SDL)
1750 return TRUE; /* the only possible message here is SDL_QUIT */
1751 #elif defined(PLATFORM_UNIX)
1752 if ((event->window == window->drawable) &&
1753 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
1761 /* ========================================================================= */
1762 /* joystick functions */
1763 /* ========================================================================= */
1765 void InitJoysticks()
1769 #if defined(NO_JOYSTICK)
1770 return; /* joysticks generally deactivated by compile-time directive */
1773 /* always start with reliable default values */
1774 joystick.status = JOYSTICK_NOT_AVAILABLE;
1775 for (i = 0; i < MAX_PLAYERS; i++)
1776 joystick.fd[i] = -1; /* joystick device closed */
1778 #if defined(TARGET_SDL)
1780 #elif defined(PLATFORM_UNIX)
1781 UnixInitJoysticks();
1782 #elif defined(PLATFORM_MSDOS)
1783 MSDOSInitJoysticks();
1787 for (i = 0; i < MAX_PLAYERS; i++)
1788 printf("::: Joystick for player %d: %d\n", i, joystick.fd[i]);
1792 boolean ReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1794 #if defined(TARGET_SDL)
1795 return SDLReadJoystick(nr, x, y, b1, b2);
1796 #elif defined(PLATFORM_UNIX)
1797 return UnixReadJoystick(nr, x, y, b1, b2);
1798 #elif defined(PLATFORM_MSDOS)
1799 return MSDOSReadJoystick(nr, x, y, b1, b2);