rnd-20001210-2-src
[rocksndiamonds.git] / src / libgame / system.c
index bc7d5a13c304116bacf57da84c57e721dc069ae5..5217460d47f80ed11a9dc3dcb4b14b7de09790cf 100644 (file)
@@ -12,6 +12,7 @@
 ***********************************************************/
 
 #include <string.h>
+#include <signal.h>
 
 #include "platform.h"
 
@@ -42,9 +43,9 @@ Visual               *visual = NULL;
 int            screen = 0;
 Colormap       cmap = None;
 
-DrawWindow     window = NULL;
-DrawBuffer     backbuffer = NULL;
-DrawBuffer     drawto = NULL;
+DrawWindow     *window = NULL;
+DrawBuffer     *backbuffer = NULL;
+DrawBuffer     *drawto = NULL;
 
 int            button_status = MB_NOT_PRESSED;
 boolean                motion_status = FALSE;
@@ -56,7 +57,7 @@ int           FrameCounter = 0;
 
 
 /* ========================================================================= */
-/* init functions                                                            */
+/* init/close functions                                                      */
 /* ========================================================================= */
 
 void InitCommandName(char *argv0)
@@ -68,6 +69,15 @@ void InitCommandName(char *argv0)
 void InitExitFunction(void (*exit_function)(int))
 {
   program.exit_function = exit_function;
+
+  /* set signal handlers to custom exit function */
+  signal(SIGINT, exit_function);
+  signal(SIGTERM, exit_function);
+
+#if defined(TARGET_SDL)
+  /* set exit function to automatically cleanup SDL stuff after exit() */
+  atexit(SDL_Quit);
+#endif
 }
 
 void InitPlatformDependantStuff(void)
@@ -75,6 +85,23 @@ void InitPlatformDependantStuff(void)
 #if defined(PLATFORM_MSDOS)
   _fmode = O_BINARY;
 #endif
+
+#if !defined(PLATFORM_UNIX)
+  program.userdata_directory = "userdata";
+  initErrorFile();
+#endif
+
+#if defined(TARGET_SDL)
+  if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
+    Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+#endif
+}
+
+void ClosePlatformDependantStuff(void)
+{
+#if !defined(PLATFORM_UNIX)
+  dumpErrorFile();
+#endif
 }
 
 void InitProgramInfo(char *unix_userdata_directory, char *program_title,
@@ -159,7 +186,15 @@ inline void InitVideoDisplay(void)
 #endif
 }
 
-inline void InitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
+inline void CloseVideoDisplay(void)
+{
+#if defined(TARGET_X11)
+  if (display)
+    XCloseDisplay(display);
+#endif
+}
+
+inline void InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window,
                            int width, int height, int depth,
                            boolean fullscreen)
 {
@@ -176,7 +211,7 @@ inline void InitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
 #endif
 }
 
-inline Bitmap CreateBitmapStruct(void)
+inline Bitmap *CreateBitmapStruct(void)
 {
 #ifdef TARGET_SDL
   return checked_calloc(sizeof(struct SDLSurfaceInfo));
@@ -185,9 +220,9 @@ inline Bitmap CreateBitmapStruct(void)
 #endif
 }
 
-inline Bitmap CreateBitmap(int width, int height, int depth)
+inline Bitmap *CreateBitmap(int width, int height, int depth)
 {
-  Bitmap new_bitmap = CreateBitmapStruct();
+  Bitmap *new_bitmap = CreateBitmapStruct();
   int real_depth = GetRealDepth(depth);
 
 #ifdef TARGET_SDL
@@ -226,7 +261,7 @@ inline Bitmap CreateBitmap(int width, int height, int depth)
   return new_bitmap;
 }
 
-inline void FreeBitmap(Bitmap bitmap)
+inline void FreeBitmap(Bitmap *bitmap)
 {
   if (bitmap == NULL)
     return;
@@ -248,7 +283,7 @@ inline void FreeBitmap(Bitmap bitmap)
   free(bitmap);
 }
 
-inline void CloseWindow(DrawWindow window)
+inline void CloseWindow(DrawWindow *window)
 {
 #ifdef TARGET_X11
   if (window->drawable)
@@ -261,7 +296,7 @@ inline void CloseWindow(DrawWindow window)
 #endif
 }
 
-inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
+inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
                       int src_x, int src_y,
                       int width, int height,
                       int dst_x, int dst_y)
@@ -275,7 +310,7 @@ inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
 #endif
 }
 
-inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
+inline void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
 {
 #ifdef TARGET_SDL
   SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
@@ -290,7 +325,7 @@ static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */
 #endif
 #endif
 
-inline void SetClipMask(Bitmap bitmap, GC clip_gc, Pixmap clip_pixmap)
+inline void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
 {
 #ifdef TARGET_X11
   if (clip_gc)
@@ -304,7 +339,7 @@ inline void SetClipMask(Bitmap bitmap, GC clip_gc, Pixmap clip_pixmap)
 #endif
 }
 
-inline void SetClipOrigin(Bitmap bitmap, GC clip_gc, int clip_x, int clip_y)
+inline void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
 {
 #ifdef TARGET_X11
   if (clip_gc)
@@ -318,7 +353,7 @@ inline void SetClipOrigin(Bitmap bitmap, GC clip_gc, int clip_x, int clip_y)
 #endif
 }
 
-inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
+inline void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
                             int src_x, int src_y,
                             int width, int height,
                             int dst_x, int dst_y)
@@ -332,7 +367,7 @@ inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
 #endif
 }
 
-inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
+inline void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
                                int to_x, int to_y)
 {
 #ifdef TARGET_SDL
@@ -345,7 +380,7 @@ inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
 }
 
 #if !defined(TARGET_X11_NATIVE)
-inline void DrawLine(Bitmap bitmap, int from_x, int from_y,
+inline void DrawLine(Bitmap *bitmap, int from_x, int from_y,
                     int to_x, int to_y, Pixel pixel, int line_width)
 {
   int x, y;
@@ -375,7 +410,7 @@ inline void DrawLine(Bitmap bitmap, int from_x, int from_y,
 }
 #endif
 
-inline void DrawLines(Bitmap bitmap, struct XY *points, int num_points,
+inline void DrawLines(Bitmap *bitmap, struct XY *points, int num_points,
                      Pixel pixel)
 {
 #if !defined(TARGET_X11_NATIVE)
@@ -399,7 +434,7 @@ inline void DrawLines(Bitmap bitmap, struct XY *points, int num_points,
 #endif
 }
 
-inline Pixel GetPixelFromRGB(Bitmap bitmap, unsigned int color_r,
+inline Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
                             unsigned int color_g, unsigned int color_b)
 {
   Pixel pixel;
@@ -420,7 +455,7 @@ inline Pixel GetPixelFromRGB(Bitmap bitmap, unsigned int color_r,
   return pixel;
 }
 
-inline Pixel GetPixelFromRGBcompact(Bitmap bitmap, unsigned int color)
+inline Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
 {
   unsigned int color_r = (color >> 16) & 0xff;
   unsigned int color_g = (color >>  8) & 0xff;
@@ -452,7 +487,8 @@ inline void KeyboardAutoRepeatOn(void)
                      SDL_DEFAULT_REPEAT_INTERVAL / 2);
   SDL_EnableUNICODE(1);
 #else
-  XAutoRepeatOn(display);
+  if (display)
+    XAutoRepeatOn(display);
 #endif
 }
 
@@ -462,11 +498,12 @@ inline void KeyboardAutoRepeatOff(void)
   SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
   SDL_EnableUNICODE(0);
 #else
-  XAutoRepeatOff(display);
+  if (display)
+    XAutoRepeatOff(display);
 #endif
 }
 
-inline boolean PointerInWindow(DrawWindow window)
+inline boolean PointerInWindow(DrawWindow *window)
 {
 #ifdef TARGET_SDL
   return TRUE;
@@ -515,55 +552,66 @@ inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
   return fullscreen;
 }
 
+Bitmap *LoadImage(char *basename)
+{
+  Bitmap *new_bitmap;
+  char *filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
+                           basename);
+
+#if defined(TARGET_SDL)
+  new_bitmap = SDLLoadImage(filename);
+#else
+  new_bitmap = X11LoadImage(filename);
+#endif
+
+  free(filename);
+
+  return new_bitmap;
+}
+
 
 /* ========================================================================= */
 /* audio functions                                                           */
 /* ========================================================================= */
 
-inline boolean OpenAudio(struct AudioSystemInfo *audio)
+inline void OpenAudio(void)
 {
-  audio->sound_available = FALSE;
-  audio->loops_available = FALSE;
-  audio->sound_enabled = FALSE;
-  audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
-  audio->soundserver_pid = 0;
-  audio->device_name = NULL;
-  audio->device_fd = 0;
+  /* always start with reliable default values */
+  audio.sound_available = FALSE;
+  audio.music_available = FALSE;
+  audio.loops_available = FALSE;
+  audio.mods_available = FALSE;
+  audio.sound_enabled = FALSE;
+
+  audio.soundserver_pipe[0] = audio.soundserver_pipe[1] = 0;
+  audio.soundserver_pid = 0;
+  audio.device_name = NULL;
+  audio.device_fd = 0;
+
+  audio.channels = 0;
+  audio.music_channel = 0;
+  audio.music_nr = 0;
 
 #if defined(TARGET_SDL)
-  if (SDLOpenAudio())
-  {
-    audio->sound_available = TRUE;
-    audio->loops_available = TRUE;
-    audio->sound_enabled = TRUE;
-  }
+  SDLOpenAudio();
 #elif defined(PLATFORM_MSDOS)
-  if (MSDOSOpenAudio())
-  {
-    audio->sound_available = TRUE;
-    audio->loops_available = TRUE;
-    audio->sound_enabled = TRUE;
-  }
+  MSDOSOpenAudio();
 #elif defined(PLATFORM_UNIX)
-  UnixOpenAudio(audio);
+  UnixOpenAudio();
 #endif
-
-  return audio->sound_available;
 }
 
-inline void CloseAudio(struct AudioSystemInfo *audio)
+inline void CloseAudio(void)
 {
 #if defined(TARGET_SDL)
   SDLCloseAudio();
 #elif defined(PLATFORM_MSDOS)
   MSDOSCloseAudio();
 #elif defined(PLATFORM_UNIX)
-  UnixCloseAudio(audio);
+  UnixCloseAudio();
 #endif
 
-  audio->sound_available = FALSE;
-  audio->loops_available = FALSE;
-  audio->sound_enabled = FALSE;
+  audio.sound_enabled = FALSE;
 }
 
 inline void SetAudioMode(boolean enabled)