rnd-20030703-1-src
[rocksndiamonds.git] / src / libgame / system.c
index 290b92a4889d0ffb256a020f69fd669d601e33f5..bfa9966bb0eb742f7f370247ffb181f86dede637 100644 (file)
@@ -70,7 +70,7 @@ void InitProgramInfo(char *argv0,
                     char *userdata_directory, char *program_title,
                     char *window_title, char *icon_title,
                     char *x11_icon_filename, char *x11_iconmask_filename,
-                    char *msdos_pointer_filename,
+                    char *msdos_cursor_filename,
                     char *cookie_prefix, char *filename_prefix,
                     int program_version)
 {
@@ -83,7 +83,7 @@ void InitProgramInfo(char *argv0,
   program.icon_title = icon_title;
   program.x11_icon_filename = x11_icon_filename;
   program.x11_iconmask_filename = x11_iconmask_filename;
-  program.msdos_pointer_filename = msdos_pointer_filename;
+  program.msdos_cursor_filename = msdos_cursor_filename;
 
   program.cookie_prefix = cookie_prefix;
   program.filename_prefix = filename_prefix;
@@ -107,7 +107,7 @@ void InitExitFunction(void (*exit_function)(int))
 #endif
 }
 
-void InitPlatformDependantStuff(void)
+void InitPlatformDependentStuff(void)
 {
 #if defined(PLATFORM_MSDOS)
   _fmode = O_BINARY;
@@ -120,7 +120,7 @@ void InitPlatformDependantStuff(void)
 #endif
 }
 
-void ClosePlatformDependantStuff(void)
+void ClosePlatformDependentStuff(void)
 {
 #if defined(PLATFORM_MSDOS)
   dumpErrorFile();
@@ -607,6 +607,10 @@ inline void DrawLines(Bitmap *bitmap, struct XY *points, int num_points,
 
 inline Pixel GetPixel(Bitmap *bitmap, int x, int y)
 {
+  if (x < 0 || x >= bitmap->width ||
+      y < 0 || y >= bitmap->height)
+    return BLACK_PIXEL;
+
 #if defined(TARGET_SDL)
   return SDLGetPixel(bitmap, x, y);
 #elif defined(TARGET_ALLEGRO)
@@ -847,6 +851,111 @@ void CreateBitmapWithSmallBitmaps(Bitmap *src_bitmap)
 }
 
 
+/* ------------------------------------------------------------------------- */
+/* mouse pointer functions                                                   */
+/* ------------------------------------------------------------------------- */
+
+/* XPM */
+static const char *cursor_image_playfield[] =
+{
+  /* width height num_colors chars_per_pixel */
+  "    16    16        3            1",
+
+  /* colors */
+  "X c #000000",
+  ". c #ffffff",
+  "  c None",
+
+  /* pixels */
+  " X              ",
+  "X.X             ",
+  " X              ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+  "                ",
+
+  /* hot spot */
+  "1,1"
+};
+
+#if defined(TARGET_SDL)
+static const int cursor_bit_order = BIT_ORDER_MSB;
+#elif defined(TARGET_X11_NATIVE)
+static const int cursor_bit_order = BIT_ORDER_LSB;
+#endif
+
+static struct MouseCursorInfo *get_cursor_from_image(const char **image)
+{
+  struct MouseCursorInfo *cursor;
+  boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
+  int header_lines = 4;
+  int x, y, i;
+
+  cursor = checked_calloc(sizeof(struct MouseCursorInfo));
+
+  sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
+
+  i = -1;
+  for (y=0; y < cursor->width; y++)
+  {
+    for (x=0; x < cursor->height; x++)
+    {
+      int bit_nr = x % 8;
+      int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
+
+      if (bit_nr == 0)
+      {
+        i++;
+        cursor->data[i] = cursor->mask[i] = 0;
+      }
+
+      switch (image[header_lines + y][x])
+      {
+        case 'X':
+         cursor->data[i] |= bit_mask;
+         cursor->mask[i] |= bit_mask;
+         break;
+
+        case '.':
+         cursor->mask[i] |= bit_mask;
+         break;
+
+        case ' ':
+         break;
+      }
+    }
+  }
+
+  sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
+
+  return cursor;
+}
+
+void SetMouseCursor(int mode)
+{
+  static struct MouseCursorInfo *cursor_playfield = NULL;
+
+  if (cursor_playfield == NULL)
+    cursor_playfield = get_cursor_from_image(cursor_image_playfield);
+
+#if defined(TARGET_SDL)
+  SDLSetMouseCursor(mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
+#elif defined(TARGET_X11_NATIVE)
+  X11SetMouseCursor(mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
+#endif
+}
+
+
 /* ========================================================================= */
 /* audio functions                                                           */
 /* ========================================================================= */
@@ -961,6 +1070,64 @@ inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
 #endif
 }
 
+inline KeyMod HandleKeyModState(Key key, int key_status)
+{
+#if !defined(TARGET_SDL)
+  static KeyMod current_modifiers = KMOD_None;
+
+  if (key != KSYM_UNDEFINED)   /* new key => check for modifier key change */
+  {
+    KeyMod new_modifier = KMOD_None;
+
+    switch(key)
+    {
+      case KSYM_Shift_L:
+       new_modifier = KMOD_Shift_L;
+       break;
+      case KSYM_Shift_R:
+       new_modifier = KMOD_Shift_R;
+       break;
+      case KSYM_Control_L:
+       new_modifier = KMOD_Control_L;
+       break;
+      case KSYM_Control_R:
+       new_modifier = KMOD_Control_R;
+       break;
+      case KSYM_Meta_L:
+       new_modifier = KMOD_Meta_L;
+       break;
+      case KSYM_Meta_R:
+       new_modifier = KMOD_Meta_R;
+       break;
+      case KSYM_Alt_L:
+       new_modifier = KMOD_Alt_L;
+       break;
+      case KSYM_Alt_R:
+       new_modifier = KMOD_Alt_R;
+       break;
+      default:
+       break;
+    }
+
+    if (key_status == KEY_PRESSED)
+      current_modifiers |= new_modifier;
+    else
+      current_modifiers &= ~new_modifier;
+  }
+
+  return current_modifiers;
+#endif
+}
+
+inline KeyMod GetKeyModState()
+{
+#if defined(TARGET_SDL)
+  return (KeyMod)SDL_GetModState();
+#else
+  return HandleKeyModState(KSYM_UNDEFINED, 0);
+#endif
+}
+
 inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
 {
   if (event->type != EVENT_CLIENTMESSAGE)