1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * ©1995 Artsoft Development *
6 * 33659 Bielefeld-Senne *
7 * Telefon: (0521) 493245 *
8 * eMail: aeglos@valinor.owl.de *
9 * aeglos@uni-paderborn.de *
10 * q99492@pbhrzx.uni-paderborn.de *
11 *----------------------------------------------------------*
13 ***********************************************************/
19 #if defined(PLATFORM_MSDOS)
26 /* ========================================================================= */
27 /* exported variables */
28 /* ========================================================================= */
30 struct ProgramInfo program;
31 struct OptionInfo options;
32 struct VideoSystemInfo video;
33 struct AudioSystemInfo audio;
36 Display *display = NULL;
37 Visual *visual = NULL;
41 DrawWindow window = NULL;
42 DrawBuffer backbuffer = NULL;
43 DrawBuffer drawto = NULL;
45 int button_status = MB_NOT_PRESSED;
46 boolean motion_status = FALSE;
48 int redraw_mask = REDRAW_NONE;
55 /* ========================================================================= */
57 /* ========================================================================= */
59 void InitCommandName(char *argv0)
61 program.command_basename =
62 (strrchr(argv0, '/') ? strrchr(argv0, '/') + 1 : argv0);
65 void InitExitFunction(void (*exit_function)(int))
67 program.exit_function = exit_function;
70 void InitPlatformDependantStuff(void)
72 #if defined(PLATFORM_MSDOS)
77 void InitProgramInfo(char *unix_userdata_directory, char *program_title,
78 char *window_title, char *icon_title,
79 char *x11_icon_basename, char *x11_iconmask_basename,
80 char *msdos_pointer_basename)
82 char *gfx_dir = getPath2(options.ro_base_directory, GRAPHICS_DIRECTORY);
83 char *x11_icon_filename = getPath2(gfx_dir, x11_icon_basename);
84 char *x11_iconmask_filename = getPath2(gfx_dir, x11_iconmask_basename);
85 char *msdos_pointer_filename = getPath2(gfx_dir, msdos_pointer_basename);
89 #if defined(PLATFORM_UNIX)
90 program.userdata_directory = unix_userdata_directory;
92 program.userdata_directory = "userdata";
95 program.program_title = program_title;
96 program.window_title = window_title;
97 program.icon_title = icon_title;
98 program.x11_icon_filename = x11_icon_filename;
99 program.x11_iconmask_filename = x11_iconmask_filename;
100 program.msdos_pointer_filename = msdos_pointer_filename;
103 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
104 int real_sx, int real_sy,
105 int full_sxsize, int full_sysize)
111 gfx.real_sx = real_sx;
112 gfx.real_sy = real_sy;
113 gfx.full_sxsize = full_sxsize;
114 gfx.full_sysize = full_sysize;
117 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
125 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
133 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
135 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
136 gfx.scrollbuffer_width = scrollbuffer_width;
137 gfx.scrollbuffer_height = scrollbuffer_height;
141 /* ========================================================================= */
142 /* video functions */
143 /* ========================================================================= */
145 inline static int GetRealDepth(int depth)
147 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
150 inline void InitVideoDisplay(void)
153 SDLInitVideoDisplay();
155 X11InitVideoDisplay();
159 inline void InitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
160 int width, int height, int depth,
164 video.height = height;
165 video.depth = GetRealDepth(depth);
166 video.fullscreen_available = FULLSCREEN_STATUS;
167 video.fullscreen_enabled = FALSE;
170 SDLInitVideoBuffer(backbuffer, window, fullscreen);
172 X11InitVideoBuffer(backbuffer, window);
176 inline Bitmap CreateBitmapStruct(void)
179 return checked_calloc(sizeof(struct SDLSurfaceInfo));
181 return checked_calloc(sizeof(struct X11DrawableInfo));
185 inline Bitmap CreateBitmap(int width, int height, int depth)
187 Bitmap new_bitmap = CreateBitmapStruct();
188 int real_depth = GetRealDepth(depth);
191 SDL_Surface *surface_tmp, *surface_native;
193 if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
194 real_depth, 0, 0, 0, 0))
196 Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
198 if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
199 Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
201 SDL_FreeSurface(surface_tmp);
203 new_bitmap->surface = surface_native;
207 if (!(pixmap = XCreatePixmap(display, window->drawable,
208 width, height, real_depth)))
209 Error(ERR_EXIT, "cannot create pixmap");
210 new_bitmap->drawable = pixmap;
213 Error(ERR_EXIT, "Window GC needed for Bitmap -- create Window first");
214 new_bitmap->gc = window->gc;
221 inline void FreeBitmap(Bitmap bitmap)
228 SDL_FreeSurface(bitmap->surface);
229 if (bitmap->surface_masked)
230 SDL_FreeSurface(bitmap->surface_masked);
232 if (bitmap->drawable)
233 XFreePixmap(display, bitmap->drawable);
234 if (bitmap->clip_mask)
235 XFreePixmap(display, bitmap->clip_mask);
236 if (bitmap->stored_clip_gc)
237 XFreeGC(display, bitmap->stored_clip_gc);
243 inline void CloseWindow(DrawWindow window)
246 if (window->drawable)
248 XUnmapWindow(display, window->drawable);
249 XDestroyWindow(display, window->drawable);
252 XFreeGC(display, window->gc);
256 inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
257 int src_x, int src_y,
258 int width, int height,
259 int dst_x, int dst_y)
262 SDLCopyArea(src_bitmap, dst_bitmap,
263 src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_OPAQUE);
265 XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
266 dst_bitmap->gc, src_x, src_y, width, height, dst_x, dst_y);
270 inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
273 SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
275 XFillRectangle(display, bitmap->drawable, bitmap->gc, x, y, width, height);
281 static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */
285 inline void SetClipMask(Bitmap bitmap, GC clip_gc, Pixmap clip_pixmap)
290 bitmap->clip_gc = clip_gc;
291 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
294 last_clip_gc = clip_gc;
299 inline void SetClipOrigin(Bitmap bitmap, GC clip_gc, int clip_x, int clip_y)
304 bitmap->clip_gc = clip_gc;
305 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
308 last_clip_gc = clip_gc;
313 inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
314 int src_x, int src_y,
315 int width, int height,
316 int dst_x, int dst_y)
319 SDLCopyArea(src_bitmap, dst_bitmap,
320 src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_MASKED);
322 XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
323 src_bitmap->clip_gc, src_x, src_y, width, height, dst_x, dst_y);
327 inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
331 SDLDrawSimpleLine(bitmap->surface, from_x, from_y, to_x, to_y, 0xffffff);
333 XSetForeground(display, bitmap->gc, WhitePixel(display, screen));
334 XDrawLine(display, bitmap->drawable, bitmap->gc, from_x, from_y, to_x, to_y);
335 XSetForeground(display, bitmap->gc, BlackPixel(display, screen));
339 /* execute all pending screen drawing operations */
340 inline void FlushDisplay(void)
347 /* execute and wait for all pending screen drawing operations */
348 inline void SyncDisplay(void)
351 XSync(display, FALSE);
355 inline void KeyboardAutoRepeatOn(void)
358 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
359 SDL_DEFAULT_REPEAT_INTERVAL / 2);
360 SDL_EnableUNICODE(1);
362 XAutoRepeatOn(display);
366 inline void KeyboardAutoRepeatOff(void)
369 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
370 SDL_EnableUNICODE(0);
372 XAutoRepeatOff(display);
376 inline boolean PointerInWindow(DrawWindow window)
386 /* if XQueryPointer() returns False, the pointer
387 is not on the same screen as the specified window */
388 return XQueryPointer(display, window->drawable, &root, &child,
389 &root_x, &root_y, &win_x, &win_y, &mask);
393 inline boolean SetVideoMode(boolean fullscreen)
396 return SDLSetVideoMode(&backbuffer, fullscreen);
398 boolean success = TRUE;
400 if (fullscreen && video.fullscreen_available)
402 Error(ERR_WARN, "fullscreen not available in X11 version");
404 /* display error message only once */
405 video.fullscreen_available = FALSE;
414 inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
417 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
418 (!fullscreen && video.fullscreen_enabled))
419 fullscreen = SetVideoMode(fullscreen);
426 /* ========================================================================= */
427 /* audio functions */
428 /* ========================================================================= */
430 inline boolean OpenAudio(struct AudioSystemInfo *audio)
432 audio->sound_available = FALSE;
433 audio->loops_available = FALSE;
434 audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
435 audio->soundserver_pid = 0;
436 audio->device_name = NULL;
437 audio->device_fd = 0;
439 #if defined(TARGET_SDL)
442 audio->sound_available = TRUE;
443 audio->loops_available = TRUE;
445 #elif defined(PLATFORM_MSDOS)
446 if (MSDOSOpenAudio())
448 audio->sound_available = TRUE;
449 audio->loops_available = TRUE;
451 #elif defined(PLATFORM_UNIX)
452 UnixOpenAudio(audio);
455 return audio->sound_available;
458 inline void CloseAudio(struct AudioSystemInfo *audio)
460 #if defined(TARGET_SDL)
462 #elif defined(PLATFORM_MSDOS)
464 #elif defined(PLATFORM_UNIX)
465 UnixCloseAudio(audio);
468 audio->sound_available = FALSE;
469 audio->loops_available = FALSE;
473 /* ========================================================================= */
474 /* event functions */
475 /* ========================================================================= */
477 inline void InitEventFilter(EventFilter filter_function)
480 /* set event filter to filter out certain events */
481 SDL_SetEventFilter(filter_function);
485 inline boolean PendingEvent(void)
488 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
490 return (XPending(display) ? TRUE : FALSE);
494 inline void NextEvent(Event *event)
497 SDL_WaitEvent(event);
499 XNextEvent(display, event);
503 inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
507 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
508 (int)event->keysym.unicode,
509 (int)event->keysym.sym,
510 (int)SDL_GetModState());
513 if (with_modifiers && event->keysym.unicode != 0)
514 return event->keysym.unicode;
516 return event->keysym.sym;
519 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
520 (int)XLookupKeysym(event, event->state),
521 (int)XLookupKeysym(event, 0));
525 return XLookupKeysym(event, event->state);
527 return XLookupKeysym(event, 0);
531 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
533 if (event->type != EVENT_CLIENTMESSAGE)
536 #if defined(TARGET_SDL)
537 return TRUE; /* the only possible message here is SDL_QUIT */
538 #elif defined(PLATFORM_UNIX)
539 if ((event->window == window->drawable) &&
540 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
548 inline void dummy(void)