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 Display *display = NULL;
50 Visual *visual = NULL;
54 DrawWindow *window = NULL;
55 DrawBuffer *backbuffer = NULL;
56 DrawBuffer *drawto = NULL;
58 int button_status = MB_NOT_PRESSED;
59 boolean motion_status = FALSE;
61 int redraw_mask = REDRAW_NONE;
67 /* ========================================================================= */
68 /* init/close functions */
69 /* ========================================================================= */
71 void InitProgramInfo(char *argv0,
72 char *userdata_subdir, char *userdata_subdir_unix,
73 char *program_title, char *window_title, char *icon_title,
74 char *x11_icon_filename, char *x11_iconmask_filename,
75 char *sdl_icon_filename, char *msdos_cursor_filename,
76 char *cookie_prefix, char *filename_prefix,
79 program.command_basepath = getBasePath(argv0);
80 program.command_basename = getBaseName(argv0);
82 program.userdata_subdir = userdata_subdir;
83 program.userdata_subdir_unix = userdata_subdir_unix;
84 program.userdata_path = getUserGameDataDir();
86 program.program_title = program_title;
87 program.window_title = window_title;
88 program.icon_title = icon_title;
90 program.x11_icon_filename = x11_icon_filename;
91 program.x11_iconmask_filename = x11_iconmask_filename;
92 program.sdl_icon_filename = sdl_icon_filename;
93 program.msdos_cursor_filename = msdos_cursor_filename;
95 program.cookie_prefix = cookie_prefix;
96 program.filename_prefix = filename_prefix;
98 program.version_major = VERSION_MAJOR(program_version);
99 program.version_minor = VERSION_MINOR(program_version);
100 program.version_patch = VERSION_PATCH(program_version);
102 program.error_filename = getErrorFilename(ERROR_BASENAME);
103 program.error_file = stderr;
106 void InitExitFunction(void (*exit_function)(int))
108 program.exit_function = exit_function;
110 /* set signal handlers to custom exit function */
111 signal(SIGINT, exit_function);
112 signal(SIGTERM, exit_function);
114 #if defined(TARGET_SDL)
115 /* set exit function to automatically cleanup SDL stuff after exit() */
120 void InitPlatformDependentStuff(void)
122 #if defined(PLATFORM_MSDOS)
126 #if defined(PLATFORM_MACOSX)
127 updateUserGameDataDir();
130 #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
134 #if defined(TARGET_SDL)
135 if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
136 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
142 void ClosePlatformDependentStuff(void)
144 #if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
148 #if defined(PLATFORM_MSDOS)
153 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
154 int real_sx, int real_sy,
155 int full_sxsize, int full_sysize,
156 Bitmap *field_save_buffer)
162 gfx.real_sx = real_sx;
163 gfx.real_sy = real_sy;
164 gfx.full_sxsize = full_sxsize;
165 gfx.full_sysize = full_sysize;
167 gfx.field_save_buffer = field_save_buffer;
170 gfx.background_bitmap = NULL;
171 gfx.background_bitmap_mask = REDRAW_NONE;
174 SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
175 SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
178 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
186 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
194 void InitGfxWindowInfo(int win_xsize, int win_ysize)
196 gfx.win_xsize = win_xsize;
197 gfx.win_ysize = win_ysize;
200 gfx.background_bitmap_mask = REDRAW_NONE;
202 ReCreateBitmap(&gfx.background_bitmap, win_xsize, win_ysize, DEFAULT_DEPTH);
206 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
208 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
209 /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
210 gfx.scrollbuffer_width = scrollbuffer_width;
211 gfx.scrollbuffer_height = scrollbuffer_height;
214 void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height)
216 gfx.clipping_enabled = enabled;
219 gfx.clip_width = width;
220 gfx.clip_height = height;
223 void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void))
225 gfx.draw_busy_anim_function = draw_busy_anim_function;
228 void InitGfxCustomArtworkInfo()
230 gfx.override_level_graphics = FALSE;
231 gfx.override_level_sounds = FALSE;
232 gfx.override_level_music = FALSE;
234 gfx.draw_init_text = TRUE;
237 void SetDrawDeactivationMask(int draw_deactivation_mask)
239 gfx.draw_deactivation_mask = draw_deactivation_mask;
242 void SetDrawBackgroundMask(int draw_background_mask)
244 gfx.draw_background_mask = draw_background_mask;
249 static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
250 int dest_x, int dest_y, int width, int height)
252 int bitmap_xsize = width;
253 int bitmap_ysize = height;
254 int tile_xsize = tile->width;
255 int tile_ysize = tile->height;
256 int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
257 int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
260 for (y = 0; y < tile_ysteps; y++)
262 for (x = 0; x < tile_xsteps; x++)
264 int draw_x = dest_x + x * tile_xsize;
265 int draw_y = dest_y + y * tile_ysize;
266 int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
267 int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
269 BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
274 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
276 if (background_bitmap_tile != NULL)
277 gfx.background_bitmap_mask |= mask;
279 gfx.background_bitmap_mask &= ~mask;
282 if (gfx.background_bitmap == NULL)
283 gfx.background_bitmap = CreateBitmap(video.width, video.height,
287 if (background_bitmap_tile == NULL) /* empty background requested */
290 if (mask == REDRAW_ALL)
291 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
292 0, 0, video.width, video.height);
293 else if (mask == REDRAW_FIELD)
294 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
295 gfx.real_sx, gfx.real_sy,
296 gfx.full_sxsize, gfx.full_sysize);
297 else if (mask == REDRAW_DOOR_1)
299 DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
301 gfx.dxsize, gfx.dysize);
307 void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
309 if (background_bitmap_tile != NULL)
310 gfx.background_bitmap_mask |= mask;
312 gfx.background_bitmap_mask &= ~mask;
315 if (gfx.background_bitmap == NULL)
316 gfx.background_bitmap = CreateBitmap(video.width, video.height,
320 if (background_bitmap_tile == NULL) /* empty background requested */
323 if (mask == REDRAW_ALL)
324 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
325 0, 0, video.width, video.height);
326 else if (mask == REDRAW_FIELD)
327 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
328 gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize);
329 else if (mask == REDRAW_DOOR_1)
331 BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
332 gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize);
338 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
340 /* remove every mask before setting mask for window */
341 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
342 SetBackgroundBitmap(NULL, 0xffff); /* !!! FIX THIS !!! */
343 SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
346 void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
348 /* remove window area mask before setting mask for main area */
349 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
350 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
351 SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
354 void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
356 /* remove window area mask before setting mask for door area */
357 /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
358 SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
359 SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
363 /* ========================================================================= */
364 /* video functions */
365 /* ========================================================================= */
367 inline static int GetRealDepth(int depth)
369 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
372 inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
373 int width, int height, Pixel color)
375 #if defined(TARGET_SDL)
376 SDLFillRectangle(bitmap, x, y, width, height, color);
378 X11FillRectangle(bitmap, x, y, width, height, color);
382 inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
383 int src_x, int src_y, int width, int height,
384 int dst_x, int dst_y, int mask_mode)
386 #if defined(TARGET_SDL)
387 SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
388 dst_x, dst_y, mask_mode);
390 X11CopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
391 dst_x, dst_y, mask_mode);
395 void InitVideoDisplay(void)
397 #if defined(TARGET_SDL)
398 SDLInitVideoDisplay();
400 X11InitVideoDisplay();
404 void CloseVideoDisplay(void)
406 KeyboardAutoRepeatOn();
408 #if defined(TARGET_SDL)
409 SDL_QuitSubSystem(SDL_INIT_VIDEO);
412 XCloseDisplay(display);
416 void InitVideoBuffer(int width, int height, int depth, boolean fullscreen)
419 video.height = height;
420 video.depth = GetRealDepth(depth);
422 video.fullscreen_available = FULLSCREEN_STATUS;
423 video.fullscreen_enabled = FALSE;
425 video.fullscreen_mode_current = NULL;
426 video.fullscreen_modes = NULL;
429 #if defined(TARGET_SDL)
430 SDLInitVideoBuffer(&backbuffer, &window, fullscreen);
432 X11InitVideoBuffer(&backbuffer, &window);
438 inline static void FreeBitmapPointers(Bitmap *bitmap)
443 #if defined(TARGET_SDL)
444 SDLFreeBitmapPointers(bitmap);
446 X11FreeBitmapPointers(bitmap);
449 checked_free(bitmap->source_filename);
450 bitmap->source_filename = NULL;
453 inline static void TransferBitmapPointers(Bitmap *src_bitmap,
456 if (src_bitmap == NULL || dst_bitmap == NULL)
459 FreeBitmapPointers(dst_bitmap);
461 *dst_bitmap = *src_bitmap;
464 void FreeBitmap(Bitmap *bitmap)
469 FreeBitmapPointers(bitmap);
474 Bitmap *CreateBitmapStruct(void)
476 #if defined(TARGET_SDL)
477 return checked_calloc(sizeof(struct SDLSurfaceInfo));
479 return checked_calloc(sizeof(struct X11DrawableInfo));
483 Bitmap *CreateBitmap(int width, int height, int depth)
485 Bitmap *new_bitmap = CreateBitmapStruct();
486 int real_width = MAX(1, width); /* prevent zero bitmap width */
487 int real_height = MAX(1, height); /* prevent zero bitmap height */
488 int real_depth = GetRealDepth(depth);
490 #if defined(TARGET_SDL)
491 SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
493 X11CreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
496 new_bitmap->width = real_width;
497 new_bitmap->height = real_height;
502 void ReCreateBitmap(Bitmap **bitmap, int width, int height, int depth)
504 Bitmap *new_bitmap = CreateBitmap(width, height, depth);
508 *bitmap = new_bitmap;
512 TransferBitmapPointers(new_bitmap, *bitmap);
517 void CloseWindow(DrawWindow *window)
519 #if defined(TARGET_X11)
520 X11CloseWindow(window);
524 inline static boolean CheckDrawingArea(int x, int y, int width, int height,
527 if (draw_mask == REDRAW_NONE)
530 if (draw_mask & REDRAW_ALL)
533 if ((draw_mask & REDRAW_FIELD) &&
534 x >= gfx.real_sx && x < gfx.real_sx + gfx.full_sxsize)
537 if ((draw_mask & REDRAW_DOOR_1) &&
538 x >= gfx.dx && y < gfx.dy + gfx.dysize)
541 if ((draw_mask & REDRAW_DOOR_2) &&
542 x >= gfx.dx && y >= gfx.vy)
548 boolean DrawingDeactivated(int x, int y, int width, int height)
550 return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask);
553 boolean DrawingOnBackground(int x, int y)
555 return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) &&
556 CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
559 static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y,
560 int *width, int *height, boolean is_dest)
563 int clip_x, clip_y, clip_width, clip_height;
565 if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */
567 clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width);
568 clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height);
569 clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x);
570 clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y);
576 clip_width = bitmap->width;
577 clip_height = bitmap->height;
580 /* skip if rectangle completely outside bitmap */
582 if (*x + *width <= clip_x ||
583 *y + *height <= clip_y ||
584 *x >= clip_x + clip_width ||
585 *y >= clip_y + clip_height)
588 /* clip if rectangle overlaps bitmap */
592 *width -= clip_x - *x;
595 else if (*x + *width > clip_x + clip_width)
597 *width = clip_x + clip_width - *x;
602 *height -= clip_y - *y;
605 else if (*y + *height > clip_y + clip_height)
607 *height = clip_y + clip_height - *y;
614 /* skip if rectangle completely outside bitmap */
616 if (*x + *width <= 0 ||
618 *x >= bitmap->width ||
619 *y >= bitmap->height)
622 /* clip if rectangle overlaps bitmap */
629 else if (*x + *width > bitmap->width)
631 *width = bitmap->width - *x;
639 else if (*y + *height > bitmap->height)
641 *height = bitmap->height - *y;
648 void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
649 int src_x, int src_y, int width, int height,
650 int dst_x, int dst_y)
652 int dst_x_unclipped = dst_x;
653 int dst_y_unclipped = dst_y;
655 if (DrawingDeactivated(dst_x, dst_y, width, height))
659 if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) ||
660 !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE))
663 /* source x/y might need adjustment if destination x/y was clipped top/left */
664 src_x += dst_x - dst_x_unclipped;
665 src_y += dst_y - dst_y_unclipped;
668 /* skip if rectangle starts outside bitmap */
669 if (src_x >= src_bitmap->width ||
670 src_y >= src_bitmap->height ||
671 dst_x >= dst_bitmap->width ||
672 dst_y >= dst_bitmap->height)
675 /* clip if rectangle overlaps bitmap */
676 if (src_x + width > src_bitmap->width)
677 width = src_bitmap->width - src_x;
678 if (src_y + height > src_bitmap->height)
679 height = src_bitmap->height - src_y;
680 if (dst_x + width > dst_bitmap->width)
681 width = dst_bitmap->width - dst_x;
682 if (dst_y + height > dst_bitmap->height)
683 height = dst_bitmap->height - dst_y;
687 /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
688 /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
689 but is already fixed in SVN and should therefore finally be fixed with
690 the next official SDL release, which is probably version 1.2.14.) */
692 /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
693 #if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
694 if (src_bitmap == dst_bitmap)
696 /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
698 /* needed when blitting directly to same bitmap -- should not be needed with
699 recent SDL libraries, but apparently does not work in 1.2.11 directly */
701 static Bitmap *tmp_bitmap = NULL;
702 static int tmp_bitmap_xsize = 0;
703 static int tmp_bitmap_ysize = 0;
705 /* start with largest static bitmaps for initial bitmap size ... */
706 if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
708 tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
709 tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
712 /* ... and allow for later re-adjustments due to custom artwork bitmaps */
713 if (src_bitmap->width > tmp_bitmap_xsize ||
714 src_bitmap->height > tmp_bitmap_ysize)
716 tmp_bitmap_xsize = MAX(tmp_bitmap_xsize, src_bitmap->width);
717 tmp_bitmap_ysize = MAX(tmp_bitmap_ysize, src_bitmap->height);
719 FreeBitmap(tmp_bitmap);
724 if (tmp_bitmap == NULL)
725 tmp_bitmap = CreateBitmap(tmp_bitmap_xsize, tmp_bitmap_ysize,
728 sysCopyArea(src_bitmap, tmp_bitmap,
729 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
730 sysCopyArea(tmp_bitmap, dst_bitmap,
731 dst_x, dst_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
740 if (dst_x < gfx.sx + gfx.sxsize)
741 printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n",
742 FrameCounter, dst_x, dst_y, width, height);
745 sysCopyArea(src_bitmap, dst_bitmap,
746 src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
749 void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap,
750 int src_x, int src_y, int src_width, int src_height,
751 int dst_x, int dst_y, int dst_width, int dst_height)
753 int src_xsize = (src_width == 0 ? src_bitmap->width : src_width);
754 int src_ysize = (src_height == 0 ? src_bitmap->height : src_height);
755 int dst_xsize = dst_width;
756 int dst_ysize = dst_height;
757 int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize;
758 int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize;
761 for (y = 0; y < src_ysteps; y++)
763 for (x = 0; x < src_xsteps; x++)
765 int draw_x = dst_x + x * src_xsize;
766 int draw_y = dst_y + y * src_ysize;
767 int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize);
768 int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize);
770 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize,
776 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
777 int fade_mode, int fade_delay, int post_delay,
778 void (*draw_border_function)(void))
781 /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */
782 if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE))
786 #if defined(TARGET_SDL)
787 SDLFadeRectangle(bitmap_cross, x, y, width, height,
788 fade_mode, fade_delay, post_delay, draw_border_function);
790 X11FadeRectangle(bitmap_cross, x, y, width, height,
791 fade_mode, fade_delay, post_delay, draw_border_function);
795 void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height,
798 if (DrawingDeactivated(x, y, width, height))
802 if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE))
805 /* skip if rectangle starts outside bitmap */
806 if (x >= bitmap->width ||
810 /* clip if rectangle overlaps bitmap */
811 if (x + width > bitmap->width)
812 width = bitmap->width - x;
813 if (y + height > bitmap->height)
814 height = bitmap->height - y;
817 sysFillRectangle(bitmap, x, y, width, height, color);
820 void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
822 FillRectangle(bitmap, x, y, width, height, BLACK_PIXEL);
825 void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
826 int width, int height)
828 if (DrawingOnBackground(x, y))
829 BlitBitmap(gfx.background_bitmap, bitmap, x, y, width, height, x, y);
831 ClearRectangle(bitmap, x, y, width, height);
834 void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
836 #if defined(TARGET_X11)
839 bitmap->clip_gc = clip_gc;
840 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
845 void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
847 #if defined(TARGET_X11)
850 bitmap->clip_gc = clip_gc;
851 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
856 void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
857 int src_x, int src_y, int width, int height,
858 int dst_x, int dst_y)
860 if (DrawingDeactivated(dst_x, dst_y, width, height))
863 sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
864 dst_x, dst_y, BLIT_MASKED);
867 void BlitBitmapOnBackground(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 (DrawingOnBackground(dst_x, dst_y))
873 /* draw background */
874 BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
877 /* draw foreground */
878 SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
879 dst_x - src_x, dst_y - src_y);
880 BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
884 BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
888 void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y,
891 #if defined(TARGET_SDL)
892 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
894 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL);
898 void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
901 #if defined(TARGET_SDL)
902 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
904 X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
908 #if !defined(TARGET_X11_NATIVE)
909 void DrawLine(Bitmap *bitmap, int from_x, int from_y,
910 int to_x, int to_y, Pixel pixel, int line_width)
914 for (x = 0; x < line_width; x++)
916 for (y = 0; y < line_width; y++)
918 int dx = x - line_width / 2;
919 int dy = y - line_width / 2;
921 if ((x == 0 && y == 0) ||
922 (x == 0 && y == line_width - 1) ||
923 (x == line_width - 1 && y == 0) ||
924 (x == line_width - 1 && y == line_width - 1))
927 #if defined(TARGET_SDL)
929 from_x + dx, from_y + dy, to_x + dx, to_y + dy, pixel);
930 #elif defined(TARGET_ALLEGRO)
931 AllegroDrawLine(bitmap->drawable, from_x + dx, from_y + dy,
932 to_x + dx, to_y + dy, pixel);
939 void DrawLines(Bitmap *bitmap, struct XY *points, int num_points, Pixel pixel)
941 #if !defined(TARGET_X11_NATIVE)
945 for (i = 0; i < num_points - 1; i++)
946 DrawLine(bitmap, points[i].x, points[i].y,
947 points[i + 1].x, points[i + 1].y, pixel, line_width);
950 SDLDrawLines(bitmap->surface, points, num_points, pixel);
953 XSetForeground(display, bitmap->line_gc[1], pixel);
954 XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
955 (XPoint *)points, num_points, CoordModeOrigin);
959 Pixel GetPixel(Bitmap *bitmap, int x, int y)
961 if (x < 0 || x >= bitmap->width ||
962 y < 0 || y >= bitmap->height)
965 #if defined(TARGET_SDL)
966 return SDLGetPixel(bitmap, x, y);
967 #elif defined(TARGET_ALLEGRO)
968 return AllegroGetPixel(bitmap->drawable, x, y);
970 return X11GetPixel(bitmap, x, y);
974 Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
975 unsigned int color_g, unsigned int color_b)
977 #if defined(TARGET_SDL)
978 return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
979 #elif defined(TARGET_ALLEGRO)
980 return AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
982 return X11GetPixelFromRGB(color_r, color_g, color_b);
986 Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
988 unsigned int color_r = (color >> 16) & 0xff;
989 unsigned int color_g = (color >> 8) & 0xff;
990 unsigned int color_b = (color >> 0) & 0xff;
992 return GetPixelFromRGB(bitmap, color_r, color_g, color_b);
995 /* execute all pending screen drawing operations */
996 void FlushDisplay(void)
1003 /* execute and wait for all pending screen drawing operations */
1004 void SyncDisplay(void)
1007 XSync(display, FALSE);
1011 void KeyboardAutoRepeatOn(void)
1013 #if defined(TARGET_SDL)
1014 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
1015 SDL_DEFAULT_REPEAT_INTERVAL / 2);
1016 SDL_EnableUNICODE(1);
1019 XAutoRepeatOn(display);
1023 void KeyboardAutoRepeatOff(void)
1025 #if defined(TARGET_SDL)
1026 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
1027 SDL_EnableUNICODE(0);
1030 XAutoRepeatOff(display);
1034 boolean PointerInWindow(DrawWindow *window)
1036 #if defined(TARGET_SDL)
1044 /* if XQueryPointer() returns False, the pointer
1045 is not on the same screen as the specified window */
1046 return XQueryPointer(display, window->drawable, &root, &child,
1047 &root_x, &root_y, &win_x, &win_y, &mask);
1051 boolean SetVideoMode(boolean fullscreen)
1053 #if defined(TARGET_SDL)
1054 return SDLSetVideoMode(&backbuffer, fullscreen);
1056 boolean success = TRUE;
1058 if (fullscreen && video.fullscreen_available)
1060 Error(ERR_WARN, "fullscreen not available in X11 version");
1062 /* display error message only once */
1063 video.fullscreen_available = FALSE;
1072 boolean ChangeVideoModeIfNeeded(boolean fullscreen)
1074 #if defined(TARGET_SDL)
1075 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
1076 (!fullscreen && video.fullscreen_enabled))
1077 fullscreen = SetVideoMode(fullscreen);
1083 Bitmap *LoadImage(char *filename)
1087 #if defined(TARGET_SDL)
1088 new_bitmap = SDLLoadImage(filename);
1090 new_bitmap = X11LoadImage(filename);
1094 new_bitmap->source_filename = getStringCopy(filename);
1099 Bitmap *LoadCustomImage(char *basename)
1101 char *filename = getCustomImageFilename(basename);
1104 if (filename == NULL)
1105 Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
1107 if ((new_bitmap = LoadImage(filename)) == NULL)
1108 Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
1113 void ReloadCustomImage(Bitmap *bitmap, char *basename)
1115 char *filename = getCustomImageFilename(basename);
1118 if (filename == NULL) /* (should never happen) */
1120 Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
1124 if (strEqual(filename, bitmap->source_filename))
1126 /* The old and new image are the same (have the same filename and path).
1127 This usually means that this image does not exist in this graphic set
1128 and a fallback to the existing image is done. */
1133 if ((new_bitmap = LoadImage(filename)) == NULL)
1135 Error(ERR_WARN, "LoadImage() failed: %s", GetError());
1139 if (bitmap->width != new_bitmap->width ||
1140 bitmap->height != new_bitmap->height)
1142 Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
1144 FreeBitmap(new_bitmap);
1148 TransferBitmapPointers(new_bitmap, bitmap);
1152 Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
1154 Bitmap *dst_bitmap = CreateBitmap(zoom_width, zoom_height, DEFAULT_DEPTH);
1156 #if defined(TARGET_SDL)
1157 SDLZoomBitmap(src_bitmap, dst_bitmap);
1159 X11ZoomBitmap(src_bitmap, dst_bitmap);
1165 static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
1166 boolean create_small_bitmaps)
1170 Bitmap *tmp_bitmap_1;
1171 Bitmap *tmp_bitmap_2;
1172 Bitmap *tmp_bitmap_4;
1173 Bitmap *tmp_bitmap_8;
1174 Bitmap *tmp_bitmap_16;
1175 Bitmap *tmp_bitmap_32;
1176 int width_1, height_1;
1177 int width_2, height_2;
1178 int width_4, height_4;
1179 int width_8, height_8;
1180 int width_16, height_16;
1181 int width_32, height_32;
1182 int new_width, new_height;
1184 /* calculate new image dimensions for normal sized image */
1185 width_1 = old_bitmap->width * zoom_factor;
1186 height_1 = old_bitmap->height * zoom_factor;
1188 /* get image with normal size (this might require scaling up) */
1189 if (zoom_factor != 1)
1190 tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
1192 tmp_bitmap_1 = old_bitmap;
1194 /* this is only needed to make compilers happy */
1195 tmp_bitmap_2 = NULL;
1196 tmp_bitmap_4 = NULL;
1197 tmp_bitmap_8 = NULL;
1198 tmp_bitmap_16 = NULL;
1199 tmp_bitmap_32 = NULL;
1201 if (create_small_bitmaps)
1203 /* calculate new image dimensions for small images */
1204 width_2 = width_1 / 2;
1205 height_2 = height_1 / 2;
1206 width_4 = width_1 / 4;
1207 height_4 = height_1 / 4;
1208 width_8 = width_1 / 8;
1209 height_8 = height_1 / 8;
1210 width_16 = width_1 / 16;
1211 height_16 = height_1 / 16;
1212 width_32 = width_1 / 32;
1213 height_32 = height_1 / 32;
1215 UPDATE_BUSY_STATE();
1217 /* get image with 1/2 of normal size (for use in the level editor) */
1218 if (zoom_factor != 2)
1219 tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
1221 tmp_bitmap_2 = old_bitmap;
1223 UPDATE_BUSY_STATE();
1225 /* get image with 1/4 of normal size (for use in the level editor) */
1226 if (zoom_factor != 4)
1227 tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2);
1229 tmp_bitmap_4 = old_bitmap;
1231 UPDATE_BUSY_STATE();
1233 /* get image with 1/8 of normal size (for use on the preview screen) */
1234 if (zoom_factor != 8)
1235 tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2);
1237 tmp_bitmap_8 = old_bitmap;
1239 UPDATE_BUSY_STATE();
1241 /* get image with 1/16 of normal size (for use on the preview screen) */
1242 if (zoom_factor != 16)
1243 tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2);
1245 tmp_bitmap_16 = old_bitmap;
1247 UPDATE_BUSY_STATE();
1249 /* get image with 1/32 of normal size (for use on the preview screen) */
1250 if (zoom_factor != 32)
1251 tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2);
1253 tmp_bitmap_32 = old_bitmap;
1255 UPDATE_BUSY_STATE();
1259 /* if image was scaled up, create new clipmask for normal size image */
1260 if (zoom_factor != 1)
1262 #if defined(TARGET_X11)
1263 if (old_bitmap->clip_mask)
1264 XFreePixmap(display, old_bitmap->clip_mask);
1266 old_bitmap->clip_mask =
1267 Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
1269 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1271 SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
1273 if (old_bitmap->surface_masked)
1274 SDL_FreeSurface(old_bitmap->surface_masked);
1276 SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
1277 SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
1278 if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
1279 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1280 SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
1285 if (create_small_bitmaps)
1287 new_width = width_1;
1288 new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
1290 new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
1292 BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
1293 BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
1295 BlitBitmap(tmp_bitmap_4, new_bitmap, 0, 0, width_1 / 4, height_1 / 4,
1296 width_1 / 2, height_1);
1297 BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
1298 3 * width_1 / 4, height_1);
1299 BlitBitmap(tmp_bitmap_16, new_bitmap, 0, 0, width_1 / 16, height_1 / 16,
1300 7 * width_1 / 8, height_1);
1301 BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32,
1302 15 * width_1 / 16, height_1);
1304 UPDATE_BUSY_STATE();
1308 new_width = width_1;
1309 new_height = height_1;
1311 new_bitmap = tmp_bitmap_1; /* directly use tmp_bitmap_1 as new bitmap */
1314 if (create_small_bitmaps)
1316 /* if no small bitmaps created, tmp_bitmap_1 is used as new bitmap now */
1317 if (zoom_factor != 1)
1318 FreeBitmap(tmp_bitmap_1);
1320 if (zoom_factor != 2)
1321 FreeBitmap(tmp_bitmap_2);
1323 if (zoom_factor != 4)
1324 FreeBitmap(tmp_bitmap_4);
1326 if (zoom_factor != 8)
1327 FreeBitmap(tmp_bitmap_8);
1329 if (zoom_factor != 16)
1330 FreeBitmap(tmp_bitmap_16);
1332 if (zoom_factor != 32)
1333 FreeBitmap(tmp_bitmap_32);
1336 /* replace image with extended image (containing 1/1, 1/2, 1/4, 1/8 size) */
1337 #if defined(TARGET_SDL)
1338 swap_bitmap.surface = old_bitmap->surface;
1339 old_bitmap->surface = new_bitmap->surface;
1340 new_bitmap->surface = swap_bitmap.surface;
1342 swap_bitmap.drawable = old_bitmap->drawable;
1343 old_bitmap->drawable = new_bitmap->drawable;
1344 new_bitmap->drawable = swap_bitmap.drawable;
1347 old_bitmap->width = new_bitmap->width;
1348 old_bitmap->height = new_bitmap->height;
1351 /* this replaces all blit masks created when loading -- maybe optimize this */
1353 #if defined(TARGET_X11)
1354 if (old_bitmap->clip_mask)
1355 XFreePixmap(display, old_bitmap->clip_mask);
1357 old_bitmap->clip_mask =
1358 Pixmap_to_Mask(old_bitmap->drawable, new_width, new_height);
1360 XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
1362 SDL_Surface *old_surface = old_bitmap->surface;
1364 if (old_bitmap->surface_masked)
1365 SDL_FreeSurface(old_bitmap->surface_masked);
1367 SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
1368 SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
1369 if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
1370 Error(ERR_EXIT, "SDL_DisplayFormat() failed");
1371 SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */
1376 UPDATE_BUSY_STATE();
1378 FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */
1381 void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
1383 CreateScaledBitmaps(old_bitmap, zoom_factor, TRUE);
1386 void ScaleBitmap(Bitmap *old_bitmap, int zoom_factor)
1388 CreateScaledBitmaps(old_bitmap, zoom_factor, FALSE);
1392 /* ------------------------------------------------------------------------- */
1393 /* mouse pointer functions */
1394 /* ------------------------------------------------------------------------- */
1396 #if !defined(PLATFORM_MSDOS)
1397 #define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
1398 /* XPM image definitions */
1399 static const char *cursor_image_none[] =
1401 /* width height num_colors chars_per_pixel */
1430 #if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
1431 static const char *cursor_image_dot[] =
1433 /* width height num_colors chars_per_pixel */
1462 static const char **cursor_image_playfield = cursor_image_dot;
1464 /* some people complained about a "white dot" on the screen and thought it
1465 was a graphical error... OK, let's just remove the whole pointer :-) */
1466 static const char **cursor_image_playfield = cursor_image_none;
1469 #if defined(TARGET_SDL)
1470 static const int cursor_bit_order = BIT_ORDER_MSB;
1471 #elif defined(TARGET_X11_NATIVE)
1472 static const int cursor_bit_order = BIT_ORDER_LSB;
1475 static struct MouseCursorInfo *get_cursor_from_image(const char **image)
1477 struct MouseCursorInfo *cursor;
1478 boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
1479 int header_lines = 4;
1482 cursor = checked_calloc(sizeof(struct MouseCursorInfo));
1484 sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
1487 for (y = 0; y < cursor->width; y++)
1489 for (x = 0; x < cursor->height; x++)
1492 int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
1497 cursor->data[i] = cursor->mask[i] = 0;
1500 switch (image[header_lines + y][x])
1503 cursor->data[i] |= bit_mask;
1504 cursor->mask[i] |= bit_mask;
1508 cursor->mask[i] |= bit_mask;
1517 sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
1521 #endif /* !PLATFORM_MSDOS */
1523 void SetMouseCursor(int mode)
1525 #if !defined(PLATFORM_MSDOS)
1526 static struct MouseCursorInfo *cursor_none = NULL;
1527 static struct MouseCursorInfo *cursor_playfield = NULL;
1528 struct MouseCursorInfo *cursor_new;
1530 if (cursor_none == NULL)
1531 cursor_none = get_cursor_from_image(cursor_image_none);
1533 if (cursor_playfield == NULL)
1534 cursor_playfield = get_cursor_from_image(cursor_image_playfield);
1536 cursor_new = (mode == CURSOR_DEFAULT ? NULL :
1537 mode == CURSOR_NONE ? cursor_none :
1538 mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
1540 #if defined(TARGET_SDL)
1541 SDLSetMouseCursor(cursor_new);
1542 #elif defined(TARGET_X11_NATIVE)
1543 X11SetMouseCursor(cursor_new);
1549 /* ========================================================================= */
1550 /* audio functions */
1551 /* ========================================================================= */
1553 void OpenAudio(void)
1555 /* always start with reliable default values */
1556 audio.sound_available = FALSE;
1557 audio.music_available = FALSE;
1558 audio.loops_available = FALSE;
1560 audio.sound_enabled = FALSE;
1561 audio.sound_deactivated = FALSE;
1563 audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
1564 audio.mixer_pid = 0;
1565 audio.device_name = NULL;
1566 audio.device_fd = -1;
1568 audio.num_channels = 0;
1569 audio.music_channel = 0;
1570 audio.first_sound_channel = 0;
1572 #if defined(TARGET_SDL)
1574 #elif defined(PLATFORM_UNIX)
1576 #elif defined(PLATFORM_MSDOS)
1581 void CloseAudio(void)
1583 #if defined(TARGET_SDL)
1585 #elif defined(PLATFORM_UNIX)
1587 #elif defined(PLATFORM_MSDOS)
1591 audio.sound_enabled = FALSE;
1594 void SetAudioMode(boolean enabled)
1596 if (!audio.sound_available)
1599 audio.sound_enabled = enabled;
1603 /* ========================================================================= */
1604 /* event functions */
1605 /* ========================================================================= */
1607 void InitEventFilter(EventFilter filter_function)
1609 #if defined(TARGET_SDL)
1610 /* set event filter to filter out certain events */
1611 SDL_SetEventFilter(filter_function);
1615 boolean PendingEvent(void)
1617 #if defined(TARGET_SDL)
1618 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
1620 return (XPending(display) ? TRUE : FALSE);
1624 void NextEvent(Event *event)
1626 #if defined(TARGET_SDL)
1627 SDLNextEvent(event);
1629 XNextEvent(display, event);
1633 void PeekEvent(Event *event)
1635 #if defined(TARGET_SDL)
1636 SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
1638 XPeekEvent(display, event);
1642 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
1644 #if defined(TARGET_SDL)
1647 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
1648 (int)event->keysym.unicode,
1649 (int)event->keysym.sym,
1650 (int)SDL_GetModState());
1653 if (with_modifiers &&
1654 event->keysym.unicode > 0x0000 &&
1655 event->keysym.unicode < 0x2000)
1656 return event->keysym.unicode;
1658 return event->keysym.sym;
1663 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
1664 (int)XLookupKeysym(event, event->state),
1665 (int)XLookupKeysym(event, 0));
1669 return XLookupKeysym(event, event->state);
1671 return XLookupKeysym(event, 0);
1675 KeyMod HandleKeyModState(Key key, int key_status)
1677 static KeyMod current_modifiers = KMOD_None;
1679 if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
1681 KeyMod new_modifier = KMOD_None;
1686 new_modifier = KMOD_Shift_L;
1689 new_modifier = KMOD_Shift_R;
1691 case KSYM_Control_L:
1692 new_modifier = KMOD_Control_L;
1694 case KSYM_Control_R:
1695 new_modifier = KMOD_Control_R;
1698 new_modifier = KMOD_Meta_L;
1701 new_modifier = KMOD_Meta_R;
1704 new_modifier = KMOD_Alt_L;
1707 new_modifier = KMOD_Alt_R;
1713 if (key_status == KEY_PRESSED)
1714 current_modifiers |= new_modifier;
1716 current_modifiers &= ~new_modifier;
1719 return current_modifiers;
1722 KeyMod GetKeyModState()
1724 #if defined(TARGET_SDL)
1725 return (KeyMod)SDL_GetModState();
1727 return HandleKeyModState(KSYM_UNDEFINED, 0);
1731 KeyMod GetKeyModStateFromEvents()
1733 /* always use key modifier state as tracked from key events (this is needed
1734 if the modifier key event was injected into the event queue, but the key
1735 was not really pressed on keyboard -- SDL_GetModState() seems to directly
1736 query the keys as held pressed on the keyboard) -- this case is currently
1737 only used to filter out clipboard insert events from "True X-Mouse" tool */
1739 return HandleKeyModState(KSYM_UNDEFINED, 0);
1742 boolean CheckCloseWindowEvent(ClientMessageEvent *event)
1744 if (event->type != EVENT_CLIENTMESSAGE)
1747 #if defined(TARGET_SDL)
1748 return TRUE; /* the only possible message here is SDL_QUIT */
1749 #elif defined(PLATFORM_UNIX)
1750 if ((event->window == window->drawable) &&
1751 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
1759 /* ========================================================================= */
1760 /* joystick functions */
1761 /* ========================================================================= */
1763 void InitJoysticks()
1767 #if defined(NO_JOYSTICK)
1768 return; /* joysticks generally deactivated by compile-time directive */
1771 /* always start with reliable default values */
1772 joystick.status = JOYSTICK_NOT_AVAILABLE;
1773 for (i = 0; i < MAX_PLAYERS; i++)
1774 joystick.fd[i] = -1; /* joystick device closed */
1776 #if defined(TARGET_SDL)
1778 #elif defined(PLATFORM_UNIX)
1779 UnixInitJoysticks();
1780 #elif defined(PLATFORM_MSDOS)
1781 MSDOSInitJoysticks();
1785 for (i = 0; i < MAX_PLAYERS; i++)
1786 printf("::: Joystick for player %d: %d\n", i, joystick.fd[i]);
1790 boolean ReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1792 #if defined(TARGET_SDL)
1793 return SDLReadJoystick(nr, x, y, b1, b2);
1794 #elif defined(PLATFORM_UNIX)
1795 return UnixReadJoystick(nr, x, y, b1, b2);
1796 #elif defined(PLATFORM_MSDOS)
1797 return MSDOSReadJoystick(nr, x, y, b1, b2);