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)
28 /* ========================================================================= */
29 /* exported variables */
30 /* ========================================================================= */
32 struct ProgramInfo program;
33 struct OptionInfo options;
34 struct VideoSystemInfo video;
35 struct AudioSystemInfo audio;
38 struct LevelDirInfo *leveldir_first = NULL;
39 struct LevelDirInfo *leveldir_current = NULL;
41 Display *display = NULL;
42 Visual *visual = NULL;
46 DrawWindow window = NULL;
47 DrawBuffer backbuffer = NULL;
48 DrawBuffer drawto = NULL;
50 int button_status = MB_NOT_PRESSED;
51 boolean motion_status = FALSE;
53 int redraw_mask = REDRAW_NONE;
59 /* ========================================================================= */
61 /* ========================================================================= */
63 void InitCommandName(char *argv0)
65 program.command_basename =
66 (strrchr(argv0, '/') ? strrchr(argv0, '/') + 1 : argv0);
69 void InitExitFunction(void (*exit_function)(int))
71 program.exit_function = exit_function;
74 void InitPlatformDependantStuff(void)
76 #if defined(PLATFORM_MSDOS)
81 void InitProgramInfo(char *unix_userdata_directory, char *program_title,
82 char *window_title, char *icon_title,
83 char *x11_icon_basename, char *x11_iconmask_basename,
84 char *msdos_pointer_basename)
86 char *gfx_dir = getPath2(options.ro_base_directory, GRAPHICS_DIRECTORY);
87 char *x11_icon_filename = getPath2(gfx_dir, x11_icon_basename);
88 char *x11_iconmask_filename = getPath2(gfx_dir, x11_iconmask_basename);
89 char *msdos_pointer_filename = getPath2(gfx_dir, msdos_pointer_basename);
93 #if defined(PLATFORM_UNIX)
94 program.userdata_directory = unix_userdata_directory;
96 program.userdata_directory = "userdata";
99 program.program_title = program_title;
100 program.window_title = window_title;
101 program.icon_title = icon_title;
102 program.x11_icon_filename = x11_icon_filename;
103 program.x11_iconmask_filename = x11_iconmask_filename;
104 program.msdos_pointer_filename = msdos_pointer_filename;
107 void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
108 int real_sx, int real_sy,
109 int full_sxsize, int full_sysize)
115 gfx.real_sx = real_sx;
116 gfx.real_sy = real_sy;
117 gfx.full_sxsize = full_sxsize;
118 gfx.full_sysize = full_sysize;
121 void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
129 void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
137 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
139 /* currently only used by MSDOS code to alloc VRAM buffer, if available */
140 gfx.scrollbuffer_width = scrollbuffer_width;
141 gfx.scrollbuffer_height = scrollbuffer_height;
145 /* ========================================================================= */
146 /* video functions */
147 /* ========================================================================= */
149 inline static int GetRealDepth(int depth)
151 return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
154 inline void InitVideoDisplay(void)
157 SDLInitVideoDisplay();
159 X11InitVideoDisplay();
163 inline void InitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
164 int width, int height, int depth,
168 video.height = height;
169 video.depth = GetRealDepth(depth);
170 video.fullscreen_available = FULLSCREEN_STATUS;
171 video.fullscreen_enabled = FALSE;
174 SDLInitVideoBuffer(backbuffer, window, fullscreen);
176 X11InitVideoBuffer(backbuffer, window);
180 inline Bitmap CreateBitmapStruct(void)
183 return checked_calloc(sizeof(struct SDLSurfaceInfo));
185 return checked_calloc(sizeof(struct X11DrawableInfo));
189 inline Bitmap CreateBitmap(int width, int height, int depth)
191 Bitmap new_bitmap = CreateBitmapStruct();
192 int real_depth = GetRealDepth(depth);
195 SDL_Surface *surface_tmp, *surface_native;
197 if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
198 real_depth, 0, 0, 0, 0))
200 Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
202 if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
203 Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
205 SDL_FreeSurface(surface_tmp);
207 new_bitmap->surface = surface_native;
211 if (!(pixmap = XCreatePixmap(display, window->drawable,
212 width, height, real_depth)))
213 Error(ERR_EXIT, "cannot create pixmap");
214 new_bitmap->drawable = pixmap;
217 Error(ERR_EXIT, "Window GC needed for Bitmap -- create Window first");
218 new_bitmap->gc = window->gc;
225 inline void FreeBitmap(Bitmap bitmap)
232 SDL_FreeSurface(bitmap->surface);
233 if (bitmap->surface_masked)
234 SDL_FreeSurface(bitmap->surface_masked);
236 if (bitmap->drawable)
237 XFreePixmap(display, bitmap->drawable);
238 if (bitmap->clip_mask)
239 XFreePixmap(display, bitmap->clip_mask);
240 if (bitmap->stored_clip_gc)
241 XFreeGC(display, bitmap->stored_clip_gc);
247 inline void CloseWindow(DrawWindow window)
250 if (window->drawable)
252 XUnmapWindow(display, window->drawable);
253 XDestroyWindow(display, window->drawable);
256 XFreeGC(display, window->gc);
260 inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
261 int src_x, int src_y,
262 int width, int height,
263 int dst_x, int dst_y)
266 SDLCopyArea(src_bitmap, dst_bitmap,
267 src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_OPAQUE);
269 XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
270 dst_bitmap->gc, src_x, src_y, width, height, dst_x, dst_y);
274 inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
277 SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
279 XFillRectangle(display, bitmap->drawable, bitmap->gc, x, y, width, height);
285 static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */
289 inline void SetClipMask(Bitmap bitmap, GC clip_gc, Pixmap clip_pixmap)
294 bitmap->clip_gc = clip_gc;
295 XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
298 last_clip_gc = clip_gc;
303 inline void SetClipOrigin(Bitmap bitmap, GC clip_gc, int clip_x, int clip_y)
308 bitmap->clip_gc = clip_gc;
309 XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
312 last_clip_gc = clip_gc;
317 inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
318 int src_x, int src_y,
319 int width, int height,
320 int dst_x, int dst_y)
323 SDLCopyArea(src_bitmap, dst_bitmap,
324 src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_MASKED);
326 XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
327 src_bitmap->clip_gc, src_x, src_y, width, height, dst_x, dst_y);
331 inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
335 SDLDrawSimpleLine(bitmap->surface, from_x, from_y, to_x, to_y, 0xffffff);
337 XSetForeground(display, bitmap->gc, WhitePixel(display, screen));
338 XDrawLine(display, bitmap->drawable, bitmap->gc, from_x, from_y, to_x, to_y);
339 XSetForeground(display, bitmap->gc, BlackPixel(display, screen));
343 /* execute all pending screen drawing operations */
344 inline void FlushDisplay(void)
351 /* execute and wait for all pending screen drawing operations */
352 inline void SyncDisplay(void)
355 XSync(display, FALSE);
359 inline void KeyboardAutoRepeatOn(void)
362 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
363 SDL_DEFAULT_REPEAT_INTERVAL / 2);
364 SDL_EnableUNICODE(1);
366 XAutoRepeatOn(display);
370 inline void KeyboardAutoRepeatOff(void)
373 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
374 SDL_EnableUNICODE(0);
376 XAutoRepeatOff(display);
380 inline boolean PointerInWindow(DrawWindow window)
390 /* if XQueryPointer() returns False, the pointer
391 is not on the same screen as the specified window */
392 return XQueryPointer(display, window->drawable, &root, &child,
393 &root_x, &root_y, &win_x, &win_y, &mask);
397 inline boolean SetVideoMode(boolean fullscreen)
400 return SDLSetVideoMode(&backbuffer, fullscreen);
402 boolean success = TRUE;
404 if (fullscreen && video.fullscreen_available)
406 Error(ERR_WARN, "fullscreen not available in X11 version");
408 /* display error message only once */
409 video.fullscreen_available = FALSE;
418 inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
421 if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
422 (!fullscreen && video.fullscreen_enabled))
423 fullscreen = SetVideoMode(fullscreen);
430 /* ========================================================================= */
431 /* audio functions */
432 /* ========================================================================= */
434 inline boolean OpenAudio(struct AudioSystemInfo *audio)
436 audio->sound_available = FALSE;
437 audio->loops_available = FALSE;
438 audio->sound_enabled = FALSE;
439 audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
440 audio->soundserver_pid = 0;
441 audio->device_name = NULL;
442 audio->device_fd = 0;
444 #if defined(TARGET_SDL)
447 audio->sound_available = TRUE;
448 audio->loops_available = TRUE;
449 audio->sound_enabled = TRUE;
451 #elif defined(PLATFORM_MSDOS)
452 if (MSDOSOpenAudio())
454 audio->sound_available = TRUE;
455 audio->loops_available = TRUE;
456 audio->sound_enabled = TRUE;
458 #elif defined(PLATFORM_UNIX)
459 UnixOpenAudio(audio);
462 return audio->sound_available;
465 inline void CloseAudio(struct AudioSystemInfo *audio)
467 #if defined(TARGET_SDL)
469 #elif defined(PLATFORM_MSDOS)
471 #elif defined(PLATFORM_UNIX)
472 UnixCloseAudio(audio);
475 audio->sound_available = FALSE;
476 audio->loops_available = FALSE;
477 audio->sound_enabled = FALSE;
480 inline void SetAudioMode(boolean enabled)
482 if (!audio.sound_available)
485 audio.sound_enabled = enabled;
489 /* ========================================================================= */
490 /* event functions */
491 /* ========================================================================= */
493 inline void InitEventFilter(EventFilter filter_function)
496 /* set event filter to filter out certain events */
497 SDL_SetEventFilter(filter_function);
501 inline boolean PendingEvent(void)
504 return (SDL_PollEvent(NULL) ? TRUE : FALSE);
506 return (XPending(display) ? TRUE : FALSE);
510 inline void NextEvent(Event *event)
513 SDL_WaitEvent(event);
515 XNextEvent(display, event);
519 inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
523 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
524 (int)event->keysym.unicode,
525 (int)event->keysym.sym,
526 (int)SDL_GetModState());
529 if (with_modifiers && event->keysym.unicode != 0)
530 return event->keysym.unicode;
532 return event->keysym.sym;
535 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
536 (int)XLookupKeysym(event, event->state),
537 (int)XLookupKeysym(event, 0));
541 return XLookupKeysym(event, event->state);
543 return XLookupKeysym(event, 0);
547 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
549 if (event->type != EVENT_CLIENTMESSAGE)
552 #if defined(TARGET_SDL)
553 return TRUE; /* the only possible message here is SDL_QUIT */
554 #elif defined(PLATFORM_UNIX)
555 if ((event->window == window->drawable) &&
556 (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
564 inline void dummy(void)