From: Holger Schemel Date: Fri, 4 Apr 2003 21:34:59 +0000 (+0200) Subject: rnd-20030404-4-src X-Git-Tag: 3.0.0^2~112 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=de8b3ae622eae10f1caf96872fb1790f7bd9644b;p=rocksndiamonds.git rnd-20030404-4-src --- diff --git a/Makefile b/Makefile index ea7b1525..a5b3d976 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,8 @@ CROSS_PATH_WIN32=/usr/local/cross-tools/i386-mingw32msvc 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) diff --git a/src/conftime.h b/src/conftime.h index 695cc5da..90226b29 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-04-04 02:13]" +#define COMPILE_DATE_STRING "[2003-04-04 23:16]" diff --git a/src/events.c b/src/events.c index 332dcca2..b5be2a16 100644 --- a/src/events.c +++ b/src/events.c @@ -30,15 +30,31 @@ /* 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 diff --git a/src/game.c b/src/game.c index d60f158a..493bd5f6 100644 --- a/src/game.c +++ b/src/game.c @@ -948,6 +948,7 @@ void InitGame() PlayMusic(level_nr); KeyboardAutoRepeatOff(); + SetMouseCursor(CURSOR_PLAYFIELD); if (options.debug) { diff --git a/src/libgame/msdos.c b/src/libgame/msdos.c index 9cd4ddcc..ec19ef63 100644 --- a/src/libgame/msdos.c +++ b/src/libgame/msdos.c @@ -297,7 +297,7 @@ Display *XOpenDisplay(char *display_name) 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; diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 24064895..51c2baf8 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -1233,6 +1233,72 @@ Bitmap *SDLLoadImage(char *filename) } +/* ------------------------------------------------------------------------- */ +/* 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 */ /* ========================================================================= */ diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index e214879b..c2f55ee9 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -35,6 +35,7 @@ typedef struct SDLSurfaceInfo Bitmap; typedef struct SDLSurfaceInfo DrawBuffer; typedef struct SDLSurfaceInfo DrawWindow; typedef Uint32 Pixel; +typedef SDL_Cursor *Cursor; typedef SDLKey Key; @@ -338,6 +339,8 @@ void SDLZoomBitmap(Bitmap *, Bitmap *); Bitmap *SDLLoadImage(char *); +void SDLSetMouseCursor(const char **); + inline void SDLOpenAudio(void); inline void SDLCloseAudio(void); diff --git a/src/libgame/system.c b/src/libgame/system.c index 290b92a4..45fb77c1 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -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; @@ -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,119 @@ void CreateBitmapWithSmallBitmaps(Bitmap *src_bitmap) } +/* ------------------------------------------------------------------------- */ +/* 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 */ /* ========================================================================= */ diff --git a/src/libgame/system.h b/src/libgame/system.h index af31de3f..c8afb2de 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -66,6 +66,7 @@ #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 @@ -88,6 +89,7 @@ (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 @@ -101,6 +103,7 @@ #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) @@ -110,6 +113,7 @@ #define ANIM_RANDOM (1 << 4) #define ANIM_REVERSE (1 << 5) + /* values for redraw_mask */ #define REDRAW_NONE (0) #define REDRAW_ALL (1 << 0) @@ -135,6 +139,15 @@ #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 @@ -243,7 +256,7 @@ struct ProgramInfo 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 */ @@ -350,6 +363,15 @@ struct JoystickInfo 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 */ @@ -688,6 +710,8 @@ void ReloadCustomImage(Bitmap *, char *); Bitmap *ZoomBitmap(Bitmap *, int, int); void CreateBitmapWithSmallBitmaps(Bitmap *); +void SetMouseCursor(int); + inline void OpenAudio(void); inline void CloseAudio(void); inline void SetAudioMode(boolean); diff --git a/src/libgame/x11.c b/src/libgame/x11.c index fcf31601..61d1a1a5 100644 --- a/src/libgame/x11.c +++ b/src/libgame/x11.c @@ -199,7 +199,10 @@ static DrawWindow *X11InitWindow() 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 @@ -420,4 +423,89 @@ inline Pixel X11GetPixelFromRGB(unsigned int color_r, unsigned int color_g, 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 */ diff --git a/src/libgame/x11.h b/src/libgame/x11.h index 80226b6f..a4a0577f 100644 --- a/src/libgame/x11.h +++ b/src/libgame/x11.h @@ -51,7 +51,8 @@ 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; @@ -319,4 +320,8 @@ inline void X11DrawSimpleLine(Bitmap *, int, int, int, int, Pixel); 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 */ diff --git a/src/screens.c b/src/screens.c index 4be05731..6e8c548c 100644 --- a/src/screens.c +++ b/src/screens.c @@ -199,6 +199,7 @@ void DrawMainMenu() KeyboardAutoRepeatOn(); ActivateJoystick(); + SetMouseCursor(CURSOR_DEFAULT); SetDrawDeactivationMask(REDRAW_NONE); SetDrawBackgroundMask(REDRAW_FIELD);