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 ***********************************************************/
17 /* ========================================================================= */
18 /* internal variables */
19 /* ========================================================================= */
21 Display *display = NULL;
22 Visual *visual = NULL;
26 DrawWindow window = None;
27 DrawBuffer backbuffer = None;
33 /* ========================================================================= */
34 /* exported variables */
35 /* ========================================================================= */
37 struct ProgramInfo program;
38 struct VideoSystemInfo video;
39 struct AudioSystemInfo audio;
40 struct OptionInfo options;
43 /* ========================================================================= */
45 /* ========================================================================= */
47 inline static int GetRealDepth(int depth)
49 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
52 inline void InitProgramInfo(char *command_name, char *program_title,
53 char *window_title, char *icon_title,
54 char *x11_icon_filename,
55 char *x11_iconmask_filename,
56 char *msdos_pointer_filename)
58 program.command_name = command_name;
59 program.program_title = program_title;
60 program.window_title = window_title;
61 program.icon_title = icon_title;
62 program.x11_icon_filename = x11_icon_filename;
63 program.x11_iconmask_filename = x11_iconmask_filename;
64 program.msdos_pointer_filename = msdos_pointer_filename;
67 inline void InitScrollbufferSize(int scrollbuffer_width,
68 int scrollbuffer_height)
70 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
71 video.scrollbuffer_width = scrollbuffer_width;
72 video.scrollbuffer_height = scrollbuffer_height;
75 inline void InitVideoDisplay(void)
78 SDLInitVideoDisplay();
80 X11InitVideoDisplay();
84 inline void InitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
85 int width, int height, int depth,
89 video.height = height;
90 video.depth = GetRealDepth(depth);
91 video.fullscreen_available = FULLSCREEN_STATUS;
92 video.fullscreen_enabled = FALSE;
95 SDLInitVideoBuffer(backbuffer, window, fullscreen);
97 X11InitVideoBuffer(backbuffer, window);
101 inline Bitmap CreateBitmap(int width, int height, int depth)
103 int real_depth = GetRealDepth(depth);
106 SDL_Surface *surface_tmp, *surface_native;
108 if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
109 real_depth, 0, 0, 0, 0))
111 Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
113 if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
114 Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
116 SDL_FreeSurface(surface_tmp);
118 return surface_native;
122 if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth)))
123 Error(ERR_EXIT, "cannot create pixmap");
129 inline void FreeBitmap(Bitmap bitmap)
132 SDL_FreeSurface(bitmap);
134 XFreePixmap(display, bitmap);
138 inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
141 SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
143 XFillRectangle(display, bitmap, gc, x, y, width, height);
147 inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
148 int src_x, int src_y,
149 int width, int height,
150 int dst_x, int dst_y)
153 SDLCopyArea(src_bitmap, dst_bitmap,
154 src_x, src_y, width, height, dst_x, dst_y);
156 XCopyArea(display, src_bitmap, dst_bitmap, gc,
157 src_x, src_y, width, height, dst_x, dst_y);
162 static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */
165 inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap)
168 XSetClipMask(display, clip_gc, clip_pixmap);
169 last_clip_gc = clip_gc;
173 inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y)
176 XSetClipOrigin(display, clip_gc, clip_x, clip_y);
177 last_clip_gc = clip_gc;
181 inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
182 int src_x, int src_y,
183 int width, int height,
184 int dst_x, int dst_y)
187 SDLCopyArea(src_bitmap, dst_bitmap,
188 src_x, src_y, width, height, dst_x, dst_y);
190 XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc,
191 src_x, src_y, width, height, dst_x, dst_y);
195 inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
199 SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff);
201 XSetForeground(display, gc, WhitePixel(display, screen));
202 XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y);
203 XSetForeground(display, gc, BlackPixel(display, screen));
207 /* execute all pending screen drawing operations */
208 inline void FlushDisplay(void)
215 /* execute and wait for all pending screen drawing operations */
216 inline void SyncDisplay(void)
219 XSync(display, FALSE);
223 inline void KeyboardAutoRepeatOn(void)
226 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
227 SDL_DEFAULT_REPEAT_INTERVAL / 2);
228 SDL_EnableUNICODE(1);
230 XAutoRepeatOn(display);
234 inline void KeyboardAutoRepeatOff(void)
237 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
238 SDL_EnableUNICODE(0);
240 XAutoRepeatOff(display);
244 inline boolean PointerInWindow(DrawWindow window)
249 DrawWindow root, child;
254 /* if XQueryPointer() returns False, the pointer
255 is not on the same screen as the specified window */
256 return XQueryPointer(display, window, &root, &child, &root_x, &root_y,
257 &win_x, &win_y, &mask);
261 inline boolean SetVideoMode(boolean fullscreen)
264 return SDLSetVideoMode(&backbuffer, fullscreen);
266 boolean success = TRUE;
268 if (fullscreen && video.fullscreen_available)
270 Error(ERR_WARN, "fullscreen not available in X11 version");
272 /* display error message only once */
273 video.fullscreen_available = FALSE;
282 inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
285 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
286 (!fullscreen && video.fullscreen_enabled))
287 fullscreen = SetVideoMode(fullscreen);
294 /* ========================================================================= */
295 /* audio functions */
296 /* ========================================================================= */
298 inline boolean OpenAudio(struct AudioSystemInfo *audio)
300 audio->sound_available = FALSE;
301 audio->loops_available = FALSE;
302 audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
303 audio->soundserver_pid = 0;
304 audio->device_name = NULL;
305 audio->device_fd = 0;
307 #if defined(TARGET_SDL)
310 audio->sound_available = TRUE;
311 audio->loops_available = TRUE;
313 #elif defined(PLATFORM_MSDOS)
314 if (MSDOSOpenAudio())
316 audio->sound_available = TRUE;
317 audio->loops_available = TRUE;
319 #elif defined(PLATFORM_UNIX)
320 UnixOpenAudio(audio);
323 return audio->sound_available;
326 inline void CloseAudio(struct AudioSystemInfo *audio)
328 #if defined(TARGET_SDL)
330 #elif defined(PLATFORM_MSDOS)
332 #elif defined(PLATFORM_UNIX)
333 UnixCloseAudio(audio);
336 audio->sound_available = FALSE;
337 audio->loops_available = FALSE;
341 /* ========================================================================= */
342 /* event functions */
343 /* ========================================================================= */
345 inline void InitEventFilter(EventFilter filter_function)
348 /* set event filter to filter out certain events */
349 SDL_SetEventFilter(filter_function);
353 inline boolean PendingEvent(void)
356 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
358 return (XPending(display) ? TRUE : FALSE);
362 inline void NextEvent(Event *event)
365 SDL_WaitEvent(event);
367 XNextEvent(display, event);
371 inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
375 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
376 (int)event->keysym.unicode,
377 (int)event->keysym.sym,
378 (int)SDL_GetModState());
381 if (with_modifiers && event->keysym.unicode != 0)
382 return event->keysym.unicode;
384 return event->keysym.sym;
387 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
388 (int)XLookupKeysym(event, event->state),
389 (int)XLookupKeysym(event, 0));
393 return XLookupKeysym(event, event->state);
395 return XLookupKeysym(event, 0);
399 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
401 if (event->type != EVENT_CLIENTMESSAGE)
404 #if defined(TARGET_SDL)
405 return TRUE; /* the only possible message here is SDL_QUIT */
406 #elif defined(PLATFORM_UNIX)
407 if ((event->window == window) &&
408 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
416 inline void dummy(void)