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 InitExitMessageFunction(void (*exit_message_function)(char *, va_list))
110 program.exit_message_function = exit_message_function;
113 void InitExitFunction(void (*exit_function)(int))
115 program.exit_function = exit_function;
117 /* set signal handlers to custom exit function */
118 signal(SIGINT, exit_function);
119 signal(SIGTERM, exit_function);
121 #if defined(TARGET_SDL)
122 /* set exit function to automatically cleanup SDL stuff after exit() */
127 void InitPlatformDependentStuff(void)
129 #if defined(PLATFORM_MSDOS)
133 #if defined(PLATFORM_MACOSX)
134 updateUserGameDataDir();
140 #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
145 #if defined(TARGET_SDL)
146 if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
147 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
153 void ClosePlatformDependentStuff(void)
155 #if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
159 #if defined(PLATFORM_MSDOS)
164 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
165 int real_sx, int real_sy,
166 int full_sxsize, int full_sysize,
167 Bitmap *field_save_buffer)
173 gfx.real_sx = real_sx;
174 gfx.real_sy = real_sy;
175 gfx.full_sxsize = full_sxsize;
176 gfx.full_sysize = full_sysize;
178 gfx.field_save_buffer = field_save_buffer;
181 gfx.background_bitmap = NULL;
182 gfx.background_bitmap_mask = REDRAW_NONE;
185 SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
186 SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
189 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
197 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
205 void InitGfxWindowInfo(int win_xsize, int win_ysize)
207 gfx.win_xsize = win_xsize;
208 gfx.win_ysize = win_ysize;
211 gfx.background_bitmap_mask = REDRAW_NONE;
213 ReCreateBitmap(&gfx.background_bitmap, win_xsize, win_ysize, DEFAULT_DEPTH);
217 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
219 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
220 /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
221 gfx.scrollbuffer_width = scrollbuffer_width;
222 gfx.scrollbuffer_height = scrollbuffer_height;
225 void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height)
227 gfx.clipping_enabled = enabled;
230 gfx.clip_width = width;
231 gfx.clip_height = height;
234 void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void))
236 gfx.draw_busy_anim_function = draw_busy_anim_function;
239 void InitGfxCustomArtworkInfo()
241 gfx.override_level_graphics = FALSE;
242 gfx.override_level_sounds = FALSE;
243 gfx.override_level_music = FALSE;
245 gfx.draw_init_text = TRUE;
248 void SetDrawDeactivationMask(int draw_deactivation_mask)
250 gfx.draw_deactivation_mask = draw_deactivation_mask;
253 void SetDrawBackgroundMask(int draw_background_mask)
255 gfx.draw_background_mask = draw_background_mask;
260 static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
261 int dest_x, int dest_y, int width, int height)
263 int bitmap_xsize = width;
264 int bitmap_ysize = height;
265 int tile_xsize = tile->width;
266 int tile_ysize = tile->height;
267 int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
268 int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
271 for (y = 0; y < tile_ysteps; y++)
273 for (x = 0; x < tile_xsteps; x++)
275 int draw_x = dest_x + x * tile_xsize;
276 int draw_y = dest_y + y * tile_ysize;
277 int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
278 int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
280 BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
285 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
287 if (background_bitmap_tile != NULL)
288 gfx.background_bitmap_mask |= mask;
290 gfx.background_bitmap_mask &= ~mask;
293 if (gfx.background_bitmap == NULL)
294 gfx.background_bitmap = CreateBitmap(video.width, video.height,
298 if (background_bitmap_tile == NULL) /* empty background requested */
301 if (mask == REDRAW_ALL)
302 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
303 0, 0, video.width, video.height);
304 else if (mask == REDRAW_FIELD)
305 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
306 gfx.real_sx, gfx.real_sy,
307 gfx.full_sxsize, gfx.full_sysize);
308 else if (mask == REDRAW_DOOR_1)
310 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
312 gfx.dxsize, gfx.dysize);
318 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
320 if (background_bitmap_tile != NULL)
321 gfx.background_bitmap_mask |= mask;
323 gfx.background_bitmap_mask &= ~mask;
326 if (gfx.background_bitmap == NULL)
327 gfx.background_bitmap = CreateBitmap(video.width, video.height,
331 if (background_bitmap_tile == NULL) /* empty background requested */
334 if (mask == REDRAW_ALL)
335 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
336 0, 0, video.width, video.height);
337 else if (mask == REDRAW_FIELD)
338 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
339 gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize);
340 else if (mask == REDRAW_DOOR_1)
342 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
343 gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize);
349 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
351 /* remove every mask before setting mask for window */
352 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
353 SetBackgroundBitmap(NULL, 0xffff); /* !!! FIX THIS !!! */
354 SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
357 void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
359 /* remove window area mask before setting mask for main area */
360 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
361 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
362 SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
365 void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
367 /* remove window area mask before setting mask for door area */
368 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
369 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
370 SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
374 /* ========================================================================= */
375 /* video functions */
376 /* ========================================================================= */
378 inline static int GetRealDepth(int depth)
380 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
383 inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
384 int width, int height, Pixel color)
386 #if defined(TARGET_SDL)
387 SDLFillRectangle(bitmap, x, y, width, height, color);
389 X11FillRectangle(bitmap, x, y, width, height, color);
393 inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
394 int src_x, int src_y, int width, int height,
395 int dst_x, int dst_y, int mask_mode)
397 #if defined(TARGET_SDL)
398 SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
399 dst_x, dst_y, mask_mode);
401 X11CopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
402 dst_x, dst_y, mask_mode);
406 void InitVideoDisplay(void)
408 #if defined(TARGET_SDL)
409 SDLInitVideoDisplay();
411 X11InitVideoDisplay();
415 void CloseVideoDisplay(void)
417 KeyboardAutoRepeatOn();
419 #if defined(TARGET_SDL)
420 SDL_QuitSubSystem(SDL_INIT_VIDEO);
423 XCloseDisplay(display);
427 void InitVideoBuffer(int width, int height, int depth, boolean fullscreen)
430 video.height = height;
431 video.depth = GetRealDepth(depth);
433 video.fullscreen_available = FULLSCREEN_STATUS;
434 video.fullscreen_enabled = FALSE;
436 video.fullscreen_mode_current = NULL;
437 video.fullscreen_modes = NULL;
440 #if defined(TARGET_SDL)
441 SDLInitVideoBuffer(&backbuffer, &window, fullscreen);
443 X11InitVideoBuffer(&backbuffer, &window);
449 inline static void FreeBitmapPointers(Bitmap *bitmap)
454 #if defined(TARGET_SDL)
455 SDLFreeBitmapPointers(bitmap);
457 X11FreeBitmapPointers(bitmap);
460 checked_free(bitmap->source_filename);
461 bitmap->source_filename = NULL;
464 inline static void TransferBitmapPointers(Bitmap *src_bitmap,
467 if (src_bitmap == NULL || dst_bitmap == NULL)
470 FreeBitmapPointers(dst_bitmap);
472 *dst_bitmap = *src_bitmap;
475 void FreeBitmap(Bitmap *bitmap)
480 FreeBitmapPointers(bitmap);
485 Bitmap *CreateBitmapStruct(void)
487 #if defined(TARGET_SDL)
488 return checked_calloc(sizeof(struct SDLSurfaceInfo));
490 return checked_calloc(sizeof(struct X11DrawableInfo));
494 Bitmap *CreateBitmap(int width, int height, int depth)
496 Bitmap *new_bitmap = CreateBitmapStruct();
497 int real_width = MAX(1, width); /* prevent zero bitmap width */
498 int real_height = MAX(1, height); /* prevent zero bitmap height */
499 int real_depth = GetRealDepth(depth);
501 #if defined(TARGET_SDL)
502 SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
504 X11CreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
507 new_bitmap->width = real_width;
508 new_bitmap->height = real_height;
513 void ReCreateBitmap(Bitmap **bitmap, int width, int height, int depth)
515 Bitmap *new_bitmap = CreateBitmap(width, height, depth);
519 *bitmap = new_bitmap;
523 TransferBitmapPointers(new_bitmap, *bitmap);
528 void CloseWindow(DrawWindow *window)
530 #if defined(TARGET_X11)
531 X11CloseWindow(window);
535 inline static boolean CheckDrawingArea(int x, int y, int width, int height,
538 if (draw_mask == REDRAW_NONE)
541 if (draw_mask & REDRAW_ALL)
544 if ((draw_mask & REDRAW_FIELD) &&
545 x >= gfx.real_sx && x < gfx.real_sx + gfx.full_sxsize)
548 if ((draw_mask & REDRAW_DOOR_1) &&
549 x >= gfx.dx && y < gfx.dy + gfx.dysize)
552 if ((draw_mask & REDRAW_DOOR_2) &&
553 x >= gfx.dx && y >= gfx.vy)
559 boolean DrawingDeactivated(int x, int y, int width, int height)
561 return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask);
564 boolean DrawingOnBackground(int x, int y)
566 return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) &&
567 CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
570 static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y,
571 int *width, int *height, boolean is_dest)
574 int clip_x, clip_y, clip_width, clip_height;
576 if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */
578 clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width);
579 clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height);
580 clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x);
581 clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y);
587 clip_width = bitmap->width;
588 clip_height = bitmap->height;
591 /* skip if rectangle completely outside bitmap */
593 if (*x + *width <= clip_x ||
594 *y + *height <= clip_y ||
595 *x >= clip_x + clip_width ||
596 *y >= clip_y + clip_height)
599 /* clip if rectangle overlaps bitmap */
603 *width -= clip_x - *x;
606 else if (*x + *width > clip_x + clip_width)
608 *width = clip_x + clip_width - *x;
613 *height -= clip_y - *y;
616 else if (*y + *height > clip_y + clip_height)
618 *height = clip_y + clip_height - *y;
625 /* skip if rectangle completely outside bitmap */
627 if (*x + *width <= 0 ||
629 *x >= bitmap->width ||
630 *y >= bitmap->height)
633 /* clip if rectangle overlaps bitmap */
640 else if (*x + *width > bitmap->width)
642 *width = bitmap->width - *x;
650 else if (*y + *height > bitmap->height)
652 *height = bitmap->height - *y;
659 void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
660 int src_x, int src_y, int width, int height,
661 int dst_x, int dst_y)
663 int dst_x_unclipped = dst_x;
664 int dst_y_unclipped = dst_y;
666 if (DrawingDeactivated(dst_x, dst_y, width, height))
670 if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) ||
671 !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE))
674 /* source x/y might need adjustment if destination x/y was clipped top/left */
675 src_x += dst_x - dst_x_unclipped;
676 src_y += dst_y - dst_y_unclipped;
679 /* skip if rectangle starts outside bitmap */
680 if (src_x >= src_bitmap->width ||
681 src_y >= src_bitmap->height ||
682 dst_x >= dst_bitmap->width ||
683 dst_y >= dst_bitmap->height)
686 /* clip if rectangle overlaps bitmap */
687 if (src_x + width > src_bitmap->width)
688 width = src_bitmap->width - src_x;
689 if (src_y + height > src_bitmap->height)
690 height = src_bitmap->height - src_y;
691 if (dst_x + width > dst_bitmap->width)
692 width = dst_bitmap->width - dst_x;
693 if (dst_y + height > dst_bitmap->height)
694 height = dst_bitmap->height - dst_y;
698 /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
699 /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
700 but is already fixed in SVN and should therefore finally be fixed with
701 the next official SDL release, which is probably version 1.2.14.) */
703 /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
704 #if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
705 if (src_bitmap == dst_bitmap)
707 /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
709 /* needed when blitting directly to same bitmap -- should not be needed with
710 recent SDL libraries, but apparently does not work in 1.2.11 directly */
712 static Bitmap *tmp_bitmap = NULL;
713 static int tmp_bitmap_xsize = 0;
714 static int tmp_bitmap_ysize = 0;
716 /* start with largest static bitmaps for initial bitmap size ... */
717 if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
719 tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
720 tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
723 /* ... and allow for later re-adjustments due to custom artwork bitmaps */
724 if (src_bitmap->width > tmp_bitmap_xsize ||
725 src_bitmap->height > tmp_bitmap_ysize)
727 tmp_bitmap_xsize = MAX(tmp_bitmap_xsize, src_bitmap->width);
728 tmp_bitmap_ysize = MAX(tmp_bitmap_ysize, src_bitmap->height);
730 FreeBitmap(tmp_bitmap);
735 if (tmp_bitmap == NULL)
736 tmp_bitmap = CreateBitmap(tmp_bitmap_xsize, tmp_bitmap_ysize,
739 sysCopyArea(src_bitmap, tmp_bitmap,
740 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
741 sysCopyArea(tmp_bitmap, dst_bitmap,
742 dst_x, dst_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
751 if (dst_x < gfx.sx + gfx.sxsize)
752 printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n",
753 FrameCounter, dst_x, dst_y, width, height);
756 sysCopyArea(src_bitmap, dst_bitmap,
757 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
760 void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap,
761 int src_x, int src_y, int src_width, int src_height,
762 int dst_x, int dst_y, int dst_width, int dst_height)
764 int src_xsize = (src_width == 0 ? src_bitmap->width : src_width);
765 int src_ysize = (src_height == 0 ? src_bitmap->height : src_height);
766 int dst_xsize = dst_width;
767 int dst_ysize = dst_height;
768 int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize;
769 int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize;
772 for (y = 0; y < src_ysteps; y++)
774 for (x = 0; x < src_xsteps; x++)
776 int draw_x = dst_x + x * src_xsize;
777 int draw_y = dst_y + y * src_ysize;
778 int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize);
779 int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize);
781 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize,
787 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
788 int fade_mode, int fade_delay, int post_delay,
789 void (*draw_border_function)(void))
792 /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */
793 if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE))
797 #if defined(TARGET_SDL)
798 SDLFadeRectangle(bitmap_cross, x, y, width, height,
799 fade_mode, fade_delay, post_delay, draw_border_function);
801 X11FadeRectangle(bitmap_cross, x, y, width, height,
802 fade_mode, fade_delay, post_delay, draw_border_function);
806 void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height,
809 if (DrawingDeactivated(x, y, width, height))
813 if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE))
816 /* skip if rectangle starts outside bitmap */
817 if (x >= bitmap->width ||
821 /* clip if rectangle overlaps bitmap */
822 if (x + width > bitmap->width)
823 width = bitmap->width - x;
824 if (y + height > bitmap->height)
825 height = bitmap->height - y;
828 sysFillRectangle(bitmap, x, y, width, height, color);
831 void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
833 FillRectangle(bitmap, x, y, width, height, BLACK_PIXEL);
836 void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
837 int width, int height)
839 if (DrawingOnBackground(x, y))
840 BlitBitmap(gfx.background_bitmap, bitmap, x, y, width, height, x, y);
842 ClearRectangle(bitmap, x, y, width, height);
845 void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
847 #if defined(TARGET_X11)
850 bitmap->clip_gc = clip_gc;
851 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
856 void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
858 #if defined(TARGET_X11)
861 bitmap->clip_gc = clip_gc;
862 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
867 void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
868 int src_x, int src_y, int width, int height,
869 int dst_x, int dst_y)
871 if (DrawingDeactivated(dst_x, dst_y, width, height))
874 sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
875 dst_x, dst_y, BLIT_MASKED);
878 void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap,
879 int src_x, int src_y, int width, int height,
880 int dst_x, int dst_y)
882 if (DrawingOnBackground(dst_x, dst_y))
884 /* draw background */
885 BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
888 /* draw foreground */
889 SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
890 dst_x - src_x, dst_y - src_y);
891 BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
895 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
899 void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y,
902 #if defined(TARGET_SDL)
903 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
905 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
909 void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
912 #if defined(TARGET_SDL)
913 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
915 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
919 #if !defined(TARGET_X11_NATIVE)
920 void DrawLine(Bitmap *bitmap, int from_x, int from_y,
921 int to_x, int to_y, Pixel pixel, int line_width)
925 for (x = 0; x < line_width; x++)
927 for (y = 0; y < line_width; y++)
929 int dx = x - line_width / 2;
930 int dy = y - line_width / 2;
932 if ((x == 0 && y == 0) ||
933 (x == 0 && y == line_width - 1) ||
934 (x == line_width - 1 && y == 0) ||
935 (x == line_width - 1 && y == line_width - 1))
938 #if defined(TARGET_SDL)
940 from_x + dx, from_y + dy, to_x + dx, to_y + dy, pixel);
941 #elif defined(TARGET_ALLEGRO)
942 AllegroDrawLine(bitmap->drawable, from_x + dx, from_y + dy,
943 to_x + dx, to_y + dy, pixel);
950 void DrawLines(Bitmap *bitmap, struct XY *points, int num_points, Pixel pixel)
952 #if !defined(TARGET_X11_NATIVE)
956 for (i = 0; i < num_points - 1; i++)
957 DrawLine(bitmap, points[i].x, points[i].y,
958 points[i + 1].x, points[i + 1].y, pixel, line_width);
961 SDLDrawLines(bitmap->surface, points, num_points, pixel);
964 XSetForeground(display, bitmap->line_gc[1], pixel);
965 XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
966 (XPoint *)points, num_points, CoordModeOrigin);
970 Pixel GetPixel(Bitmap *bitmap, int x, int y)
972 if (x < 0 || x >= bitmap->width ||
973 y < 0 || y >= bitmap->height)
976 #if defined(TARGET_SDL)
977 return SDLGetPixel(bitmap, x, y);
978 #elif defined(TARGET_ALLEGRO)
979 return AllegroGetPixel(bitmap->drawable, x, y);
981 return X11GetPixel(bitmap, x, y);
985 Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
986 unsigned int color_g, unsigned int color_b)
988 #if defined(TARGET_SDL)
989 return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
990 #elif defined(TARGET_ALLEGRO)
991 return AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
993 return X11GetPixelFromRGB(color_r, color_g, color_b);
997 Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
999 unsigned int color_r = (color >> 16) & 0xff;
1000 unsigned int color_g = (color >> 8) & 0xff;
1001 unsigned int color_b = (color >> 0) & 0xff;
1003 return GetPixelFromRGB(bitmap, color_r, color_g, color_b);
1006 /* execute all pending screen drawing operations */
1007 void FlushDisplay(void)
1014 /* execute and wait for all pending screen drawing operations */
1015 void SyncDisplay(void)
1018 XSync(display, FALSE);
1022 void KeyboardAutoRepeatOn(void)
1024 #if defined(TARGET_SDL)
1025 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
1026 SDL_DEFAULT_REPEAT_INTERVAL / 2);
1027 SDL_EnableUNICODE(1);
1030 XAutoRepeatOn(display);
1034 void KeyboardAutoRepeatOff(void)
1036 #if defined(TARGET_SDL)
1037 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
1038 SDL_EnableUNICODE(0);
1041 XAutoRepeatOff(display);
1045 boolean PointerInWindow(DrawWindow *window)
1047 #if defined(TARGET_SDL)
1055 /* if XQueryPointer() returns False, the pointer
1056 is not on the same screen as the specified window */
1057 return XQueryPointer(display, window->drawable, &root, &child,
1058 &root_x, &root_y, &win_x, &win_y, &mask);
1062 boolean SetVideoMode(boolean fullscreen)
1064 #if defined(TARGET_SDL)
1065 return SDLSetVideoMode(&backbuffer, fullscreen);
1067 boolean success = TRUE;
1069 if (fullscreen && video.fullscreen_available)
1071 Error(ERR_WARN, "fullscreen not available in X11 version");
1073 /* display error message only once */
1074 video.fullscreen_available = FALSE;
1083 boolean ChangeVideoModeIfNeeded(boolean fullscreen)
1085 #if defined(TARGET_SDL)
1086 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
1087 (!fullscreen && video.fullscreen_enabled))
1088 fullscreen = SetVideoMode(fullscreen);
1094 Bitmap *LoadImage(char *filename)
1098 #if defined(TARGET_SDL)
1099 new_bitmap = SDLLoadImage(filename);
1101 new_bitmap = X11LoadImage(filename);
1105 new_bitmap->source_filename = getStringCopy(filename);
1110 Bitmap *LoadCustomImage(char *basename)
1112 char *filename = getCustomImageFilename(basename);
1115 if (filename == NULL)
1116 Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
1118 if ((new_bitmap = LoadImage(filename)) == NULL)
1119 Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
1124 void ReloadCustomImage(Bitmap *bitmap, char *basename)
1126 char *filename = getCustomImageFilename(basename);
1129 if (filename == NULL) /* (should never happen) */
1131 Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
1135 if (strEqual(filename, bitmap->source_filename))
1137 /* The old and new image are the same (have the same filename and path).
1138 This usually means that this image does not exist in this graphic set
1139 and a fallback to the existing image is done. */
1144 if ((new_bitmap = LoadImage(filename)) == NULL)
1146 Error(ERR_WARN, "LoadImage() failed: %s", GetError());
1150 if (bitmap->width != new_bitmap->width ||
1151 bitmap->height != new_bitmap->height)
1153 Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
1155 FreeBitmap(new_bitmap);
1159 TransferBitmapPointers(new_bitmap, bitmap);
1163 Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
1165 Bitmap *dst_bitmap = CreateBitmap(zoom_width, zoom_height, DEFAULT_DEPTH);
1167 #if defined(TARGET_SDL)
1168 SDLZoomBitmap(src_bitmap, dst_bitmap);
1170 X11ZoomBitmap(src_bitmap, dst_bitmap);
1176 static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
1177 boolean create_small_bitmaps)
1181 Bitmap *tmp_bitmap_1;
1182 Bitmap *tmp_bitmap_2;
1183 Bitmap *tmp_bitmap_4;
1184 Bitmap *tmp_bitmap_8;
1185 Bitmap *tmp_bitmap_16;
1186 Bitmap *tmp_bitmap_32;
1187 int width_1, height_1;
1188 int width_2, height_2;
1189 int width_4, height_4;
1190 int width_8, height_8;
1191 int width_16, height_16;
1193 int width_32, height_32;
1195 int new_width, new_height;
1197 /* calculate new image dimensions for normal sized image */
1198 width_1 = old_bitmap->width * zoom_factor;
1199 height_1 = old_bitmap->height * zoom_factor;
1201 /* get image with normal size (this might require scaling up) */
1202 if (zoom_factor != 1)
1203 tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
1205 tmp_bitmap_1 = old_bitmap;
1207 /* this is only needed to make compilers happy */
1208 tmp_bitmap_2 = NULL;
1209 tmp_bitmap_4 = NULL;
1210 tmp_bitmap_8 = NULL;
1211 tmp_bitmap_16 = NULL;
1212 tmp_bitmap_32 = NULL;
1214 if (create_small_bitmaps)
1216 /* calculate new image dimensions for small images */
1217 width_2 = width_1 / 2;
1218 height_2 = height_1 / 2;
1219 width_4 = width_1 / 4;
1220 height_4 = height_1 / 4;
1221 width_8 = width_1 / 8;
1222 height_8 = height_1 / 8;
1223 width_16 = width_1 / 16;
1224 height_16 = height_1 / 16;
1226 width_32 = width_1 / 32;
1227 height_32 = height_1 / 32;
1230 UPDATE_BUSY_STATE();
1232 /* get image with 1/2 of normal size (for use in the level editor) */
1233 if (zoom_factor != 2)
1234 tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
1236 tmp_bitmap_2 = old_bitmap;
1238 UPDATE_BUSY_STATE();
1240 /* get image with 1/4 of normal size (for use in the level editor) */
1241 if (zoom_factor != 4)
1242 tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2);
1244 tmp_bitmap_4 = old_bitmap;
1246 UPDATE_BUSY_STATE();
1248 /* get image with 1/8 of normal size (for use on the preview screen) */
1249 if (zoom_factor != 8)
1250 tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2);
1252 tmp_bitmap_8 = old_bitmap;
1254 UPDATE_BUSY_STATE();
1256 /* get image with 1/16 of normal size (for use on the preview screen) */
1257 if (zoom_factor != 16)
1258 tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2);
1260 tmp_bitmap_16 = old_bitmap;
1262 UPDATE_BUSY_STATE();
1264 /* get image with 1/32 of normal size (for use on the preview screen) */
1265 if (zoom_factor != 32)
1266 tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2);
1268 tmp_bitmap_32 = old_bitmap;
1270 UPDATE_BUSY_STATE();
1274 /* if image was scaled up, create new clipmask for normal size image */
1275 if (zoom_factor != 1)
1277 #if defined(TARGET_X11)
1278 if (old_bitmap->clip_mask)
1279 XFreePixmap(display, old_bitmap->clip_mask);
1281 old_bitmap->clip_mask =
1282 Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
1284 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1286 SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
1288 if (old_bitmap->surface_masked)
1289 SDL_FreeSurface(old_bitmap->surface_masked);
1291 SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
1292 SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
1293 if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
1294 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1295 SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
1300 if (create_small_bitmaps)
1302 new_width = width_1;
1303 new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
1305 new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
1307 BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
1308 BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
1310 BlitBitmap(tmp_bitmap_4, new_bitmap, 0, 0, width_1 / 4, height_1 / 4,
1311 width_1 / 2, height_1);
1312 BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
1313 3 * width_1 / 4, height_1);
1314 BlitBitmap(tmp_bitmap_16, new_bitmap, 0, 0, width_1 / 16, height_1 / 16,
1315 7 * width_1 / 8, height_1);
1316 BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32,
1317 15 * width_1 / 16, height_1);
1319 UPDATE_BUSY_STATE();
1323 new_width = width_1;
1324 new_height = height_1;
1326 new_bitmap = tmp_bitmap_1; /* directly use tmp_bitmap_1 as new bitmap */
1329 if (create_small_bitmaps)
1331 /* if no small bitmaps created, tmp_bitmap_1 is used as new bitmap now */
1332 if (zoom_factor != 1)
1333 FreeBitmap(tmp_bitmap_1);
1335 if (zoom_factor != 2)
1336 FreeBitmap(tmp_bitmap_2);
1338 if (zoom_factor != 4)
1339 FreeBitmap(tmp_bitmap_4);
1341 if (zoom_factor != 8)
1342 FreeBitmap(tmp_bitmap_8);
1344 if (zoom_factor != 16)
1345 FreeBitmap(tmp_bitmap_16);
1347 if (zoom_factor != 32)
1348 FreeBitmap(tmp_bitmap_32);
1351 /* replace image with extended image (containing 1/1, 1/2, 1/4, 1/8 size) */
1352 #if defined(TARGET_SDL)
1353 swap_bitmap.surface = old_bitmap->surface;
1354 old_bitmap->surface = new_bitmap->surface;
1355 new_bitmap->surface = swap_bitmap.surface;
1357 swap_bitmap.drawable = old_bitmap->drawable;
1358 old_bitmap->drawable = new_bitmap->drawable;
1359 new_bitmap->drawable = swap_bitmap.drawable;
1362 old_bitmap->width = new_bitmap->width;
1363 old_bitmap->height = new_bitmap->height;
1366 /* this replaces all blit masks created when loading -- maybe optimize this */
1368 #if defined(TARGET_X11)
1369 if (old_bitmap->clip_mask)
1370 XFreePixmap(display, old_bitmap->clip_mask);
1372 old_bitmap->clip_mask =
1373 Pixmap_to_Mask(old_bitmap->drawable, new_width, new_height);
1375 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1377 SDL_Surface *old_surface = old_bitmap->surface;
1379 if (old_bitmap->surface_masked)
1380 SDL_FreeSurface(old_bitmap->surface_masked);
1382 SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
1383 SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
1384 if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
1385 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1386 SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */
1391 UPDATE_BUSY_STATE();
1393 FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */
1396 void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
1398 CreateScaledBitmaps(old_bitmap, zoom_factor, TRUE);
1401 void ScaleBitmap(Bitmap *old_bitmap, int zoom_factor)
1403 CreateScaledBitmaps(old_bitmap, zoom_factor, FALSE);
1407 /* ------------------------------------------------------------------------- */
1408 /* mouse pointer functions */
1409 /* ------------------------------------------------------------------------- */
1411 #if !defined(PLATFORM_MSDOS)
1412 #define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
1413 /* XPM image definitions */
1414 static const char *cursor_image_none[] =
1416 /* width height num_colors chars_per_pixel */
1445 #if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
1446 static const char *cursor_image_dot[] =
1448 /* width height num_colors chars_per_pixel */
1477 static const char **cursor_image_playfield = cursor_image_dot;
1479 /* some people complained about a "white dot" on the screen and thought it
1480 was a graphical error... OK, let's just remove the whole pointer :-) */
1481 static const char **cursor_image_playfield = cursor_image_none;
1484 #if defined(TARGET_SDL)
1485 static const int cursor_bit_order = BIT_ORDER_MSB;
1486 #elif defined(TARGET_X11_NATIVE)
1487 static const int cursor_bit_order = BIT_ORDER_LSB;
1490 static struct MouseCursorInfo *get_cursor_from_image(const char **image)
1492 struct MouseCursorInfo *cursor;
1493 boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
1494 int header_lines = 4;
1497 cursor = checked_calloc(sizeof(struct MouseCursorInfo));
1499 sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
1502 for (y = 0; y < cursor->width; y++)
1504 for (x = 0; x < cursor->height; x++)
1507 int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
1512 cursor->data[i] = cursor->mask[i] = 0;
1515 switch (image[header_lines + y][x])
1518 cursor->data[i] |= bit_mask;
1519 cursor->mask[i] |= bit_mask;
1523 cursor->mask[i] |= bit_mask;
1532 sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
1536 #endif /* !PLATFORM_MSDOS */
1538 void SetMouseCursor(int mode)
1540 #if !defined(PLATFORM_MSDOS)
1541 static struct MouseCursorInfo *cursor_none = NULL;
1542 static struct MouseCursorInfo *cursor_playfield = NULL;
1543 struct MouseCursorInfo *cursor_new;
1545 if (cursor_none == NULL)
1546 cursor_none = get_cursor_from_image(cursor_image_none);
1548 if (cursor_playfield == NULL)
1549 cursor_playfield = get_cursor_from_image(cursor_image_playfield);
1551 cursor_new = (mode == CURSOR_DEFAULT ? NULL :
1552 mode == CURSOR_NONE ? cursor_none :
1553 mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
1555 #if defined(TARGET_SDL)
1556 SDLSetMouseCursor(cursor_new);
1557 #elif defined(TARGET_X11_NATIVE)
1558 X11SetMouseCursor(cursor_new);
1564 /* ========================================================================= */
1565 /* audio functions */
1566 /* ========================================================================= */
1568 void OpenAudio(void)
1570 /* always start with reliable default values */
1571 audio.sound_available = FALSE;
1572 audio.music_available = FALSE;
1573 audio.loops_available = FALSE;
1575 audio.sound_enabled = FALSE;
1576 audio.sound_deactivated = FALSE;
1578 audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
1579 audio.mixer_pid = 0;
1580 audio.device_name = NULL;
1581 audio.device_fd = -1;
1583 audio.num_channels = 0;
1584 audio.music_channel = 0;
1585 audio.first_sound_channel = 0;
1587 #if defined(TARGET_SDL)
1589 #elif defined(PLATFORM_UNIX)
1591 #elif defined(PLATFORM_MSDOS)
1596 void CloseAudio(void)
1598 #if defined(TARGET_SDL)
1600 #elif defined(PLATFORM_UNIX)
1602 #elif defined(PLATFORM_MSDOS)
1606 audio.sound_enabled = FALSE;
1609 void SetAudioMode(boolean enabled)
1611 if (!audio.sound_available)
1614 audio.sound_enabled = enabled;
1618 /* ========================================================================= */
1619 /* event functions */
1620 /* ========================================================================= */
1622 void InitEventFilter(EventFilter filter_function)
1624 #if defined(TARGET_SDL)
1625 /* set event filter to filter out certain events */
1626 SDL_SetEventFilter(filter_function);
1630 boolean PendingEvent(void)
1632 #if defined(TARGET_SDL)
1633 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
1635 return (XPending(display) ? TRUE : FALSE);
1639 void NextEvent(Event *event)
1641 #if defined(TARGET_SDL)
1642 SDLNextEvent(event);
1644 XNextEvent(display, event);
1648 void PeekEvent(Event *event)
1650 #if defined(TARGET_SDL)
1651 SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
1653 XPeekEvent(display, event);
1657 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
1659 #if defined(TARGET_SDL)
1662 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
1663 (int)event->keysym.unicode,
1664 (int)event->keysym.sym,
1665 (int)SDL_GetModState());
1668 if (with_modifiers &&
1669 event->keysym.unicode > 0x0000 &&
1670 event->keysym.unicode < 0x2000)
1671 return event->keysym.unicode;
1673 return event->keysym.sym;
1678 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
1679 (int)XLookupKeysym(event, event->state),
1680 (int)XLookupKeysym(event, 0));
1684 return XLookupKeysym(event, event->state);
1686 return XLookupKeysym(event, 0);
1690 KeyMod HandleKeyModState(Key key, int key_status)
1692 static KeyMod current_modifiers = KMOD_None;
1694 if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
1696 KeyMod new_modifier = KMOD_None;
1701 new_modifier = KMOD_Shift_L;
1704 new_modifier = KMOD_Shift_R;
1706 case KSYM_Control_L:
1707 new_modifier = KMOD_Control_L;
1709 case KSYM_Control_R:
1710 new_modifier = KMOD_Control_R;
1713 new_modifier = KMOD_Meta_L;
1716 new_modifier = KMOD_Meta_R;
1719 new_modifier = KMOD_Alt_L;
1722 new_modifier = KMOD_Alt_R;
1728 if (key_status == KEY_PRESSED)
1729 current_modifiers |= new_modifier;
1731 current_modifiers &= ~new_modifier;
1734 return current_modifiers;
1737 KeyMod GetKeyModState()
1739 #if defined(TARGET_SDL)
1740 return (KeyMod)SDL_GetModState();
1742 return HandleKeyModState(KSYM_UNDEFINED, 0);
1746 KeyMod GetKeyModStateFromEvents()
1748 /* always use key modifier state as tracked from key events (this is needed
1749 if the modifier key event was injected into the event queue, but the key
1750 was not really pressed on keyboard -- SDL_GetModState() seems to directly
1751 query the keys as held pressed on the keyboard) -- this case is currently
1752 only used to filter out clipboard insert events from "True X-Mouse" tool */
1754 return HandleKeyModState(KSYM_UNDEFINED, 0);
1757 boolean CheckCloseWindowEvent(ClientMessageEvent *event)
1759 if (event->type != EVENT_CLIENTMESSAGE)
1762 #if defined(TARGET_SDL)
1763 return TRUE; /* the only possible message here is SDL_QUIT */
1764 #elif defined(PLATFORM_UNIX)
1765 if ((event->window == window->drawable) &&
1766 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
1774 /* ========================================================================= */
1775 /* joystick functions */
1776 /* ========================================================================= */
1778 void InitJoysticks()
1782 #if defined(NO_JOYSTICK)
1783 return; /* joysticks generally deactivated by compile-time directive */
1786 /* always start with reliable default values */
1787 joystick.status = JOYSTICK_NOT_AVAILABLE;
1788 for (i = 0; i < MAX_PLAYERS; i++)
1789 joystick.fd[i] = -1; /* joystick device closed */
1791 #if defined(TARGET_SDL)
1793 #elif defined(PLATFORM_UNIX)
1794 UnixInitJoysticks();
1795 #elif defined(PLATFORM_MSDOS)
1796 MSDOSInitJoysticks();
1800 for (i = 0; i < MAX_PLAYERS; i++)
1801 printf("::: Joystick for player %d: %d\n", i, joystick.fd[i]);
1805 boolean ReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1807 #if defined(TARGET_SDL)
1808 return SDLReadJoystick(nr, x, y, b1, b2);
1809 #elif defined(PLATFORM_UNIX)
1810 return UnixReadJoystick(nr, x, y, b1, b2);
1811 #elif defined(PLATFORM_MSDOS)
1812 return MSDOSReadJoystick(nr, x, y, b1, b2);