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();
135 #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
140 #if defined(TARGET_SDL)
141 if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
142 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
148 void ClosePlatformDependentStuff(void)
150 #if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
154 #if defined(PLATFORM_MSDOS)
159 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
160 int real_sx, int real_sy,
161 int full_sxsize, int full_sysize,
162 Bitmap *field_save_buffer)
168 gfx.real_sx = real_sx;
169 gfx.real_sy = real_sy;
170 gfx.full_sxsize = full_sxsize;
171 gfx.full_sysize = full_sysize;
173 gfx.field_save_buffer = field_save_buffer;
176 gfx.background_bitmap = NULL;
177 gfx.background_bitmap_mask = REDRAW_NONE;
180 SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
181 SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
184 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
192 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
200 void InitGfxWindowInfo(int win_xsize, int win_ysize)
202 gfx.win_xsize = win_xsize;
203 gfx.win_ysize = win_ysize;
206 gfx.background_bitmap_mask = REDRAW_NONE;
208 ReCreateBitmap(&gfx.background_bitmap, win_xsize, win_ysize, DEFAULT_DEPTH);
212 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
214 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
215 /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
216 gfx.scrollbuffer_width = scrollbuffer_width;
217 gfx.scrollbuffer_height = scrollbuffer_height;
220 void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height)
222 gfx.clipping_enabled = enabled;
225 gfx.clip_width = width;
226 gfx.clip_height = height;
229 void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void))
231 gfx.draw_busy_anim_function = draw_busy_anim_function;
234 void InitGfxCustomArtworkInfo()
236 gfx.override_level_graphics = FALSE;
237 gfx.override_level_sounds = FALSE;
238 gfx.override_level_music = FALSE;
240 gfx.draw_init_text = TRUE;
243 void SetDrawDeactivationMask(int draw_deactivation_mask)
245 gfx.draw_deactivation_mask = draw_deactivation_mask;
248 void SetDrawBackgroundMask(int draw_background_mask)
250 gfx.draw_background_mask = draw_background_mask;
255 static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
256 int dest_x, int dest_y, int width, int height)
258 int bitmap_xsize = width;
259 int bitmap_ysize = height;
260 int tile_xsize = tile->width;
261 int tile_ysize = tile->height;
262 int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
263 int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
266 for (y = 0; y < tile_ysteps; y++)
268 for (x = 0; x < tile_xsteps; x++)
270 int draw_x = dest_x + x * tile_xsize;
271 int draw_y = dest_y + y * tile_ysize;
272 int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
273 int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
275 BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
280 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
282 if (background_bitmap_tile != NULL)
283 gfx.background_bitmap_mask |= mask;
285 gfx.background_bitmap_mask &= ~mask;
288 if (gfx.background_bitmap == NULL)
289 gfx.background_bitmap = CreateBitmap(video.width, video.height,
293 if (background_bitmap_tile == NULL) /* empty background requested */
296 if (mask == REDRAW_ALL)
297 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
298 0, 0, video.width, video.height);
299 else if (mask == REDRAW_FIELD)
300 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
301 gfx.real_sx, gfx.real_sy,
302 gfx.full_sxsize, gfx.full_sysize);
303 else if (mask == REDRAW_DOOR_1)
305 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
307 gfx.dxsize, gfx.dysize);
313 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
315 if (background_bitmap_tile != NULL)
316 gfx.background_bitmap_mask |= mask;
318 gfx.background_bitmap_mask &= ~mask;
321 if (gfx.background_bitmap == NULL)
322 gfx.background_bitmap = CreateBitmap(video.width, video.height,
326 if (background_bitmap_tile == NULL) /* empty background requested */
329 if (mask == REDRAW_ALL)
330 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
331 0, 0, video.width, video.height);
332 else if (mask == REDRAW_FIELD)
333 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
334 gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize);
335 else if (mask == REDRAW_DOOR_1)
337 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
338 gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize);
344 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
346 /* remove every mask before setting mask for window */
347 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
348 SetBackgroundBitmap(NULL, 0xffff); /* !!! FIX THIS !!! */
349 SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
352 void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
354 /* remove window area mask before setting mask for main area */
355 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
356 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
357 SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
360 void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
362 /* remove window area mask before setting mask for door area */
363 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
364 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
365 SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
369 /* ========================================================================= */
370 /* video functions */
371 /* ========================================================================= */
373 inline static int GetRealDepth(int depth)
375 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
378 inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
379 int width, int height, Pixel color)
381 #if defined(TARGET_SDL)
382 SDLFillRectangle(bitmap, x, y, width, height, color);
384 X11FillRectangle(bitmap, x, y, width, height, color);
388 inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
389 int src_x, int src_y, int width, int height,
390 int dst_x, int dst_y, int mask_mode)
392 #if defined(TARGET_SDL)
393 SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
394 dst_x, dst_y, mask_mode);
396 X11CopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
397 dst_x, dst_y, mask_mode);
401 void InitVideoDisplay(void)
403 #if defined(TARGET_SDL)
404 SDLInitVideoDisplay();
406 X11InitVideoDisplay();
410 void CloseVideoDisplay(void)
412 KeyboardAutoRepeatOn();
414 #if defined(TARGET_SDL)
415 SDL_QuitSubSystem(SDL_INIT_VIDEO);
418 XCloseDisplay(display);
422 void InitVideoBuffer(int width, int height, int depth, boolean fullscreen)
425 video.height = height;
426 video.depth = GetRealDepth(depth);
428 video.fullscreen_available = FULLSCREEN_STATUS;
429 video.fullscreen_enabled = FALSE;
431 video.fullscreen_mode_current = NULL;
432 video.fullscreen_modes = NULL;
435 #if defined(TARGET_SDL)
436 SDLInitVideoBuffer(&backbuffer, &window, fullscreen);
438 X11InitVideoBuffer(&backbuffer, &window);
444 inline static void FreeBitmapPointers(Bitmap *bitmap)
449 #if defined(TARGET_SDL)
450 SDLFreeBitmapPointers(bitmap);
452 X11FreeBitmapPointers(bitmap);
455 checked_free(bitmap->source_filename);
456 bitmap->source_filename = NULL;
459 inline static void TransferBitmapPointers(Bitmap *src_bitmap,
462 if (src_bitmap == NULL || dst_bitmap == NULL)
465 FreeBitmapPointers(dst_bitmap);
467 *dst_bitmap = *src_bitmap;
470 void FreeBitmap(Bitmap *bitmap)
475 FreeBitmapPointers(bitmap);
480 Bitmap *CreateBitmapStruct(void)
482 #if defined(TARGET_SDL)
483 return checked_calloc(sizeof(struct SDLSurfaceInfo));
485 return checked_calloc(sizeof(struct X11DrawableInfo));
489 Bitmap *CreateBitmap(int width, int height, int depth)
491 Bitmap *new_bitmap = CreateBitmapStruct();
492 int real_width = MAX(1, width); /* prevent zero bitmap width */
493 int real_height = MAX(1, height); /* prevent zero bitmap height */
494 int real_depth = GetRealDepth(depth);
496 #if defined(TARGET_SDL)
497 SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
499 X11CreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
502 new_bitmap->width = real_width;
503 new_bitmap->height = real_height;
508 void ReCreateBitmap(Bitmap **bitmap, int width, int height, int depth)
510 Bitmap *new_bitmap = CreateBitmap(width, height, depth);
514 *bitmap = new_bitmap;
518 TransferBitmapPointers(new_bitmap, *bitmap);
523 void CloseWindow(DrawWindow *window)
525 #if defined(TARGET_X11)
526 X11CloseWindow(window);
530 inline static boolean CheckDrawingArea(int x, int y, int width, int height,
533 if (draw_mask == REDRAW_NONE)
536 if (draw_mask & REDRAW_ALL)
539 if ((draw_mask & REDRAW_FIELD) &&
540 x >= gfx.real_sx && x < gfx.real_sx + gfx.full_sxsize)
543 if ((draw_mask & REDRAW_DOOR_1) &&
544 x >= gfx.dx && y < gfx.dy + gfx.dysize)
547 if ((draw_mask & REDRAW_DOOR_2) &&
548 x >= gfx.dx && y >= gfx.vy)
554 boolean DrawingDeactivated(int x, int y, int width, int height)
556 return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask);
559 boolean DrawingOnBackground(int x, int y)
561 return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) &&
562 CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
565 static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y,
566 int *width, int *height, boolean is_dest)
569 int clip_x, clip_y, clip_width, clip_height;
571 if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */
573 clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width);
574 clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height);
575 clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x);
576 clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y);
582 clip_width = bitmap->width;
583 clip_height = bitmap->height;
586 /* skip if rectangle completely outside bitmap */
588 if (*x + *width <= clip_x ||
589 *y + *height <= clip_y ||
590 *x >= clip_x + clip_width ||
591 *y >= clip_y + clip_height)
594 /* clip if rectangle overlaps bitmap */
598 *width -= clip_x - *x;
601 else if (*x + *width > clip_x + clip_width)
603 *width = clip_x + clip_width - *x;
608 *height -= clip_y - *y;
611 else if (*y + *height > clip_y + clip_height)
613 *height = clip_y + clip_height - *y;
620 /* skip if rectangle completely outside bitmap */
622 if (*x + *width <= 0 ||
624 *x >= bitmap->width ||
625 *y >= bitmap->height)
628 /* clip if rectangle overlaps bitmap */
635 else if (*x + *width > bitmap->width)
637 *width = bitmap->width - *x;
645 else if (*y + *height > bitmap->height)
647 *height = bitmap->height - *y;
654 void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
655 int src_x, int src_y, int width, int height,
656 int dst_x, int dst_y)
658 int dst_x_unclipped = dst_x;
659 int dst_y_unclipped = dst_y;
661 if (DrawingDeactivated(dst_x, dst_y, width, height))
665 if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) ||
666 !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE))
669 /* source x/y might need adjustment if destination x/y was clipped top/left */
670 src_x += dst_x - dst_x_unclipped;
671 src_y += dst_y - dst_y_unclipped;
674 /* skip if rectangle starts outside bitmap */
675 if (src_x >= src_bitmap->width ||
676 src_y >= src_bitmap->height ||
677 dst_x >= dst_bitmap->width ||
678 dst_y >= dst_bitmap->height)
681 /* clip if rectangle overlaps bitmap */
682 if (src_x + width > src_bitmap->width)
683 width = src_bitmap->width - src_x;
684 if (src_y + height > src_bitmap->height)
685 height = src_bitmap->height - src_y;
686 if (dst_x + width > dst_bitmap->width)
687 width = dst_bitmap->width - dst_x;
688 if (dst_y + height > dst_bitmap->height)
689 height = dst_bitmap->height - dst_y;
693 /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
694 /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
695 but is already fixed in SVN and should therefore finally be fixed with
696 the next official SDL release, which is probably version 1.2.14.) */
698 /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
699 #if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
700 if (src_bitmap == dst_bitmap)
702 /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
704 /* needed when blitting directly to same bitmap -- should not be needed with
705 recent SDL libraries, but apparently does not work in 1.2.11 directly */
707 static Bitmap *tmp_bitmap = NULL;
708 static int tmp_bitmap_xsize = 0;
709 static int tmp_bitmap_ysize = 0;
711 /* start with largest static bitmaps for initial bitmap size ... */
712 if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
714 tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
715 tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
718 /* ... and allow for later re-adjustments due to custom artwork bitmaps */
719 if (src_bitmap->width > tmp_bitmap_xsize ||
720 src_bitmap->height > tmp_bitmap_ysize)
722 tmp_bitmap_xsize = MAX(tmp_bitmap_xsize, src_bitmap->width);
723 tmp_bitmap_ysize = MAX(tmp_bitmap_ysize, src_bitmap->height);
725 FreeBitmap(tmp_bitmap);
730 if (tmp_bitmap == NULL)
731 tmp_bitmap = CreateBitmap(tmp_bitmap_xsize, tmp_bitmap_ysize,
734 sysCopyArea(src_bitmap, tmp_bitmap,
735 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
736 sysCopyArea(tmp_bitmap, dst_bitmap,
737 dst_x, dst_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
746 if (dst_x < gfx.sx + gfx.sxsize)
747 printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n",
748 FrameCounter, dst_x, dst_y, width, height);
751 sysCopyArea(src_bitmap, dst_bitmap,
752 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
755 void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap,
756 int src_x, int src_y, int src_width, int src_height,
757 int dst_x, int dst_y, int dst_width, int dst_height)
759 int src_xsize = (src_width == 0 ? src_bitmap->width : src_width);
760 int src_ysize = (src_height == 0 ? src_bitmap->height : src_height);
761 int dst_xsize = dst_width;
762 int dst_ysize = dst_height;
763 int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize;
764 int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize;
767 for (y = 0; y < src_ysteps; y++)
769 for (x = 0; x < src_xsteps; x++)
771 int draw_x = dst_x + x * src_xsize;
772 int draw_y = dst_y + y * src_ysize;
773 int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize);
774 int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize);
776 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize,
782 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
783 int fade_mode, int fade_delay, int post_delay,
784 void (*draw_border_function)(void))
787 /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */
788 if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE))
792 #if defined(TARGET_SDL)
793 SDLFadeRectangle(bitmap_cross, x, y, width, height,
794 fade_mode, fade_delay, post_delay, draw_border_function);
796 X11FadeRectangle(bitmap_cross, x, y, width, height,
797 fade_mode, fade_delay, post_delay, draw_border_function);
801 void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height,
804 if (DrawingDeactivated(x, y, width, height))
808 if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE))
811 /* skip if rectangle starts outside bitmap */
812 if (x >= bitmap->width ||
816 /* clip if rectangle overlaps bitmap */
817 if (x + width > bitmap->width)
818 width = bitmap->width - x;
819 if (y + height > bitmap->height)
820 height = bitmap->height - y;
823 sysFillRectangle(bitmap, x, y, width, height, color);
826 void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
828 FillRectangle(bitmap, x, y, width, height, BLACK_PIXEL);
831 void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
832 int width, int height)
834 if (DrawingOnBackground(x, y))
835 BlitBitmap(gfx.background_bitmap, bitmap, x, y, width, height, x, y);
837 ClearRectangle(bitmap, x, y, width, height);
840 void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
842 #if defined(TARGET_X11)
845 bitmap->clip_gc = clip_gc;
846 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
851 void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
853 #if defined(TARGET_X11)
856 bitmap->clip_gc = clip_gc;
857 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
862 void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
863 int src_x, int src_y, int width, int height,
864 int dst_x, int dst_y)
866 if (DrawingDeactivated(dst_x, dst_y, width, height))
869 sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
870 dst_x, dst_y, BLIT_MASKED);
873 void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap,
874 int src_x, int src_y, int width, int height,
875 int dst_x, int dst_y)
877 if (DrawingOnBackground(dst_x, dst_y))
879 /* draw background */
880 BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
883 /* draw foreground */
884 SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
885 dst_x - src_x, dst_y - src_y);
886 BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
890 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
894 void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y,
897 #if defined(TARGET_SDL)
898 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
900 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
904 void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
907 #if defined(TARGET_SDL)
908 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
910 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
914 #if !defined(TARGET_X11_NATIVE)
915 void DrawLine(Bitmap *bitmap, int from_x, int from_y,
916 int to_x, int to_y, Pixel pixel, int line_width)
920 for (x = 0; x < line_width; x++)
922 for (y = 0; y < line_width; y++)
924 int dx = x - line_width / 2;
925 int dy = y - line_width / 2;
927 if ((x == 0 && y == 0) ||
928 (x == 0 && y == line_width - 1) ||
929 (x == line_width - 1 && y == 0) ||
930 (x == line_width - 1 && y == line_width - 1))
933 #if defined(TARGET_SDL)
935 from_x + dx, from_y + dy, to_x + dx, to_y + dy, pixel);
936 #elif defined(TARGET_ALLEGRO)
937 AllegroDrawLine(bitmap->drawable, from_x + dx, from_y + dy,
938 to_x + dx, to_y + dy, pixel);
945 void DrawLines(Bitmap *bitmap, struct XY *points, int num_points, Pixel pixel)
947 #if !defined(TARGET_X11_NATIVE)
951 for (i = 0; i < num_points - 1; i++)
952 DrawLine(bitmap, points[i].x, points[i].y,
953 points[i + 1].x, points[i + 1].y, pixel, line_width);
956 SDLDrawLines(bitmap->surface, points, num_points, pixel);
959 XSetForeground(display, bitmap->line_gc[1], pixel);
960 XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
961 (XPoint *)points, num_points, CoordModeOrigin);
965 Pixel GetPixel(Bitmap *bitmap, int x, int y)
967 if (x < 0 || x >= bitmap->width ||
968 y < 0 || y >= bitmap->height)
971 #if defined(TARGET_SDL)
972 return SDLGetPixel(bitmap, x, y);
973 #elif defined(TARGET_ALLEGRO)
974 return AllegroGetPixel(bitmap->drawable, x, y);
976 return X11GetPixel(bitmap, x, y);
980 Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
981 unsigned int color_g, unsigned int color_b)
983 #if defined(TARGET_SDL)
984 return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
985 #elif defined(TARGET_ALLEGRO)
986 return AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
988 return X11GetPixelFromRGB(color_r, color_g, color_b);
992 Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
994 unsigned int color_r = (color >> 16) & 0xff;
995 unsigned int color_g = (color >> 8) & 0xff;
996 unsigned int color_b = (color >> 0) & 0xff;
998 return GetPixelFromRGB(bitmap, color_r, color_g, color_b);
1001 /* execute all pending screen drawing operations */
1002 void FlushDisplay(void)
1009 /* execute and wait for all pending screen drawing operations */
1010 void SyncDisplay(void)
1013 XSync(display, FALSE);
1017 void KeyboardAutoRepeatOn(void)
1019 #if defined(TARGET_SDL)
1020 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
1021 SDL_DEFAULT_REPEAT_INTERVAL / 2);
1022 SDL_EnableUNICODE(1);
1025 XAutoRepeatOn(display);
1029 void KeyboardAutoRepeatOff(void)
1031 #if defined(TARGET_SDL)
1032 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
1033 SDL_EnableUNICODE(0);
1036 XAutoRepeatOff(display);
1040 boolean PointerInWindow(DrawWindow *window)
1042 #if defined(TARGET_SDL)
1050 /* if XQueryPointer() returns False, the pointer
1051 is not on the same screen as the specified window */
1052 return XQueryPointer(display, window->drawable, &root, &child,
1053 &root_x, &root_y, &win_x, &win_y, &mask);
1057 boolean SetVideoMode(boolean fullscreen)
1059 #if defined(TARGET_SDL)
1060 return SDLSetVideoMode(&backbuffer, fullscreen);
1062 boolean success = TRUE;
1064 if (fullscreen && video.fullscreen_available)
1066 Error(ERR_WARN, "fullscreen not available in X11 version");
1068 /* display error message only once */
1069 video.fullscreen_available = FALSE;
1078 boolean ChangeVideoModeIfNeeded(boolean fullscreen)
1080 #if defined(TARGET_SDL)
1081 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
1082 (!fullscreen && video.fullscreen_enabled))
1083 fullscreen = SetVideoMode(fullscreen);
1089 Bitmap *LoadImage(char *filename)
1093 #if defined(TARGET_SDL)
1094 new_bitmap = SDLLoadImage(filename);
1096 new_bitmap = X11LoadImage(filename);
1100 new_bitmap->source_filename = getStringCopy(filename);
1105 Bitmap *LoadCustomImage(char *basename)
1107 char *filename = getCustomImageFilename(basename);
1110 if (filename == NULL)
1111 Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
1113 if ((new_bitmap = LoadImage(filename)) == NULL)
1114 Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
1119 void ReloadCustomImage(Bitmap *bitmap, char *basename)
1121 char *filename = getCustomImageFilename(basename);
1124 if (filename == NULL) /* (should never happen) */
1126 Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
1130 if (strEqual(filename, bitmap->source_filename))
1132 /* The old and new image are the same (have the same filename and path).
1133 This usually means that this image does not exist in this graphic set
1134 and a fallback to the existing image is done. */
1139 if ((new_bitmap = LoadImage(filename)) == NULL)
1141 Error(ERR_WARN, "LoadImage() failed: %s", GetError());
1145 if (bitmap->width != new_bitmap->width ||
1146 bitmap->height != new_bitmap->height)
1148 Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
1150 FreeBitmap(new_bitmap);
1154 TransferBitmapPointers(new_bitmap, bitmap);
1158 Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
1160 Bitmap *dst_bitmap = CreateBitmap(zoom_width, zoom_height, DEFAULT_DEPTH);
1162 #if defined(TARGET_SDL)
1163 SDLZoomBitmap(src_bitmap, dst_bitmap);
1165 X11ZoomBitmap(src_bitmap, dst_bitmap);
1171 static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
1172 boolean create_small_bitmaps)
1176 Bitmap *tmp_bitmap_1;
1177 Bitmap *tmp_bitmap_2;
1178 Bitmap *tmp_bitmap_4;
1179 Bitmap *tmp_bitmap_8;
1180 Bitmap *tmp_bitmap_16;
1181 Bitmap *tmp_bitmap_32;
1182 int width_1, height_1;
1183 int width_2, height_2;
1184 int width_4, height_4;
1185 int width_8, height_8;
1186 int width_16, height_16;
1188 int width_32, height_32;
1190 int new_width, new_height;
1192 /* calculate new image dimensions for normal sized image */
1193 width_1 = old_bitmap->width * zoom_factor;
1194 height_1 = old_bitmap->height * zoom_factor;
1196 /* get image with normal size (this might require scaling up) */
1197 if (zoom_factor != 1)
1198 tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
1200 tmp_bitmap_1 = old_bitmap;
1202 /* this is only needed to make compilers happy */
1203 tmp_bitmap_2 = NULL;
1204 tmp_bitmap_4 = NULL;
1205 tmp_bitmap_8 = NULL;
1206 tmp_bitmap_16 = NULL;
1207 tmp_bitmap_32 = NULL;
1209 if (create_small_bitmaps)
1211 /* calculate new image dimensions for small images */
1212 width_2 = width_1 / 2;
1213 height_2 = height_1 / 2;
1214 width_4 = width_1 / 4;
1215 height_4 = height_1 / 4;
1216 width_8 = width_1 / 8;
1217 height_8 = height_1 / 8;
1218 width_16 = width_1 / 16;
1219 height_16 = height_1 / 16;
1221 width_32 = width_1 / 32;
1222 height_32 = height_1 / 32;
1225 UPDATE_BUSY_STATE();
1227 /* get image with 1/2 of normal size (for use in the level editor) */
1228 if (zoom_factor != 2)
1229 tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
1231 tmp_bitmap_2 = old_bitmap;
1233 UPDATE_BUSY_STATE();
1235 /* get image with 1/4 of normal size (for use in the level editor) */
1236 if (zoom_factor != 4)
1237 tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2);
1239 tmp_bitmap_4 = old_bitmap;
1241 UPDATE_BUSY_STATE();
1243 /* get image with 1/8 of normal size (for use on the preview screen) */
1244 if (zoom_factor != 8)
1245 tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2);
1247 tmp_bitmap_8 = old_bitmap;
1249 UPDATE_BUSY_STATE();
1251 /* get image with 1/16 of normal size (for use on the preview screen) */
1252 if (zoom_factor != 16)
1253 tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2);
1255 tmp_bitmap_16 = old_bitmap;
1257 UPDATE_BUSY_STATE();
1259 /* get image with 1/32 of normal size (for use on the preview screen) */
1260 if (zoom_factor != 32)
1261 tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2);
1263 tmp_bitmap_32 = old_bitmap;
1265 UPDATE_BUSY_STATE();
1269 /* if image was scaled up, create new clipmask for normal size image */
1270 if (zoom_factor != 1)
1272 #if defined(TARGET_X11)
1273 if (old_bitmap->clip_mask)
1274 XFreePixmap(display, old_bitmap->clip_mask);
1276 old_bitmap->clip_mask =
1277 Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
1279 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1281 SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
1283 if (old_bitmap->surface_masked)
1284 SDL_FreeSurface(old_bitmap->surface_masked);
1286 SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
1287 SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
1288 if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
1289 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1290 SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
1295 if (create_small_bitmaps)
1297 new_width = width_1;
1298 new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
1300 new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
1302 BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
1303 BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
1305 BlitBitmap(tmp_bitmap_4, new_bitmap, 0, 0, width_1 / 4, height_1 / 4,
1306 width_1 / 2, height_1);
1307 BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
1308 3 * width_1 / 4, height_1);
1309 BlitBitmap(tmp_bitmap_16, new_bitmap, 0, 0, width_1 / 16, height_1 / 16,
1310 7 * width_1 / 8, height_1);
1311 BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32,
1312 15 * width_1 / 16, height_1);
1314 UPDATE_BUSY_STATE();
1318 new_width = width_1;
1319 new_height = height_1;
1321 new_bitmap = tmp_bitmap_1; /* directly use tmp_bitmap_1 as new bitmap */
1324 if (create_small_bitmaps)
1326 /* if no small bitmaps created, tmp_bitmap_1 is used as new bitmap now */
1327 if (zoom_factor != 1)
1328 FreeBitmap(tmp_bitmap_1);
1330 if (zoom_factor != 2)
1331 FreeBitmap(tmp_bitmap_2);
1333 if (zoom_factor != 4)
1334 FreeBitmap(tmp_bitmap_4);
1336 if (zoom_factor != 8)
1337 FreeBitmap(tmp_bitmap_8);
1339 if (zoom_factor != 16)
1340 FreeBitmap(tmp_bitmap_16);
1342 if (zoom_factor != 32)
1343 FreeBitmap(tmp_bitmap_32);
1346 /* replace image with extended image (containing 1/1, 1/2, 1/4, 1/8 size) */
1347 #if defined(TARGET_SDL)
1348 swap_bitmap.surface = old_bitmap->surface;
1349 old_bitmap->surface = new_bitmap->surface;
1350 new_bitmap->surface = swap_bitmap.surface;
1352 swap_bitmap.drawable = old_bitmap->drawable;
1353 old_bitmap->drawable = new_bitmap->drawable;
1354 new_bitmap->drawable = swap_bitmap.drawable;
1357 old_bitmap->width = new_bitmap->width;
1358 old_bitmap->height = new_bitmap->height;
1361 /* this replaces all blit masks created when loading -- maybe optimize this */
1363 #if defined(TARGET_X11)
1364 if (old_bitmap->clip_mask)
1365 XFreePixmap(display, old_bitmap->clip_mask);
1367 old_bitmap->clip_mask =
1368 Pixmap_to_Mask(old_bitmap->drawable, new_width, new_height);
1370 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1372 SDL_Surface *old_surface = old_bitmap->surface;
1374 if (old_bitmap->surface_masked)
1375 SDL_FreeSurface(old_bitmap->surface_masked);
1377 SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
1378 SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
1379 if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
1380 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1381 SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */
1386 UPDATE_BUSY_STATE();
1388 FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */
1391 void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
1393 CreateScaledBitmaps(old_bitmap, zoom_factor, TRUE);
1396 void ScaleBitmap(Bitmap *old_bitmap, int zoom_factor)
1398 CreateScaledBitmaps(old_bitmap, zoom_factor, FALSE);
1402 /* ------------------------------------------------------------------------- */
1403 /* mouse pointer functions */
1404 /* ------------------------------------------------------------------------- */
1406 #if !defined(PLATFORM_MSDOS)
1407 #define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
1408 /* XPM image definitions */
1409 static const char *cursor_image_none[] =
1411 /* width height num_colors chars_per_pixel */
1440 #if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
1441 static const char *cursor_image_dot[] =
1443 /* width height num_colors chars_per_pixel */
1472 static const char **cursor_image_playfield = cursor_image_dot;
1474 /* some people complained about a "white dot" on the screen and thought it
1475 was a graphical error... OK, let's just remove the whole pointer :-) */
1476 static const char **cursor_image_playfield = cursor_image_none;
1479 #if defined(TARGET_SDL)
1480 static const int cursor_bit_order = BIT_ORDER_MSB;
1481 #elif defined(TARGET_X11_NATIVE)
1482 static const int cursor_bit_order = BIT_ORDER_LSB;
1485 static struct MouseCursorInfo *get_cursor_from_image(const char **image)
1487 struct MouseCursorInfo *cursor;
1488 boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
1489 int header_lines = 4;
1492 cursor = checked_calloc(sizeof(struct MouseCursorInfo));
1494 sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
1497 for (y = 0; y < cursor->width; y++)
1499 for (x = 0; x < cursor->height; x++)
1502 int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
1507 cursor->data[i] = cursor->mask[i] = 0;
1510 switch (image[header_lines + y][x])
1513 cursor->data[i] |= bit_mask;
1514 cursor->mask[i] |= bit_mask;
1518 cursor->mask[i] |= bit_mask;
1527 sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
1531 #endif /* !PLATFORM_MSDOS */
1533 void SetMouseCursor(int mode)
1535 #if !defined(PLATFORM_MSDOS)
1536 static struct MouseCursorInfo *cursor_none = NULL;
1537 static struct MouseCursorInfo *cursor_playfield = NULL;
1538 struct MouseCursorInfo *cursor_new;
1540 if (cursor_none == NULL)
1541 cursor_none = get_cursor_from_image(cursor_image_none);
1543 if (cursor_playfield == NULL)
1544 cursor_playfield = get_cursor_from_image(cursor_image_playfield);
1546 cursor_new = (mode == CURSOR_DEFAULT ? NULL :
1547 mode == CURSOR_NONE ? cursor_none :
1548 mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
1550 #if defined(TARGET_SDL)
1551 SDLSetMouseCursor(cursor_new);
1552 #elif defined(TARGET_X11_NATIVE)
1553 X11SetMouseCursor(cursor_new);
1559 /* ========================================================================= */
1560 /* audio functions */
1561 /* ========================================================================= */
1563 void OpenAudio(void)
1565 /* always start with reliable default values */
1566 audio.sound_available = FALSE;
1567 audio.music_available = FALSE;
1568 audio.loops_available = FALSE;
1570 audio.sound_enabled = FALSE;
1571 audio.sound_deactivated = FALSE;
1573 audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
1574 audio.mixer_pid = 0;
1575 audio.device_name = NULL;
1576 audio.device_fd = -1;
1578 audio.num_channels = 0;
1579 audio.music_channel = 0;
1580 audio.first_sound_channel = 0;
1582 #if defined(TARGET_SDL)
1584 #elif defined(PLATFORM_UNIX)
1586 #elif defined(PLATFORM_MSDOS)
1591 void CloseAudio(void)
1593 #if defined(TARGET_SDL)
1595 #elif defined(PLATFORM_UNIX)
1597 #elif defined(PLATFORM_MSDOS)
1601 audio.sound_enabled = FALSE;
1604 void SetAudioMode(boolean enabled)
1606 if (!audio.sound_available)
1609 audio.sound_enabled = enabled;
1613 /* ========================================================================= */
1614 /* event functions */
1615 /* ========================================================================= */
1617 void InitEventFilter(EventFilter filter_function)
1619 #if defined(TARGET_SDL)
1620 /* set event filter to filter out certain events */
1621 SDL_SetEventFilter(filter_function);
1625 boolean PendingEvent(void)
1627 #if defined(TARGET_SDL)
1628 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
1630 return (XPending(display) ? TRUE : FALSE);
1634 void NextEvent(Event *event)
1636 #if defined(TARGET_SDL)
1637 SDLNextEvent(event);
1639 XNextEvent(display, event);
1643 void PeekEvent(Event *event)
1645 #if defined(TARGET_SDL)
1646 SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
1648 XPeekEvent(display, event);
1652 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
1654 #if defined(TARGET_SDL)
1657 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
1658 (int)event->keysym.unicode,
1659 (int)event->keysym.sym,
1660 (int)SDL_GetModState());
1663 if (with_modifiers &&
1664 event->keysym.unicode > 0x0000 &&
1665 event->keysym.unicode < 0x2000)
1666 return event->keysym.unicode;
1668 return event->keysym.sym;
1673 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
1674 (int)XLookupKeysym(event, event->state),
1675 (int)XLookupKeysym(event, 0));
1679 return XLookupKeysym(event, event->state);
1681 return XLookupKeysym(event, 0);
1685 KeyMod HandleKeyModState(Key key, int key_status)
1687 static KeyMod current_modifiers = KMOD_None;
1689 if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
1691 KeyMod new_modifier = KMOD_None;
1696 new_modifier = KMOD_Shift_L;
1699 new_modifier = KMOD_Shift_R;
1701 case KSYM_Control_L:
1702 new_modifier = KMOD_Control_L;
1704 case KSYM_Control_R:
1705 new_modifier = KMOD_Control_R;
1708 new_modifier = KMOD_Meta_L;
1711 new_modifier = KMOD_Meta_R;
1714 new_modifier = KMOD_Alt_L;
1717 new_modifier = KMOD_Alt_R;
1723 if (key_status == KEY_PRESSED)
1724 current_modifiers |= new_modifier;
1726 current_modifiers &= ~new_modifier;
1729 return current_modifiers;
1732 KeyMod GetKeyModState()
1734 #if defined(TARGET_SDL)
1735 return (KeyMod)SDL_GetModState();
1737 return HandleKeyModState(KSYM_UNDEFINED, 0);
1741 KeyMod GetKeyModStateFromEvents()
1743 /* always use key modifier state as tracked from key events (this is needed
1744 if the modifier key event was injected into the event queue, but the key
1745 was not really pressed on keyboard -- SDL_GetModState() seems to directly
1746 query the keys as held pressed on the keyboard) -- this case is currently
1747 only used to filter out clipboard insert events from "True X-Mouse" tool */
1749 return HandleKeyModState(KSYM_UNDEFINED, 0);
1752 boolean CheckCloseWindowEvent(ClientMessageEvent *event)
1754 if (event->type != EVENT_CLIENTMESSAGE)
1757 #if defined(TARGET_SDL)
1758 return TRUE; /* the only possible message here is SDL_QUIT */
1759 #elif defined(PLATFORM_UNIX)
1760 if ((event->window == window->drawable) &&
1761 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
1769 /* ========================================================================= */
1770 /* joystick functions */
1771 /* ========================================================================= */
1773 void InitJoysticks()
1777 #if defined(NO_JOYSTICK)
1778 return; /* joysticks generally deactivated by compile-time directive */
1781 /* always start with reliable default values */
1782 joystick.status = JOYSTICK_NOT_AVAILABLE;
1783 for (i = 0; i < MAX_PLAYERS; i++)
1784 joystick.fd[i] = -1; /* joystick device closed */
1786 #if defined(TARGET_SDL)
1788 #elif defined(PLATFORM_UNIX)
1789 UnixInitJoysticks();
1790 #elif defined(PLATFORM_MSDOS)
1791 MSDOSInitJoysticks();
1795 for (i = 0; i < MAX_PLAYERS; i++)
1796 printf("::: Joystick for player %d: %d\n", i, joystick.fd[i]);
1800 boolean ReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1802 #if defined(TARGET_SDL)
1803 return SDLReadJoystick(nr, x, y, b1, b2);
1804 #elif defined(PLATFORM_UNIX)
1805 return UnixReadJoystick(nr, x, y, b1, b2);
1806 #elif defined(PLATFORM_MSDOS)
1807 return MSDOSReadJoystick(nr, x, y, b1, b2);