SRC_DIR = src
MAKE_CMD = $(MAKE) -C $(SRC_DIR)
-# DEFAULT_TARGET = x11
-DEFAULT_TARGET = sdl
+DEFAULT_TARGET = x11
+# DEFAULT_TARGET = sdl
all:
@$(MAKE_CMD) TARGET=$(DEFAULT_TARGET)
-#define COMPILE_DATE_STRING "[2003-04-04 02:13]"
+#define COMPILE_DATE_STRING "[2003-04-04 23:16]"
/* event filter especially needed for SDL event filtering due to
- delay problems with lots of mouse motion events when mouse
- button not pressed */
+ delay problems with lots of mouse motion events when mouse button
+ not pressed (X11 can handle this with 'PointerMotionHintMask') */
int FilterMouseMotionEvents(const Event *event)
{
+ /* non-motion events are directly passed to event handler functions */
if (event->type != EVENT_MOTIONNOTIFY)
return 1;
- /* get mouse motion events without pressed button only in level editor */
+ /* when playing, display a different mouse pointer inside the playfield */
+ if (game_status == PLAYING)
+ {
+ static boolean inside_field = FALSE;
+ MotionEvent *motion = (MotionEvent *)event;
+
+ if ((motion->x >= SX && motion->x < SX + SXSIZE &&
+ motion->y >= SY && motion->y < SY + SYSIZE) != inside_field)
+ {
+ inside_field = !inside_field;
+
+ SetMouseCursor(inside_field ? CURSOR_PLAYFIELD : CURSOR_DEFAULT);
+ }
+ }
+
+ /* skip mouse motion events without pressed button outside level editor */
if (button_status == MB_RELEASED && game_status != LEVELED)
return 0;
else
PlayMusic(level_nr);
KeyboardAutoRepeatOff();
+ SetMouseCursor(CURSOR_PLAYFIELD);
if (options.debug)
{
Screen *screen;
Display *display;
BITMAP *mouse_bitmap = NULL;
- char *mouse_filename =getCustomImageFilename(program.msdos_pointer_filename);
+ char *mouse_filename = getCustomImageFilename(program.msdos_cursor_filename);
if ((mouse_bitmap = Read_PCX_to_AllegroBitmap(mouse_filename)) == NULL)
return NULL;
}
+/* ------------------------------------------------------------------------- */
+/* custom cursor fuctions */
+/* ------------------------------------------------------------------------- */
+
+static SDL_Cursor *create_cursor(const char **image)
+{
+ int i, row, col;
+ Uint8 data[4*32];
+ Uint8 mask[4*32];
+ int hot_x, hot_y;
+
+ i = -1;
+ for (row=0; row<32; ++row)
+ {
+ for (col=0; col<32; ++col)
+ {
+ if (col % 8)
+ {
+ data[i] <<= 1;
+ mask[i] <<= 1;
+ }
+ else
+ {
+ i++;
+ data[i] = mask[i] = 0;
+ }
+
+ switch (image[4+row][col])
+ {
+ case 'X':
+ data[i] |= 0x01;
+ mask[i] |= 0x01;
+ break;
+ case '.':
+ mask[i] |= 0x01;
+ break;
+ case ' ':
+ break;
+ }
+ }
+ }
+
+ sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+
+ return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+}
+
+void SDLSetMouseCursor(const char **cursor_image)
+{
+ static const char **last_cursor_image = NULL;
+ static SDL_Cursor *cursor_default = NULL;
+ static SDL_Cursor *cursor_current = NULL;
+
+ if (cursor_default == NULL)
+ cursor_default = SDL_GetCursor();
+
+ if (cursor_image != NULL && cursor_image != last_cursor_image)
+ {
+ cursor_current = create_cursor(cursor_image);
+ last_cursor_image = cursor_image;
+ }
+
+ SDL_SetCursor(cursor_image ? cursor_current : cursor_default);
+}
+
+
/* ========================================================================= */
/* audio functions */
/* ========================================================================= */
typedef struct SDLSurfaceInfo DrawBuffer;
typedef struct SDLSurfaceInfo DrawWindow;
typedef Uint32 Pixel;
+typedef SDL_Cursor *Cursor;
typedef SDLKey Key;
Bitmap *SDLLoadImage(char *);
+void SDLSetMouseCursor(const char **);
+
inline void SDLOpenAudio(void);
inline void SDLCloseAudio(void);
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)
{
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;
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)
}
+/* ------------------------------------------------------------------------- */
+/* mouse pointer functions */
+/* ------------------------------------------------------------------------- */
+
+/* cursor bitmap in XPM format */
+static const char *cursor_image_playfield[] =
+{
+ /* width height num_colors chars_per_pixel */
+ " 32 32 3 1",
+
+ /* colors */
+ "X c #000000",
+ ". c #ffffff",
+ " c None",
+
+ " X ",
+ "X.X ",
+ " X ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "1,1"
+};
+
+static struct MouseCursorInfo *get_cursor_from_image(const char **image)
+{
+ struct MouseCursorInfo *cursor;
+ int row, col, i;
+
+ cursor = checked_calloc(sizeof(struct MouseCursorInfo));
+
+ i = -1;
+ for (row=0; row<32; ++row)
+ {
+ for (col=0; col<32; ++col)
+ {
+ if (col % 8)
+ {
+ cursor->data[i] <<= 1;
+ cursor->mask[i] <<= 1;
+ }
+ else
+ {
+ i++;
+ cursor->data[i] = cursor->mask[i] = 0;
+ }
+
+ switch (image[4+row][col])
+ {
+ case 'X':
+ cursor->data[i] |= 0x01;
+ cursor->mask[i] |= 0x01;
+ break;
+
+ case '.':
+ cursor->mask[i] |= 0x01;
+ break;
+
+ case ' ':
+ break;
+ }
+ }
+ }
+
+ sscanf(image[4+row], "%d,%d", &cursor->hot_x, &cursor->hot_y);
+
+ cursor->width = 32;
+ cursor->height = 32;
+
+ return cursor;
+}
+
+void SetMouseCursor(int mode)
+{
+ 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 */
/* ========================================================================= */
#define DEFAULT_KEY_LOAD_GAME KSYM_F2
#define DEFAULT_KEY_TOGGLE_PAUSE KSYM_space
+
/* values for move directions and special "button" keys */
#define MV_BIT_LEFT 0
#define MV_BIT_RIGHT 1
(x) == MV_RIGHT ? MV_BIT_RIGHT : \
(x) == MV_UP ? MV_BIT_UP : MV_BIT_DOWN)
+
/* values for button status */
#define MB_NOT_PRESSED FALSE
#define MB_NOT_RELEASED TRUE
#define MB_MIDDLEBUTTON 2
#define MB_RIGHTBUTTON 3
+
/* values for animation mode (frame order and direction) */
#define ANIM_NONE 0
#define ANIM_LOOP (1 << 0)
#define ANIM_RANDOM (1 << 4)
#define ANIM_REVERSE (1 << 5)
+
/* values for redraw_mask */
#define REDRAW_NONE (0)
#define REDRAW_ALL (1 << 0)
#define REDRAW_FPS (1 << 11)
#define REDRAWTILES_THRESHOLD (SCR_FIELDX * SCR_FIELDY / 2)
+
+/* values for mouse cursor */
+#define CURSOR_DEFAULT 0
+#define CURSOR_PLAYFIELD 1
+
+#define CURSOR_MAX_WIDTH 32
+#define CURSOR_MAX_HEIGHT 32
+
+
/* maximum number of parallel players supported by libgame functions */
#define MAX_PLAYERS 4
char *x11_icon_filename;
char *x11_iconmask_filename;
- char *msdos_pointer_filename;
+ char *msdos_cursor_filename;
char *cookie_prefix;
char *filename_prefix; /* prefix to cut off from DOS filenames */
int fd[MAX_PLAYERS]; /* file descriptor of player's joystick */
};
+struct MouseCursorInfo
+{
+ int width, height;
+ int hot_x, hot_y;
+
+ char data[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+ char mask[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+};
+
struct SetupJoystickInfo
{
char *device_name; /* device name of player's joystick */
Bitmap *ZoomBitmap(Bitmap *, int, int);
void CreateBitmapWithSmallBitmaps(Bitmap *);
+void SetMouseCursor(int);
+
inline void OpenAudio(void);
inline void CloseAudio(void);
inline void SetAudioMode(boolean);
window_event_mask =
ExposureMask | StructureNotifyMask | FocusChangeMask |
ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
- PointerMotionHintMask | KeyPressMask | KeyReleaseMask;
+ KeyPressMask | KeyReleaseMask;
+
+ /* unwanted mouse motion events now get filtered out by filter function */
+ /* window_event_mask |= PointerMotionHintMask; */
XSelectInput(display, new_window->drawable, window_event_mask);
#endif
return pixel;
}
+/* ------------------------------------------------------------------------- */
+/* mouse pointer functions */
+/* ------------------------------------------------------------------------- */
+
+#if defined(TARGET_X11_NATIVE)
+
+static Cursor create_cursor(const char **image)
+{
+ Pixmap pixmap_data, pixmap_mask;
+ XColor color_fg, color_bg;
+ Cursor cursor;
+
+ int i, row, col;
+ char data[4*32];
+ char mask[4*32];
+ int hot_x, hot_y;
+
+ int data_width = 32, data_height = 32;
+ int mask_width = 32, mask_height = 32;
+
+ i = -1;
+ for (row=0; row<32; ++row)
+ {
+ for (col=0; col<32; ++col)
+ {
+ if (col % 8)
+ {
+ data[i] <<= 1;
+ mask[i] <<= 1;
+ }
+ else
+ {
+ i++;
+ data[i] = mask[i] = 0;
+ }
+
+ switch (image[4+row][col])
+ {
+ case 'X':
+ data[i] |= 0x01;
+ mask[i] |= 0x01;
+ break;
+ case '.':
+ mask[i] |= 0x01;
+ break;
+ case ' ':
+ break;
+ }
+ }
+ }
+
+ sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+
+ /* shape and mask are single plane pixmaps */
+ pixmap_data = XCreatePixmapFromBitmapData(display, window->drawable, data,
+ data_width, data_height, 1, 0, 1);
+ pixmap_mask = XCreatePixmapFromBitmapData(display, window->drawable, mask,
+ mask_width, mask_height, 1, 0, 1);
+
+ XParseColor(display, cmap, "black", &color_fg);
+ XParseColor(display, cmap, "white", &color_bg);
+
+ cursor = XCreatePixmapCursor(display, pixmap_data, pixmap_mask,
+ &color_fg, &color_bg, hot_x, hot_y);
+
+ return cursor;
+}
+
+void X11SetMouseCursor(const char **cursor_image)
+{
+ static const char **last_cursor_image = NULL;
+ static Cursor cursor_default = None;
+ static Cursor cursor_current = None;
+
+ if (cursor_image != NULL && cursor_image != last_cursor_image)
+ {
+ cursor_current = create_cursor(cursor_image);
+ last_cursor_image = cursor_image;
+ }
+
+ XDefineCursor(display, window->drawable,
+ cursor_image ? cursor_current : cursor_default);
+}
+#endif /* TARGET_X11_NATIVE */
+
#endif /* TARGET_X11 */
typedef struct X11DrawableInfo Bitmap;
typedef struct X11DrawableInfo DrawWindow;
typedef struct X11DrawableInfo DrawBuffer;
-/* "Pixel" is already defined in X11/Intrinsic.h */
+/* "Pixel" is already defined */
+/* "Cursor" is already defined */
typedef KeySym Key;
inline Pixel X11GetPixel(Bitmap *, int, int);
inline Pixel X11GetPixelFromRGB(unsigned int, unsigned int, unsigned int);
+#if defined(TARGET_X11_NATIVE)
+void X11SetMouseCursor(const char **);
+#endif
+
#endif /* X11_H */
KeyboardAutoRepeatOn();
ActivateJoystick();
+ SetMouseCursor(CURSOR_DEFAULT);
SetDrawDeactivationMask(REDRAW_NONE);
SetDrawBackgroundMask(REDRAW_FIELD);