From 14089dac2cbe56e563863e1e5adb8847944fd262 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 5 Jan 2003 20:26:40 +0100 Subject: [PATCH] rnd-20030105-1-src --- src/conf_gfx.c | 2 +- src/conf_gfx.h | 2 +- src/conftime.h | 2 +- src/editor.c | 196 ++++++++++++------------------------------ src/game.c | 2 +- src/init.c | 60 ++++++++++++- src/libgame/gadgets.c | 52 ++++++----- src/libgame/system.c | 44 ++++++++++ src/libgame/system.h | 17 ++++ src/libgame/text.c | 144 +++++++++++++++++++++++++++---- src/libgame/text.h | 14 +-- src/main.h | 5 ++ src/screens.c | 101 ++++++++++++++-------- src/tools.c | 59 ++++++++----- src/tools.h | 1 + 15 files changed, 447 insertions(+), 254 deletions(-) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 04d0634f..72e5e04a 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -2584,7 +2584,7 @@ struct ConfigInfo image_config[] = /* keyword to stop parser: "NO_MORE_ELEMENT_IMAGES" <-- do not change! */ { "menu.frame", "RocksScreen.pcx" }, - { "menu.back", UNDEFINED_FILENAME }, + { "menu.background", UNDEFINED_FILENAME }, { "menu.door", "RocksDoor.pcx" }, { "menu.toons", "RocksToons.pcx" }, { "menu.font_big", "RocksFontBig.pcx" }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index de9f530c..9d29cde6 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -755,7 +755,7 @@ #define IMG_CUSTOM_126 734 #define IMG_CUSTOM_127 735 #define IMG_MENU_FRAME 736 -#define IMG_MENU_BACK 737 +#define IMG_MENU_BACKGROUND 737 #define IMG_MENU_DOOR 738 #define IMG_MENU_TOONS 739 #define IMG_MENU_FONT_BIG 740 diff --git a/src/conftime.h b/src/conftime.h index 7f6fc6d3..73fc3a53 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-01-04 04:16]" +#define COMPILE_DATE_STRING "[2003-01-05 20:26]" diff --git a/src/editor.c b/src/editor.c index c6b2632a..60be1aab 100644 --- a/src/editor.c +++ b/src/editor.c @@ -2650,46 +2650,49 @@ static void PickDrawingElement(int button, int element) static void DrawDrawingWindow() { + SetBackgroundBitmap(NULL); ClearWindow(); - -#if 1 - ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); - redraw_mask |= REDRAW_FROM_BACKBUFFER; -#endif - UnmapLevelEditorWindowGadgets(); + AdjustDrawingAreaGadgets(); AdjustLevelScrollPosition(); AdjustEditorScrollbar(GADGET_ID_SCROLL_HORIZONTAL); AdjustEditorScrollbar(GADGET_ID_SCROLL_VERTICAL); + DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); MapMainDrawingArea(); } +static void DrawElementBorder(int dest_x, int dest_y, int width, int height) +{ + int border_graphic = IMG_SAND; + Bitmap *src_bitmap; + int src_x, src_y; + int num_mini_tilex = width / MINI_TILEX + 1; + int num_mini_tiley = width / MINI_TILEY + 1; + int x, y; + + getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y); + + for (y=0; y < num_mini_tiley; y++) + for (x=0; x < num_mini_tilex; x++) + BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, + dest_x - MINI_TILEX / 2 + x * MINI_TILEX, + dest_y - MINI_TILEY / 2 + y * MINI_TILEY); + + ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); +} + static void DrawRandomPlacementBackgroundArea() { int area_x = ED_AREA_RANDOM_BACKGROUND_XPOS / MINI_TILEX; int area_y = ED_AREA_RANDOM_BACKGROUND_YPOS / MINI_TILEY; int area_sx = SX + ED_AREA_RANDOM_BACKGROUND_XPOS; int area_sy = SY + ED_AREA_RANDOM_BACKGROUND_YPOS; - int x, y; ElementContent[0][0][0] = random_placement_background_element; - /* draw decorative border for the object */ - for (y=0; y<2; y++) - for (x=0; x<2; x++) - DrawMiniElement(area_x + x, area_y + y, EL_SAND); - - ClearRectangle(drawto, - area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1, - MINI_TILEX + 2, MINI_TILEY + 2); - - /* copy border to the right location */ - BlitBitmap(drawto, drawto, - area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY, - area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2); - + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); MapDrawingArea(GADGET_ID_RANDOM_BACKGROUND); @@ -2707,6 +2710,7 @@ static void DrawLevelInfoWindow() int font_color = FC_GREEN; int i, x, y; + SetBackgroundBitmap(new_graphic_info[IMG_MENU_BACKGROUND].bitmap); ClearWindow(); UnmapLevelEditorWindowGadgets(); @@ -2794,29 +2798,15 @@ static void DrawAmoebaContentArea() int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS; int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS; int font_color = FC_GREEN; - int x, y; ElementContent[0][0][0] = level.amoeba_content; - /* draw decorative border for the object */ - for (y=0; y<2; y++) - for (x=0; x<2; x++) - DrawMiniElement(area_x + x, area_y + y, EL_SAND); - - ClearRectangle(drawto, - area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1, - MINI_TILEX + 2, MINI_TILEY + 2); - - /* copy border to the right location */ - BlitBitmap(drawto, drawto, - area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY, - area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2); + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); + DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba", FS_SMALL, font_color); - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); - MapDrawingArea(GADGET_ID_AMOEBA_CONTENT); } @@ -2849,28 +2839,12 @@ static void DrawElementContentAreas() MapCounterButtons(counter_id); /* delete content areas in case of reducing number of them */ - ClearRectangle(backbuffer, - SX, area_sy - MINI_TILEX, - SXSIZE, 12 * MINI_TILEY); + DrawBackground(SX, area_sy - MINI_TILEX, SXSIZE, 12 * MINI_TILEY); - /* draw some decorative border for the objects */ for (i=0; iclip_mask, + clip_gc_valuemask, &clip_gc_values); + } + + new_graphic_info[i].clip_mask = + XCreatePixmap(display, window->drawable, TILEX, TILEY, 1); + + src_pixmap = src_bitmap->clip_mask; + XCopyArea(display, src_pixmap, new_graphic_info[i].clip_mask, + copy_clipmask_gc, src_x, src_y, TILEX, TILEY, 0, 0); + + clip_gc_values.graphics_exposures = False; + clip_gc_values.clip_mask = new_graphic_info[i].clip_mask; + clip_gc_valuemask = GCGraphicsExposures | GCClipMask; + new_graphic_info[i].clip_gc = + XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values); +#endif } + +#if defined(TARGET_X11_NATIVE) + if (copy_clipmask_gc) + XFreeGC(display, copy_clipmask_gc); +#endif + + clipmasks_initialized = TRUE; } static void InitSoundInfo() diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index b5afaa88..9dfea838 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -117,8 +117,9 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) case GD_TYPE_NORMAL_BUTTON: case GD_TYPE_CHECK_BUTTON: case GD_TYPE_RADIO_BUTTON: - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); + BlitBitmapOnBackground(gd->bitmap, drawto, + gd->x, gd->y, gi->width, gi->height, + gi->x, gi->y); if (gi->deco.design.bitmap) BlitBitmap(gi->deco.design.bitmap, drawto, gi->deco.design.x, gi->deco.design.y, @@ -156,7 +157,9 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) border, gi->height, gi->x + gi->width - border, gi->y); /* gadget text value */ - DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type); + DrawTextExt(drawto, + gi->x + border, gi->y + border, text, + FS_SMALL, font_type, FONT_OPAQUE); cursor_letter = gi->text.value[gi->text.cursor_position]; cursor_string[0] = '~'; @@ -165,8 +168,10 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) /* draw cursor, if active */ if (pressed) - DrawText(gi->x + border + gi->text.cursor_position * font_width, - gi->y + border, cursor_string, FS_SMALL, font_type); + DrawTextExt(drawto, + gi->x + border + gi->text.cursor_position * font_width, + gi->y + border, cursor_string, + FS_SMALL, font_type, FONT_OPAQUE); } break; @@ -183,33 +188,36 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) int step_size_remain = size_body - num_steps * design_body; /* clear scrollbar area */ - ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height); + ClearRectangleOnBackground(backbuffer, gi->x, gi->y, + gi->width, gi->height); /* upper part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, - gi->width, gi->border.size, - xpos, ypos); + BlitBitmapOnBackground(gd->bitmap, drawto, + gd->x, gd->y, + gi->width, gi->border.size, + xpos, ypos); /* middle part of gadget */ for (i=0; ibitmap, drawto, - gd->x, gd->y + gi->border.size, - gi->width, design_body, - xpos, ypos + gi->border.size + i * design_body); + BlitBitmapOnBackground(gd->bitmap, drawto, + gd->x, gd->y + gi->border.size, + gi->width, design_body, + xpos, ypos + gi->border.size + + i * design_body); /* remaining middle part of gadget */ if (step_size_remain > 0) - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y + gi->border.size, - gi->width, step_size_remain, - xpos, ypos + gi->border.size + num_steps * design_body); + BlitBitmapOnBackground(gd->bitmap, drawto, + gd->x, gd->y + gi->border.size, + gi->width, step_size_remain, + xpos, ypos + gi->border.size + + num_steps * design_body); /* lower part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y + design_full - gi->border.size, - gi->width, gi->border.size, - xpos, ypos + size_full - gi->border.size); + BlitBitmapOnBackground(gd->bitmap, drawto, + gd->x, gd->y + design_full - gi->border.size, + gi->width, gi->border.size, + xpos, ypos + size_full - gi->border.size); } break; diff --git a/src/libgame/system.c b/src/libgame/system.c index 7cebdb8f..c071fee8 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -36,6 +36,7 @@ struct OptionInfo options; struct VideoSystemInfo video; struct AudioSystemInfo audio; struct GfxInfo gfx; +struct FontInfo font; struct ArtworkInfo artwork; struct JoystickInfo joystick; struct SetupInfo setup; @@ -185,6 +186,11 @@ void SetDrawDeactivationMask(int draw_deactivation_mask) gfx.draw_deactivation_mask = draw_deactivation_mask; } +void SetBackgroundBitmap(Bitmap *background_bitmap) +{ + gfx.background_bitmap = background_bitmap; +} + /* ========================================================================= */ /* video functions */ @@ -377,6 +383,11 @@ inline boolean DrawingDeactivated(int x, int y, int width, int height) return FALSE; } +inline boolean DrawingOnBackground(int x, int y) +{ + return (gfx.background_bitmap != NULL && x < gfx.sx + gfx.sxsize); +} + inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, int src_x, int src_y, int width, int height, @@ -406,6 +417,16 @@ inline void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height) #endif } +inline void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y, + int width, int height) +{ + if (!DrawingOnBackground(x, y)) + ClearRectangle(bitmap, x, y, width, height); + else + BlitBitmap(gfx.background_bitmap, bitmap, + x - gfx.real_sx, y - gfx.real_sy, width, height, x, y); +} + #if 0 #ifndef TARGET_SDL static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */ @@ -457,6 +478,29 @@ inline void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap, #endif } +inline void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap, + int src_x, int src_y, + int width, int height, + int dst_x, int dst_y) +{ + if (!DrawingOnBackground(src_x, src_y)) + BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height, + dst_x, dst_y); + else + { + /* draw background */ + BlitBitmap(gfx.background_bitmap, dst_bitmap, + dst_x - gfx.real_sx, dst_y - gfx.real_sy, width, height, + dst_x, dst_y); + + /* draw foreground */ + SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, + dst_x - src_x, dst_y - src_y); + BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height, + dst_x, dst_y); + } +} + inline void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y, int to_x, int to_y) { diff --git a/src/libgame/system.h b/src/libgame/system.h index d393bfc0..3577e359 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -297,6 +297,17 @@ struct GfxInfo int vxsize, vysize; boolean draw_deactivation_mask; + + Bitmap *background_bitmap; +}; + +struct FontInfo +{ + Bitmap *bitmap_initial; + Bitmap *bitmap_big; + Bitmap *bitmap_medium; + Bitmap *bitmap_small; + Bitmap *bitmap_tile; }; struct JoystickInfo @@ -513,6 +524,7 @@ extern struct OptionInfo options; extern struct VideoSystemInfo video; extern struct AudioSystemInfo audio; extern struct GfxInfo gfx; +extern struct FontInfo font; extern struct ArtworkInfo artwork; extern struct JoystickInfo joystick; extern struct SetupInfo setup; @@ -554,6 +566,7 @@ void InitGfxDoor1Info(int, int, int, int); void InitGfxDoor2Info(int, int, int, int); void InitGfxScrollbufferInfo(int, int); void SetDrawDeactivationMask(int ); +void SetBackgroundBitmap(Bitmap *); inline void InitVideoDisplay(void); inline void CloseVideoDisplay(void); @@ -563,9 +576,13 @@ inline Bitmap *CreateBitmap(int, int, int); inline void FreeBitmap(Bitmap *); inline void BlitBitmap(Bitmap *, Bitmap *, int, int, int, int, int, int); inline void ClearRectangle(Bitmap *, int, int, int, int); +inline void ClearRectangleOnBackground(Bitmap *, int, int, int, int); inline void SetClipMask(Bitmap *, GC, Pixmap); inline void SetClipOrigin(Bitmap *, GC, int, int); inline void BlitBitmapMasked(Bitmap *, Bitmap *, int, int, int, int, int, int); +inline boolean DrawingOnBackground(int, int); +inline void BlitBitmapOnBackground(Bitmap *, Bitmap *, int, int, int, int, int, + int); inline void DrawSimpleWhiteLine(Bitmap *, int, int, int, int); inline void DrawLines(Bitmap *, struct XY *, int, Pixel); inline Pixel GetPixel(Bitmap *, int, int); diff --git a/src/libgame/text.c b/src/libgame/text.c index 2a70134b..1a5dcefe 100644 --- a/src/libgame/text.c +++ b/src/libgame/text.c @@ -18,15 +18,96 @@ /* ========================================================================= */ -/* exported variables */ +/* font functions */ /* ========================================================================= */ -struct FontInfo font; +#define NUM_FONTS 2 +#define NUM_FONT_COLORS 4 +#define NUM_FONT_CHARS (FONT_LINES_PER_FONT * FONT_CHARS_PER_LINE) +static GC tile_clip_gc = None; +static Pixmap tile_clipmask[NUM_FONTS][NUM_FONT_COLORS][NUM_FONT_CHARS]; -/* ========================================================================= */ -/* font functions */ -/* ========================================================================= */ +static struct +{ + Bitmap **bitmap; + int xsize, ysize; +} font_info[NUM_FONTS] = +{ + { &font.bitmap_big, FONT1_XSIZE, FONT1_YSIZE }, + { &font.bitmap_medium, FONT6_XSIZE, FONT6_YSIZE } +}; + +static void InitFontClipmasks() +{ +#if defined(TARGET_X11_NATIVE) + static boolean clipmasks_initialized = FALSE; + boolean fonts_initialized = TRUE; + XGCValues clip_gc_values; + unsigned long clip_gc_valuemask; + GC copy_clipmask_gc; + int i, j, k; + + for (i=0; idrawable, + clip_gc_valuemask, &clip_gc_values); + + /* create graphic context structures needed for clipping */ + clip_gc_values.graphics_exposures = False; + clip_gc_valuemask = GCGraphicsExposures; + copy_clipmask_gc = XCreateGC(display, (*font_info[0].bitmap)->clip_mask, + clip_gc_valuemask, &clip_gc_values); + + /* create only those clipping Pixmaps we really need */ + for (i=0; iclip_mask; + int xpos = k % FONT_CHARS_PER_LINE; + int ypos = k / FONT_CHARS_PER_LINE; + int xsize = font_info[i].xsize; + int ysize = font_info[i].ysize; + int src_x = xsize * xpos; + int src_y = ysize * (ypos + j * FONT_LINES_PER_FONT); + + tile_clipmask[i][j][k] = + XCreatePixmap(display, window->drawable, xsize, ysize, 1); + + XCopyArea(display, src_pixmap, tile_clipmask[i][j][k], copy_clipmask_gc, + src_x, src_y, xsize, ysize, 0, 0); + } + + XFreeGC(display, copy_clipmask_gc); + + clipmasks_initialized = TRUE; + +#endif /* TARGET_X11_NATIVE */ +} void InitFontInfo(Bitmap *bitmap_initial, Bitmap *bitmap_big, Bitmap *bitmap_medium, @@ -37,6 +118,8 @@ void InitFontInfo(Bitmap *bitmap_initial, font.bitmap_medium = bitmap_medium; font.bitmap_small = bitmap_small; font.bitmap_tile = bitmap_tile; + + InitFontClipmasks(); } int getFontWidth(int font_size, int font_type) @@ -67,7 +150,7 @@ void DrawInitText(char *text, int ypos, int color) { ClearRectangle(window, 0, ypos, video.width, FONT2_YSIZE); DrawTextExt(window, (video.width - strlen(text) * FONT2_XSIZE)/2, - ypos, text, FS_INITIAL, color); + ypos, text, FS_INITIAL, color, FONT_OPAQUE); FlushDisplay(); } } @@ -100,7 +183,12 @@ void DrawTextF(int x, int y, int font_type, char *format, ...) void DrawText(int x, int y, char *text, int font_size, int font_type) { - DrawTextExt(drawto, x, y, text, font_size, font_type); + int mask_mode = FONT_OPAQUE; + + if (DrawingOnBackground(x, y)) + mask_mode = FONT_MASKED; + + DrawTextExt(drawto, x, y, text, font_size, font_type, mask_mode); if (x < gfx.dx) redraw_mask |= REDRAW_FIELD; @@ -109,7 +197,7 @@ void DrawText(int x, int y, char *text, int font_size, int font_type) } void DrawTextExt(DrawBuffer *bitmap, int x, int y, char *text, - int font_size, int font_type) + int font_size, int font_type, int mask_mode) { Bitmap *font_bitmap; int font_width, font_height, font_starty; @@ -187,29 +275,49 @@ void DrawTextExt(DrawBuffer *bitmap, int x, int y, char *text, } } - if (print_inverse) + if (print_inverse) /* special mode for text gadgets */ { - BlitBitmap(font_bitmap, bitmap, - FONT_CHARS_PER_LINE * font_width, + /* first step: draw solid colored rectangle (use "cursor" character) */ + BlitBitmap(font_bitmap, bitmap, FONT_CHARS_PER_LINE * font_width, 3 * font_height + font_starty, font_width, font_height, x, y); + /* second step: draw masked black rectangle (use "space" character) */ SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc, dest_x - src_x, dest_y - src_y); BlitBitmapMasked(font_bitmap, bitmap, 0, 0, font_width, font_height, dest_x, dest_y); } - else + else if (mask_mode == FONT_MASKED) { -#if 1 - BlitBitmap(font_bitmap, bitmap, src_x, src_y, + /* clear font character background */ + BlitBitmap(gfx.background_bitmap, bitmap, + dest_x - gfx.real_sx, dest_y - gfx.real_sy, font_width, font_height, dest_x, dest_y); -#else - SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc, - dest_x - src_x, dest_y - src_y); + + /* use special font tile clipmasks, if available */ + if (font_size == FS_BIG || font_size == FS_MEDIUM) + { + int font_nr = (font_size == FS_BIG ? 0 : 1); + int font_char = (c >= 32 && c <= 95 ? c - 32 : 0); + + SetClipMask(font_bitmap, tile_clip_gc, + tile_clipmask[font_nr][font_type][font_char]); + SetClipOrigin(font_bitmap, tile_clip_gc, dest_x, dest_y); + } + else + { + SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc, + dest_x - src_x, dest_y - src_y); + } + BlitBitmapMasked(font_bitmap, bitmap, src_x, src_y, font_width, font_height, dest_x, dest_y); -#endif + } + else /* normal, non-masked font blitting */ + { + BlitBitmap(font_bitmap, bitmap, src_x, src_y, + font_width, font_height, dest_x, dest_y); } } diff --git a/src/libgame/text.h b/src/libgame/text.h index 44cdbf15..fdaf0e8b 100644 --- a/src/libgame/text.h +++ b/src/libgame/text.h @@ -50,20 +50,14 @@ #define FONT_CHARS_PER_LINE 16 #define FONT_LINES_PER_FONT 4 +#define FONT_OPAQUE 0 +#define FONT_MASKED 1 + /* text output definitions */ #define MAX_OUTPUT_LINESIZE 256 /* font structure definitions */ -struct FontInfo -{ - Bitmap *bitmap_initial; - Bitmap *bitmap_big; - Bitmap *bitmap_medium; - Bitmap *bitmap_small; - Bitmap *bitmap_tile; -}; - void InitFontInfo(Bitmap *, Bitmap *, Bitmap *, Bitmap *, Bitmap *); int getFontWidth(int, int); @@ -72,6 +66,6 @@ void DrawInitText(char *, int, int); void DrawTextF(int, int, int, char *, ...); void DrawTextFCentered(int, int, char *, ...); void DrawText(int, int, char *, int, int); -void DrawTextExt(DrawBuffer *, int, int, char *, int, int); +void DrawTextExt(DrawBuffer *, int, int, char *, int, int, int); #endif /* TEXT_H */ diff --git a/src/main.h b/src/main.h index 7e55e992..37fcb08b 100644 --- a/src/main.h +++ b/src/main.h @@ -1654,6 +1654,11 @@ struct NewGraphicInfo int anim_delay; /* important: delay of 1 means "no delay"! */ int anim_mode; boolean anim_global_sync; + +#if defined(TARGET_X11_NATIVE) + Pixmap clip_mask; /* single-graphic-only clip mask for X11 */ + GC clip_gc; /* single-graphic-only clip gc for X11 */ +#endif }; extern GC tile_clip_gc; diff --git a/src/screens.c b/src/screens.c index 3e58f59c..e9969781 100644 --- a/src/screens.c +++ b/src/screens.c @@ -71,31 +71,42 @@ static void HandleChooseTree(int, int, int, int, int, TreeInfo **); static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS]; static int setup_mode = SETUP_MODE_MAIN; -static void drawCursorExt(int pos, int color, int graphic) +static void drawCursorExt(int xpos, int ypos, int color, int graphic) { static int cursor_array[SCR_FIELDY]; - if (graphic) - cursor_array[pos] = graphic; - - graphic = cursor_array[pos]; + if (xpos == 0) + { + if (graphic != 0) + cursor_array[ypos] = graphic; + else + graphic = cursor_array[ypos]; + } if (color == FC_RED) graphic = (graphic == IMG_ARROW_BLUE_LEFT ? IMG_ARROW_RED_LEFT : graphic == IMG_ARROW_BLUE_RIGHT ? IMG_ARROW_RED_RIGHT : IMG_BALL_RED); - DrawGraphic(0, MENU_SCREEN_START_YPOS + pos, graphic, 0); + ypos += MENU_SCREEN_START_YPOS; + + DrawBackground(SX + xpos * 32, SY + ypos * 32, TILEX, TILEY); + DrawGraphicThruMask(xpos, ypos, graphic, 0); +} + +static void initCursor(int ypos, int graphic) +{ + drawCursorExt(0, ypos, FC_BLUE, graphic); } -static void initCursor(int pos, int graphic) +static void drawCursor(int ypos, int color) { - drawCursorExt(pos, FC_BLUE, graphic); + drawCursorExt(0, ypos, color, 0); } -static void drawCursor(int pos, int color) +static void drawCursorXY(int xpos, int ypos, int graphic) { - drawCursorExt(pos, color, 0); + drawCursorExt(xpos, ypos, -1, graphic); } void DrawHeadline() @@ -141,6 +152,7 @@ void DrawMainMenu() KeyboardAutoRepeatOn(); ActivateJoystick(); SetDrawDeactivationMask(REDRAW_NONE); + SetBackgroundBitmap(new_graphic_info[IMG_MENU_BACKGROUND].bitmap); audio.sound_deactivated = FALSE; /* needed if last screen was the playing screen, invoked from level editor */ @@ -181,7 +193,9 @@ void DrawMainMenu() GetPlayerConfig(); LoadLevel(level_nr); + SetBackgroundBitmap(new_graphic_info[IMG_MENU_BACKGROUND].bitmap); ClearWindow(); + DrawHeadline(); DrawText(SX + 32, SY + 2*32, name_text, FS_BIG, FC_GREEN); DrawText(SX + 6*32, SY + 2*32, setup.player_name, FS_BIG, FC_RED); @@ -210,8 +224,13 @@ void DrawMainMenu() for(i=0; i<8; i++) initCursor(i, (i == 1 || i == 6 ? IMG_ARROW_BLUE_RIGHT : IMG_BALL_BLUE)); +#if 0 DrawGraphic(10, 3, IMG_ARROW_BLUE_LEFT, 0); DrawGraphic(14, 3, IMG_ARROW_BLUE_RIGHT, 0); +#else + drawCursorXY(10, 1, IMG_ARROW_BLUE_LEFT); + drawCursorXY(14, 1, IMG_ARROW_BLUE_RIGHT); +#endif DrawText(SX + 56, SY + 326, "A Game by Artsoft Entertainment", FS_SMALL, FC_RED); @@ -319,10 +338,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) level_nr = new_level_nr; - DrawTextExt(drawto, SX + 11 * 32, SY + 3 * 32, - int2str(level_nr, 3), FS_BIG, font_color); - DrawTextExt(window, SX + 11 * 32, SY + 3 * 32, - int2str(level_nr, 3), FS_BIG, font_color); + DrawText(SX + 11 * 32, SY + 3 * 32, int2str(level_nr, 3), + FS_BIG, font_color); LoadLevel(level_nr); DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE); @@ -1184,8 +1201,10 @@ void HandleTypeName(int newxpos, Key key) if (newxpos) { xpos = newxpos; - DrawText(SX + 6*32, SY + ypos*32, setup.player_name, FS_BIG, FC_YELLOW); - DrawGraphic(xpos + 6, ypos, IMG_BALL_RED, 0); + DrawText(SX + 6 * 32, SY + ypos * 32, setup.player_name, + FS_BIG, FC_YELLOW); + drawCursorXY(xpos + 6, ypos - 2, IMG_BALL_RED); + return; } @@ -1203,23 +1222,23 @@ void HandleTypeName(int newxpos, Key key) setup.player_name[xpos] = ascii; setup.player_name[xpos + 1] = 0; xpos++; - DrawTextExt(drawto, SX + 6*32, SY + ypos*32, - setup.player_name, FS_BIG, FC_YELLOW); - DrawTextExt(window, SX + 6*32, SY + ypos*32, - setup.player_name, FS_BIG, FC_YELLOW); - DrawGraphic(xpos + 6, ypos, IMG_BALL_RED, 0); + + DrawText(SX + 6 * 32, SY + ypos * 32, setup.player_name, + FS_BIG, FC_YELLOW); + drawCursorXY(xpos + 6, ypos - 2, IMG_BALL_RED); } else if ((key == KSYM_Delete || key == KSYM_BackSpace) && xpos > 0) { xpos--; setup.player_name[xpos] = 0; - DrawGraphic(xpos + 6, ypos, IMG_BALL_RED, 0); - DrawGraphic(xpos + 7, ypos, IMG_EMPTY, 0); + + DrawBackground(SX + (xpos + 6) * 32, SY + ypos * 32, 2 * TILEX, TILEY); + drawCursorXY(xpos + 6, ypos - 2, IMG_BALL_RED); } else if (key == KSYM_Return && xpos > 0) { - DrawText(SX + 6*32, SY + ypos*32, setup.player_name, FS_BIG, FC_RED); - DrawGraphic(xpos + 6, ypos, IMG_EMPTY, 0); + DrawText(SX + 6 * 32, SY + ypos * 32, setup.player_name, FS_BIG, FC_RED); + DrawBackground(SX + (xpos + 6) * 32, SY + ypos * 32, TILEX, TILEY); SaveSetup(); game_status = MAINMENU; @@ -1267,7 +1286,7 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, char *title_string = NULL; int offset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : 16); - ClearRectangle(backbuffer, SX, SY, SXSIZE - 32, SYSIZE); + DrawBackground(SX, SY, SXSIZE - 32, SYSIZE); redraw_mask |= REDRAW_FIELD; title_string = @@ -1302,10 +1321,20 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, } if (first_entry > 0) - DrawGraphic(0, 1, IMG_ARROW_BLUE_UP, 0); + { + int ypos = 1; + + DrawBackground(SX, SY + ypos * 32, TILEX, TILEY); + DrawGraphicThruMask(0, ypos, IMG_ARROW_BLUE_UP, 0); + } if (first_entry + num_page_entries < num_entries) - DrawGraphic(0, MAX_MENU_ENTRIES_ON_SCREEN + 1, IMG_ARROW_BLUE_DOWN, 0); + { + int ypos = MAX_MENU_ENTRIES_ON_SCREEN + 1; + + DrawBackground(SX, SY + ypos * 32, TILEX, TILEY); + DrawGraphicThruMask(0, ypos, IMG_ARROW_BLUE_DOWN, 0); + } } static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) @@ -1319,7 +1348,7 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) node_first = getTreeInfoFirstGroupEntry(ti); node = getTreeInfoFromPos(node_first, entry_pos); - ClearRectangle(drawto, SX + 32, SY + 32, SXSIZE - 64, 32); + DrawBackground(SX + 32, SY + 32, SXSIZE - 64, 32); if (node->parent_link) DrawTextFCentered(40, FC_RED, "leave group \"%s\"", node->class_desc); @@ -2153,8 +2182,8 @@ void DrawSetupScreen_Input() initCursor(2, IMG_ARROW_BLUE_RIGHT); initCursor(13, IMG_ARROW_BLUE_LEFT); - DrawGraphic(10, MENU_SCREEN_START_YPOS, IMG_ARROW_BLUE_LEFT, 0); - DrawGraphic(12, MENU_SCREEN_START_YPOS, IMG_ARROW_BLUE_RIGHT, 0); + drawCursorXY(10, 0, IMG_ARROW_BLUE_LEFT); + drawCursorXY(12, 0, IMG_ARROW_BLUE_RIGHT); DrawText(SX+32, SY+2*32, "Player:", FS_BIG, FC_GREEN); DrawText(SX+32, SY+3*32, "Device:", FS_BIG, FC_GREEN); @@ -2220,7 +2249,7 @@ static void drawPlayerSetupInputInfo(int player_nr) custom_key = setup.input[player_nr].key; DrawText(SX+11*32, SY+2*32, int2str(player_nr + 1, 1), FS_BIG, FC_RED); - DrawGraphic(8, 2, PLAYER_NR_GFX(IMG_PLAYER1, player_nr), 0); + DrawGraphicThruMask(8, 2, PLAYER_NR_GFX(IMG_PLAYER1, player_nr), 0); if (setup.input[player_nr].use_joystick) { @@ -2238,10 +2267,10 @@ static void drawPlayerSetupInputInfo(int player_nr) } DrawText(SX+32, SY+5*32, "Actual Settings:", FS_BIG, FC_GREEN); - DrawGraphic(1, 6, IMG_ARROW_BLUE_LEFT, 0); - DrawGraphic(1, 7, IMG_ARROW_BLUE_RIGHT, 0); - DrawGraphic(1, 8, IMG_ARROW_BLUE_UP, 0); - DrawGraphic(1, 9, IMG_ARROW_BLUE_DOWN, 0); + drawCursorXY(1, 4, IMG_ARROW_BLUE_LEFT); + drawCursorXY(1, 5, IMG_ARROW_BLUE_RIGHT); + drawCursorXY(1, 6, IMG_ARROW_BLUE_UP); + drawCursorXY(1, 7, IMG_ARROW_BLUE_DOWN); DrawText(SX+2*32, SY+6*32, ":", FS_BIG, FC_BLUE); DrawText(SX+2*32, SY+7*32, ":", FS_BIG, FC_BLUE); DrawText(SX+2*32, SY+8*32, ":", FS_BIG, FC_BLUE); diff --git a/src/tools.c b/src/tools.c index 53336c7f..ecc1e127 100644 --- a/src/tools.c +++ b/src/tools.c @@ -279,7 +279,7 @@ void BackToFront() info1[0] = '\0'; sprintf(text, "%.1f fps%s", global.frames_per_second, info1); - DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW); + DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW, FONT_OPAQUE); } FlushDisplay(); @@ -362,9 +362,39 @@ void FadeToFront() BackToFront(); } +void DrawBackground(int x, int y, int width, int height) +{ + /* some sanity checks */ + if (x < REAL_SX) + { + width -= (REAL_SX - x); + x = REAL_SX; + } + + if (y < REAL_SY) + { + height -= (REAL_SY - y); + y = REAL_SY; + } + + if (width > FULL_SXSIZE) + width = FULL_SXSIZE; + + if (height > FULL_SYSIZE) + height = FULL_SYSIZE; + + if (DrawingOnBackground(x, y) && game_status != PLAYING) + BlitBitmap(gfx.background_bitmap, backbuffer, x - REAL_SX, y - REAL_SY, + width, height, x, y); + else + ClearRectangle(backbuffer, x, y, width, height); + + redraw_mask |= REDRAW_FIELD; +} + void ClearWindow() { - ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); if (setup.soft_scrolling && game_status == PLAYING) { @@ -379,15 +409,6 @@ void ClearWindow() ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); SetDrawtoField(DRAW_DIRECT); } - -#if 1 - if (game_status != PLAYING && - new_graphic_info[IMG_MENU_BACK].bitmap != NULL) - BlitBitmap(new_graphic_info[IMG_MENU_BACK].bitmap, backbuffer, - 0, 0, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY); -#endif - - redraw_mask |= REDRAW_FIELD; } static int getGraphicAnimationPhase(int frames, int delay, int mode) @@ -1740,12 +1761,7 @@ void DrawMicroElement(int xpos, int ypos, int element) { Bitmap *src_bitmap; int src_x, src_y; - int graphic; - - if (element == EL_EMPTY) - return; - - graphic = el2img(element); + int graphic = el2img(element); getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y); BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY, @@ -1780,7 +1796,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y) { int x, y; - ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE); + DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE); if (lev_fieldx < STD_LEV_FIELDX) xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX; @@ -1799,7 +1815,8 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y) if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy) DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY, Ur[lx][ly]); - else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1) + else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1 + && BorderElement != EL_EMPTY) DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY, BorderElement); } @@ -1821,7 +1838,7 @@ static void DrawMicroLevelLabelExt(int mode) { char label_text[MAX_MICROLABEL_SIZE + 1]; - ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); + DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name : mode == MICROLABEL_CREATED_BY ? "created by" : @@ -2003,7 +2020,7 @@ boolean Request(char *text, unsigned int req_state) text_line[tl] = 0; DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16, - text_line, FS_SMALL, FC_YELLOW); + text_line, FS_SMALL, FC_YELLOW, FONT_OPAQUE); text += tl + (tc == ' ' ? 1 : 0); } diff --git a/src/tools.h b/src/tools.h index 02f2dc24..b6931dae 100644 --- a/src/tools.h +++ b/src/tools.h @@ -63,6 +63,7 @@ void RedrawPlayfield(boolean, int, int, int, int); void BackToFront(); void FadeToFront(); void ClearWindow(); +void DrawBackground(int, int, int, int); void MarkTileDirty(int, int); void SetBorderElement(); -- 2.34.1