rnd-20001129-2-src
[rocksndiamonds.git] / src / system.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
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 *----------------------------------------------------------*
12 *  system.c                                                *
13 ***********************************************************/
14
15 #include "main.h"
16 #include "misc.h"
17 #include "sound.h"
18
19
20 /* ========================================================================= */
21 /* video functions                                                           */
22 /* ========================================================================= */
23
24 inline void InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
25 {
26 #ifdef TARGET_SDL
27   SDLInitBufferedDisplay(backbuffer, window);
28 #else
29   X11InitBufferedDisplay(backbuffer, window);
30 #endif
31 }
32
33 inline int GetDisplayDepth(void)
34 {
35 #ifdef TARGET_SDL
36   return SDL_GetVideoSurface()->format->BitsPerPixel;
37 #else
38   return XDefaultDepth(display, screen);
39 #endif
40 }
41
42 inline Bitmap CreateBitmap(int width, int height, int depth)
43 {
44   int real_depth = (depth == DEFAULT_DEPTH ? GetDisplayDepth() : depth);
45
46 #ifdef TARGET_SDL
47   SDL_Surface *surface_tmp, *surface_native;
48
49   if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
50                                           real_depth, 0, 0, 0, 0))
51       == NULL)
52     Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
53
54   if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
55     Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
56
57   SDL_FreeSurface(surface_tmp);
58
59   return surface_native;
60 #else
61   Pixmap pixmap;
62
63   if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth)))
64     Error(ERR_EXIT, "cannot create pixmap");
65
66   return pixmap;
67 #endif
68 }
69
70 inline void FreeBitmap(Bitmap bitmap)
71 {
72 #ifdef TARGET_SDL
73   SDL_FreeSurface(bitmap);
74 #else
75   XFreePixmap(display, bitmap);
76 #endif
77 }
78
79 inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
80 {
81 #ifdef TARGET_SDL
82   SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
83 #else
84   XFillRectangle(display, bitmap, gc, x, y, width, height);
85 #endif
86 }
87
88 inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
89                        int src_x, int src_y,
90                        int width, int height,
91                        int dst_x, int dst_y)
92 {
93 #ifdef TARGET_SDL
94   SDLCopyArea(src_bitmap, dst_bitmap,
95               src_x, src_y, width, height, dst_x, dst_y);
96 #else
97   XCopyArea(display, src_bitmap, dst_bitmap, gc,
98             src_x, src_y, width, height, dst_x, dst_y);
99 #endif
100 }
101
102 #ifndef TARGET_SDL
103 static GC last_clip_gc = 0;     /* needed for XCopyArea() through clip mask */
104 #endif
105
106 inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap)
107 {
108 #ifndef TARGET_SDL
109   XSetClipMask(display, clip_gc, clip_pixmap);
110   last_clip_gc = clip_gc;
111 #endif
112 }
113
114 inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y)
115 {
116 #ifndef TARGET_SDL
117   XSetClipOrigin(display, clip_gc, clip_x, clip_y);
118   last_clip_gc = clip_gc;
119 #endif
120 }
121
122 inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
123                              int src_x, int src_y,
124                              int width, int height,
125                              int dst_x, int dst_y)
126 {
127 #ifdef TARGET_SDL
128   SDLCopyArea(src_bitmap, dst_bitmap,
129               src_x, src_y, width, height, dst_x, dst_y);
130 #else
131   XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc,
132             src_x, src_y, width, height, dst_x, dst_y);
133 #endif
134 }
135
136 inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
137                                 int to_x, int to_y)
138 {
139 #ifdef TARGET_SDL
140   SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff);
141 #else
142   XSetForeground(display, gc, WhitePixel(display, screen));
143   XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y);
144   XSetForeground(display, gc, BlackPixel(display, screen));
145 #endif
146 }
147
148 /* execute all pending screen drawing operations */
149 inline void FlushDisplay(void)
150 {
151 #ifndef TARGET_SDL
152   XFlush(display);
153 #endif
154 }
155
156 /* execute and wait for all pending screen drawing operations */
157 inline void SyncDisplay(void)
158 {
159 #ifndef TARGET_SDL
160   XSync(display, FALSE);
161 #endif
162 }
163
164 inline void KeyboardAutoRepeatOn(void)
165 {
166 #ifdef TARGET_SDL
167   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
168                       SDL_DEFAULT_REPEAT_INTERVAL / 2);
169   SDL_EnableUNICODE(1);
170 #else
171   XAutoRepeatOn(display);
172 #endif
173 }
174
175 inline void KeyboardAutoRepeatOff(void)
176 {
177 #ifdef TARGET_SDL
178   SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
179   SDL_EnableUNICODE(0);
180 #else
181   XAutoRepeatOff(display);
182 #endif
183 }
184
185 inline boolean PointerInWindow(DrawWindow window)
186 {
187 #ifdef TARGET_SDL
188   return TRUE;
189 #else
190   DrawWindow root, child;
191   int root_x, root_y;
192   unsigned int mask;
193   int win_x, win_y;
194
195   /* if XQueryPointer() returns False, the pointer
196      is not on the same screen as the specified window */
197   return XQueryPointer(display, window, &root, &child, &root_x, &root_y,
198                        &win_x, &win_y, &mask);
199 #endif
200 }
201
202 inline boolean SetVideoMode(void)
203 {
204 #ifdef TARGET_SDL
205   return SDLSetVideoMode(&backbuffer);
206 #else
207   boolean success = TRUE;
208
209   if (setup.fullscreen && fullscreen_available)
210   {
211     Error(ERR_WARN, "fullscreen not available in X11 version");
212
213     /* display error message only once */
214     fullscreen_available = FALSE;
215
216     success = FALSE;
217   }
218
219   return success;
220 #endif
221 }
222
223 inline void ChangeVideoModeIfNeeded(void)
224 {
225 #ifdef TARGET_SDL
226   if ((setup.fullscreen && !fullscreen_enabled && fullscreen_available) ||
227       (!setup.fullscreen && fullscreen_enabled))
228     SetVideoMode();
229 #endif
230 }
231
232
233 /* ========================================================================= */
234 /* audio functions                                                           */
235 /* ========================================================================= */
236
237 inline boolean OpenAudio(struct AudioSystemInfo *audio)
238 {
239   audio->sound_available = FALSE;
240   audio->loops_available = FALSE;
241   audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
242   audio->soundserver_pid = 0;
243   audio->device_fd = 0;
244
245 #if defined(TARGET_SDL)
246   if (SDLOpenAudio())
247   {
248     audio->sound_available = TRUE;
249     audio->loops_available = TRUE;
250   }
251 #elif defined(PLATFORM_MSDOS)
252   if (MSDOSOpenAudio())
253   {
254     audio->sound_available = TRUE;
255     audio->loops_available = TRUE;
256   }
257 #elif defined(PLATFORM_UNIX)
258   UnixOpenAudio(audio);
259 #endif
260
261   return audio->sound_available;
262 }
263
264 inline void CloseAudio(struct AudioSystemInfo *audio)
265 {
266 #if defined(TARGET_SDL)
267   SDLCloseAudio();
268 #elif defined(PLATFORM_MSDOS)
269   MSDOSCloseAudio();
270 #elif defined(PLATFORM_UNIX)
271   UnixCloseAudio(audio);
272 #endif
273
274   audio->sound_available = FALSE;
275   audio->loops_available = FALSE;
276 }
277
278
279 /* ========================================================================= */
280 /* event functions                                                           */
281 /* ========================================================================= */
282
283 inline void InitEventFilter(EventFilter filter_function)
284 {
285 #ifdef TARGET_SDL
286   /* set event filter to filter out certain events */
287   SDL_SetEventFilter(filter_function);
288 #endif
289 }
290
291 inline boolean PendingEvent(void)
292 {
293 #ifdef TARGET_SDL
294   return (SDL_PollEvent(NULL) ? TRUE : FALSE);
295 #else
296   return (XPending(display) ? TRUE : FALSE);
297 #endif
298 }
299
300 inline void NextEvent(Event *event)
301 {
302 #ifdef TARGET_SDL
303   SDL_WaitEvent(event);
304 #else
305   XNextEvent(display, event);
306 #endif
307 }
308
309 inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
310 {
311 #ifdef TARGET_SDL
312 #if 0
313   printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
314          (int)event->keysym.unicode,
315          (int)event->keysym.sym,
316          (int)SDL_GetModState());
317 #endif
318
319   if (with_modifiers && event->keysym.unicode != 0)
320     return event->keysym.unicode;
321   else
322     return event->keysym.sym;
323 #else
324 #if 0
325   printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
326          (int)XLookupKeysym(event, event->state),
327          (int)XLookupKeysym(event, 0));
328 #endif
329
330   if (with_modifiers)
331     return XLookupKeysym(event, event->state);
332   else
333     return XLookupKeysym(event, 0);
334 #endif
335 }
336
337 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
338 {
339   if (event->type != EVENT_CLIENTMESSAGE)
340     return FALSE;
341
342 #if defined(TARGET_SDL)
343   return TRUE;          /* the only possible message here is SDL_QUIT */
344 #elif defined(PLATFORM_UNIX)
345   if ((event->window == window) &&
346       (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
347     return TRUE;
348 #endif
349
350   return FALSE;
351 }
352
353
354 inline void dummy(void)
355 {
356 #ifdef TARGET_SDL
357 #else
358 #endif
359 }