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