cdf66b33dc05efb823ded0623cf4e44626314329
[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 struct AudioSystemInfo InitAudio(void)
238 {
239   struct AudioSystemInfo audio;
240
241   audio.sound_available = FALSE;
242   audio.loops_available = FALSE;
243   audio.soundserver_pipe[0] = audio.soundserver_pipe[1] = 0;
244   audio.soundserver_pid = 0;
245   audio.device_fd = 0;
246
247 #if defined(TARGET_SDL)
248   if (SDLInitAudio())
249   {
250     audio.sound_available = TRUE;
251     audio.loops_available = TRUE;
252   }
253 #elif defined(PLATFORM_MSDOS)
254   if (MSDOSInitAudio())
255   {
256     audio.sound_available = TRUE;
257     audio.loops_available = TRUE;
258   }
259 #elif defined(PLATFORM_UNIX)
260   UnixInitAudio(&audio);
261 #endif
262
263   return audio;
264 }
265
266
267 /* ========================================================================= */
268 /* event functions                                                           */
269 /* ========================================================================= */
270
271 inline void InitEventFilter(EventFilter filter_function)
272 {
273 #ifdef TARGET_SDL
274   /* set event filter to filter out certain events */
275   SDL_SetEventFilter(filter_function);
276 #endif
277 }
278
279 inline boolean PendingEvent(void)
280 {
281 #ifdef TARGET_SDL
282   return (SDL_PollEvent(NULL) ? TRUE : FALSE);
283 #else
284   return (XPending(display) ? TRUE : FALSE);
285 #endif
286 }
287
288 inline void NextEvent(Event *event)
289 {
290 #ifdef TARGET_SDL
291   SDL_WaitEvent(event);
292 #else
293   XNextEvent(display, event);
294 #endif
295 }
296
297 inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
298 {
299 #ifdef TARGET_SDL
300 #if 0
301   printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
302          (int)event->keysym.unicode,
303          (int)event->keysym.sym,
304          (int)SDL_GetModState());
305 #endif
306
307   if (with_modifiers && event->keysym.unicode != 0)
308     return event->keysym.unicode;
309   else
310     return event->keysym.sym;
311 #else
312 #if 0
313   printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
314          (int)XLookupKeysym(event, event->state),
315          (int)XLookupKeysym(event, 0));
316 #endif
317
318   if (with_modifiers)
319     return XLookupKeysym(event, event->state);
320   else
321     return XLookupKeysym(event, 0);
322 #endif
323 }
324
325 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
326 {
327   if (event->type != EVENT_CLIENTMESSAGE)
328     return FALSE;
329
330 #if defined(TARGET_SDL)
331   return TRUE;          /* the only possible message here is SDL_QUIT */
332 #elif defined(PLATFORM_UNIX)
333   if ((event->window == window) &&
334       (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
335     return TRUE;
336 #endif
337
338   return FALSE;
339 }
340
341
342 inline void dummy(void)
343 {
344 #ifdef TARGET_SDL
345 #else
346 #endif
347 }