X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=a7fa785659c5dd705e2496d73ee4c8b87098accc;hb=f941ccddee3065d7531298e37ad4dcfcd892c1f8;hp=1c27d8cae76cd2c3a4f5a45ed10c6bb14ef02a85;hpb=2a4878a4c2873df0426a22c357533656928748c8;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 1c27d8ca..a7fa7856 100644 --- a/src/tools.c +++ b/src/tools.c @@ -184,15 +184,15 @@ void BackToFront() redraw_mask &= ~REDRAW_DOORS; } - if (redraw_mask & REDRAW_MICROLEV) + if (redraw_mask & REDRAW_MICROLEVEL) { XCopyArea(display,backbuffer,window,gc, - MICROLEV_XPOS,MICROLEV_YPOS, MICROLEV_XSIZE,MICROLEV_YSIZE, - MICROLEV_XPOS,MICROLEV_YPOS); + MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE, + MICROLEV_XPOS, MICROLEV_YPOS); XCopyArea(display,backbuffer,window,gc, - SX,MICROLABEL_YPOS, SXSIZE,FONT4_YSIZE, - SX,MICROLABEL_YPOS); - redraw_mask &= ~REDRAW_MICROLEV; + SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE, + SX, MICROLABEL_YPOS); + redraw_mask &= ~REDRAW_MICROLEVEL; } if (redraw_mask & REDRAW_TILES) @@ -349,6 +349,7 @@ void DrawTextExt(Drawable d, GC gc, int x, int y, { int font_width, font_height, font_start; int font_pixmap; + boolean print_inverse = FALSE; if (font_size != FS_SMALL && font_size != FS_BIG) font_size = FS_SMALL; @@ -364,10 +365,16 @@ void DrawTextExt(Drawable d, GC gc, int x, int y, font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE : FONT2_YSIZE) * FONT_LINES_PER_FONT); - while(*text) + while (*text) { char c = *text++; + if (c == '~' && font_size == FS_SMALL && font_type <= FC_YELLOW) + { + print_inverse = TRUE; + continue; + } + if (c >= 'a' && c <= 'z') c = 'A' + (c - 'a'); else if (c == 'ä' || c == 'Ä') @@ -378,10 +385,27 @@ void DrawTextExt(Drawable d, GC gc, int x, int y, c = 93; if (c >= 32 && c <= 95) - XCopyArea(display, pix[font_pixmap], d, gc, - ((c - 32) % FONT_CHARS_PER_LINE) * font_width, - ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start, - font_width, font_height, x, y); + { + int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width; + int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start; + int dest_x = x, dest_y = y; + + if (print_inverse) + { + XCopyArea(display, pix[font_pixmap], d, gc, + FONT_CHARS_PER_LINE * font_width, + 3 * font_height + font_start, + font_width, font_height, x, y); + + XSetClipOrigin(display, clip_gc[font_pixmap], + dest_x - src_x, dest_y - src_y); + XCopyArea(display, pix[font_pixmap], drawto, clip_gc[font_pixmap], + 0, 0, font_width, font_height, dest_x, dest_y); + } + else + XCopyArea(display, pix[font_pixmap], d, gc, + src_x, src_y, font_width, font_height, dest_x, dest_y); + } x += font_width; } @@ -751,6 +775,38 @@ void DrawMiniGraphic(int x, int y, int graphic) MarkTileDirty(x/2, y/2); } +void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y) +{ + if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) + { + graphic -= GFX_START_ROCKSSCREEN; + *pixmap = pix[PIX_BACK]; + *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX; + *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY; + } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + graphic -= GFX_START_ROCKSMORE; + *pixmap = pix[PIX_MORE]; + *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX; + *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY; + } + else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT) + { + graphic -= GFX_START_ROCKSFONT; + *pixmap = pix[PIX_SMALLFONT]; + *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE; + *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE + + FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT); + } + else + { + *pixmap = pix[PIX_MORE]; + *x = MINI_MORE_STARTX; + *y = MINI_MORE_STARTY; + } +} + void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic) { if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) @@ -1205,7 +1261,12 @@ void DrawScreenField(int x, int y) if (!IN_LEV_FIELD(ux, uy)) { - DrawScreenElement(x, y, EL_BETON); + if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy) + element = EL_LEERRAUM; + else + element = BorderElement; + + DrawScreenElement(x, y, element); return; } @@ -1314,10 +1375,20 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y) if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy) DrawMiniElement(sx, sy, EL_LEERRAUM); - else if (x == -1 || x == lev_fieldx || y == -1 || y == lev_fieldy) - DrawMiniElement(sx, sy, EL_BETON); - else + else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy) DrawMiniElement(sx, sy, Feld[x][y]); + else if (x == -1 && y == -1) + DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_LEFT); + else if (x == lev_fieldx && y == -1) + DrawMiniGraphic(sx, sy, GFX_STEEL_UPPER_RIGHT); + else if (x == -1 && y == lev_fieldy) + DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_LEFT); + else if (x == lev_fieldx && y == lev_fieldy) + DrawMiniGraphic(sx, sy, GFX_STEEL_LOWER_RIGHT); + else if (x == -1 || x == lev_fieldx) + DrawMiniGraphic(sx, sy, GFX_STEEL_VERTICAL); + else if (y == -1 || y == lev_fieldy) + DrawMiniGraphic(sx, sy, GFX_STEEL_HORIZONTAL); } void DrawMicroElement(int xpos, int ypos, int element) @@ -1365,49 +1436,153 @@ void DrawMiniLevel(int scroll_x, int scroll_y) { int x,y; - ClearWindow(); - - for(x=0; x<2*SCR_FIELDX; x++) - for(y=0; y<2*SCR_FIELDY; y++) + for(x=0; x= 0 && x < lev_fieldx && y >= 0 && y < lev_fieldy) + { + int lx = from_x + x, ly = from_y + y; + + if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy) DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY, - Ur[x][y]); - else if (x >= -1 && x < lev_fieldx+1 && y >= -1 && y < lev_fieldy+1) + Ur[lx][ly]); + else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1) DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY, - EL_BETON); + BorderElement); + } + } + + redraw_mask |= REDRAW_MICROLEVEL; +} + +static void DrawMicroLevelLabelExt(int mode) +{ + char label_text[100]; + + XFillRectangle(display, drawto,gc, + SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); + + strcpy(label_text, (mode == 1 ? level.name : + mode == 2 ? "created by" : + mode == 3 ? level.author : "")); + + if (strlen(label_text) > 0) + { + int size, lxpos, lypos; + + label_text[SXSIZE / FONT4_XSIZE] = '\0'; + + size = strlen(label_text); + lxpos = SX + (SXSIZE - size * FONT4_XSIZE) / 2; + lypos = MICROLABEL_YPOS; + + DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2); + } + + redraw_mask |= REDRAW_MICROLEVEL; +} + +void DrawMicroLevel(int xpos, int ypos, boolean restart) +{ + static unsigned long scroll_delay = 0; + static unsigned long label_delay = 0; + static int from_x, from_y, scroll_direction; + static int label_state, label_counter; + + if (restart) + { + from_x = from_y = 0; + scroll_direction = MV_RIGHT; + label_state = 1; + label_counter = 0; + + DrawMicroLevelExt(xpos, ypos, from_x, from_y); + DrawMicroLevelLabelExt(label_state); - XFillRectangle(display, drawto,gc, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); + /* initialize delay counters */ + DelayReached(&scroll_delay, 0); + DelayReached(&label_delay, 0); - if (level.name) + return; + } + + /* scroll micro level, if needed */ + if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) && + DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY)) { - int len = strlen(level.name); - int lxpos = SX + (SXSIZE - len * FONT4_XSIZE) / 2; - int lypos = MICROLABEL_YPOS; + switch (scroll_direction) + { + case MV_LEFT: + if (from_x > 0) + from_x--; + else + scroll_direction = MV_UP; + break; + + case MV_RIGHT: + if (from_x < lev_fieldx - STD_LEV_FIELDX) + from_x++; + else + scroll_direction = MV_DOWN; + break; + + case MV_UP: + if (from_y > 0) + from_y--; + else + scroll_direction = MV_RIGHT; + break; + + case MV_DOWN: + if (from_y < lev_fieldy - STD_LEV_FIELDY) + from_y++; + else + scroll_direction = MV_LEFT; + break; - DrawText(lxpos, lypos, level.name, FS_SMALL, FC_SPECIAL2); + default: + break; + } + + DrawMicroLevelExt(xpos, ypos, from_x, from_y); } - redraw_mask |= REDRAW_MICROLEV; + /* redraw micro level label, if needed */ + if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 && + strcmp(level.author, ANONYMOUS_NAME) != 0 && + strcmp(level.author, leveldir[leveldir_nr].name) != 0 && + DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY)) + { + label_counter = (label_counter + 1) % 23; + label_state = (label_counter >= 0 && label_counter <= 7 ? 1 : + label_counter >= 9 && label_counter <= 12 ? 2 : + label_counter >= 14 && label_counter <= 21 ? 3 : 0); + DrawMicroLevelLabelExt(label_state); + } } int REQ_in_range(int x, int y) @@ -1957,6 +2132,7 @@ int el2gfx(int element) case EL_SPEED_PILL: return GFX_SPEED_PILL; case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL; case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE; + case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL; default: {