X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=900e5ef7078e610454db0973d6b92b0e898d237d;hb=c16ef99848a25648feccaae350ada6f8665a18f4;hp=1d1c4ddab74dac7b8b66da271fc30c613a60ee7c;hpb=0a87fde47bcff35f196024766f8d0d00319a28d1;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 1d1c4dda..900e5ef7 100644 --- a/src/tools.c +++ b/src/tools.c @@ -117,13 +117,31 @@ void BackToFront() if (setup.soft_scrolling) { - fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0); - fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0); + fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0); + fy += (ScreenMovDir & (MV_UP | MV_DOWN) ? ScreenGfxPos : 0); } - XCopyArea(display,buffer,window,gc, - fx,fy, SXSIZE,SYSIZE, - SX,SY); + if (setup.soft_scrolling || + ABS(ScreenMovPos) + ScrollStepSize == TILEX || + ABS(ScreenMovPos) == ScrollStepSize || + redraw_tiles > REDRAWTILES_THRESHOLD) + { + XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY); + +#ifdef DEBUG +#if 0 + printf("redrawing all (ScreenGfxPos == %d) because %s\n", + ScreenGfxPos, + (setup.soft_scrolling ? + "setup.soft_scrolling" : + ABS(ScreenGfxPos) + ScrollStepSize == TILEX ? + "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" : + ABS(ScreenGfxPos) == ScrollStepSize ? + "ABS(ScreenGfxPos) == ScrollStepSize" : + "redraw_tiles > REDRAWTILES_THRESHOLD")); +#endif +#endif + } } redraw_mask &= ~REDRAW_MAIN; } @@ -159,18 +177,27 @@ void BackToFront() VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS); } } + if (redraw_mask & REDRAW_DOOR_3) + XCopyArea(display, backbuffer, window, gc, + EX, EY, EXSIZE, EYSIZE, + EX, EY); 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); + redraw_mask &= ~REDRAW_MICROLEVEL; + } + + if (redraw_mask & REDRAW_MICROLEVEL_LABEL) + { 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_LABEL; } if (redraw_mask & REDRAW_TILES) @@ -327,6 +354,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; @@ -342,10 +370,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 == 'Ä') @@ -356,10 +390,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; } @@ -521,7 +572,10 @@ void DrawPlayer(struct PlayerInfo *player) phase = 7 - phase; } - DrawGraphicThruMask(sx, sy, graphic + phase); + if (game_emulation == EMU_SUPAPLEX) + DrawGraphic(sx, sy, GFX_SP_DISK_RED); + else + DrawGraphicThruMask(sx, sy, graphic + phase); } if ((last_jx != jx || last_jy != jy) && @@ -620,6 +674,14 @@ void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic) SY + (graphic / GFX_PER_LINE) * TILEY, TILEX, TILEY, x, y); } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + graphic -= GFX_START_ROCKSMORE; + XCopyArea(display, pix[PIX_MORE], d, gc, + (graphic % MORE_PER_LINE) * TILEX, + (graphic / MORE_PER_LINE) * TILEY, + TILEX, TILEY, x, y); + } else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES) { graphic -= GFX_START_ROCKSHEROES; @@ -671,6 +733,14 @@ void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic) src_x = SX + (graphic % GFX_PER_LINE) * TILEX; src_y = SY + (graphic / GFX_PER_LINE) * TILEY; } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + src_pixmap = pix[PIX_MORE]; + drawing_gc = clip_gc[PIX_MORE]; + graphic -= GFX_START_ROCKSMORE; + src_x = (graphic % MORE_PER_LINE) * TILEX; + src_y = (graphic / MORE_PER_LINE) * TILEY; + } else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES) { src_pixmap = pix[PIX_HEROES]; @@ -720,6 +790,14 @@ void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic) MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY, MINI_TILEX, MINI_TILEY, x, y); } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + graphic -= GFX_START_ROCKSMORE; + XCopyArea(display, pix[PIX_MORE], d, gc, + MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX, + MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY, + MINI_TILEX, MINI_TILEY, x, y); + } else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT) { graphic -= GFX_START_ROCKSFONT; @@ -821,6 +899,14 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, src_x = SX + (graphic % GFX_PER_LINE) * TILEX + cx; src_y = SY + (graphic / GFX_PER_LINE) * TILEY + cy; } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + src_pixmap = pix[PIX_MORE]; + drawing_gc = clip_gc[PIX_MORE]; + graphic -= GFX_START_ROCKSMORE; + src_x = (graphic % MORE_PER_LINE) * TILEX + cx; + src_y = (graphic / MORE_PER_LINE) * TILEY + cy; + } else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES) { src_pixmap = pix[PIX_HEROES]; @@ -829,6 +915,8 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, src_x = (graphic % HEROES_PER_LINE) * TILEX + cx; src_y = (graphic / HEROES_PER_LINE) * TILEY + cy; } + else /* big font graphics currently not allowed (and not needed) */ + return; dest_x = FX + x * TILEX + dx; dest_y = FY + y * TILEY + dy; @@ -880,13 +968,14 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, { int ux = LEVELX(x), uy = LEVELY(y); int graphic = el2gfx(element); - int phase4 = ABS(MovPos[ux][uy]) / (TILEX / 4); - int phase = phase4 / 2; + int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8); + int phase4 = phase8 / 2; + int phase2 = phase8 / 4; int dir = MovDir[ux][uy]; if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER) { - graphic += 4*!phase; + graphic += 4 * !phase2; if (dir == MV_UP) graphic += 1; @@ -895,6 +984,23 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, else if (dir == MV_DOWN) graphic += 3; } + else if (element == EL_SP_SNIKSNAK) + { + if (dir == MV_LEFT) + graphic = GFX_SP_SNIKSNAK_LEFT; + else if (dir == MV_RIGHT) + graphic = GFX_SP_SNIKSNAK_RIGHT; + else if (dir == MV_UP) + graphic = GFX_SP_SNIKSNAK_UP; + else + graphic = GFX_SP_SNIKSNAK_DOWN; + + graphic += (phase8 < 4 ? phase8 : 7 - phase8); + } + else if (element == EL_SP_ELECTRON) + { + graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL); + } else if (element == EL_MAULWURF || element == EL_PINGUIN || element == EL_SCHWEIN || element == EL_DRACHE) { @@ -927,16 +1033,17 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, } else if (element == EL_BUTTERFLY || element == EL_FIREFLY) { - graphic += !phase; + graphic += !phase2; } else if ((element == EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode) { - graphic += phase * (element == EL_FELSBROCKEN ? 2 : 1); + if (element != EL_SP_INFOTRON) + graphic += phase2 * (element == EL_FELSBROCKEN ? 2 : 1); } - else if ((element == EL_SIEB_LEER || element == EL_SIEB2_LEER || - element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL) && SiebAktiv) + else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER || + element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL) { - graphic += 3 - (SiebAktiv % 8) / 2; + graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE); } else if (IS_AMOEBOID(element)) { @@ -1127,7 +1234,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; } @@ -1251,10 +1363,19 @@ void DrawMicroElement(int xpos, int ypos, int element) graphic = el2gfx(element); - XCopyArea(display, pix[PIX_BACK], drawto, gc, - MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX, - MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY, - MICRO_TILEX, MICRO_TILEY, xpos, ypos); + if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + graphic -= GFX_START_ROCKSMORE; + XCopyArea(display, pix[PIX_MORE], drawto, gc, + MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX, + MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY, + MICRO_TILEX, MICRO_TILEY, xpos, ypos); + } + else + XCopyArea(display, pix[PIX_BACK], drawto, gc, + MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX, + MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY, + MICRO_TILEX, MICRO_TILEY, xpos, ypos); } void DrawLevel() @@ -1278,49 +1399,120 @@ 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); + } + } - XFillRectangle(display, drawto,gc, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); + redraw_mask |= REDRAW_MICROLEVEL; +} + +void DrawMicroLevel(int xpos, int ypos, boolean restart) +{ + static unsigned long scroll_delay = 0; + static int from_x, from_y, scroll_direction; - if (level.name) + if (restart) { - int len = strlen(level.name); - int lxpos = SX + (SXSIZE - len * FONT4_XSIZE) / 2; - int lypos = MICROLABEL_YPOS; + from_x = from_y = 0; + scroll_direction = MV_RIGHT; - DrawText(lxpos, lypos, level.name, FS_SMALL, FC_SPECIAL2); + DrawMicroLevelExt(xpos, ypos, from_x, from_y); + + XFillRectangle(display, drawto,gc, + SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE); + + if (level.name && restart) + { + int len = strlen(level.name); + int lxpos = SX + (SXSIZE - len * FONT4_XSIZE) / 2; + int lypos = MICROLABEL_YPOS; + + DrawText(lxpos, lypos, level.name, FS_SMALL, FC_SPECIAL2); + } + + /* initialize delay counter */ + DelayReached(&scroll_delay, 0); + + redraw_mask |= REDRAW_MICROLEVEL_LABEL; } + else + { + if ((lev_fieldx <= STD_LEV_FIELDX && lev_fieldy <= STD_LEV_FIELDY) || + !DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY)) + return; - redraw_mask |= REDRAW_MICROLEV; + 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; + + default: + break; + } + + DrawMicroLevelExt(xpos, ypos, from_x, from_y); + } } int REQ_in_range(int x, int y) @@ -1597,11 +1789,11 @@ unsigned int GetDoorState() unsigned int MoveDoor(unsigned int door_state) { - static unsigned int door1 = DOOR_OPEN_1; - static unsigned int door2 = DOOR_CLOSE_2; - static long door_delay = 0; + static int door1 = DOOR_OPEN_1; + static int door2 = DOOR_CLOSE_2; + static unsigned long door_delay = 0; int x, start, stepsize = 2; - long door_delay_value = stepsize * 5; + unsigned long door_delay_value = stepsize * 5; if (door_state == DOOR_GET_STATE) return(door1 | door2); @@ -1728,10 +1920,15 @@ unsigned int MoveDoor(unsigned int door_state) int ReadPixel(Drawable d, int x, int y) { - static XImage *pixelimage; + XImage *pixel_image; + unsigned long pixel_value; + + pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap); + pixel_value = XGetPixel(pixel_image, 0, 0); - pixelimage = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap); - return(XGetPixel(pixelimage, 0, 0)); + XDestroyImage(pixel_image); + + return pixel_value; } int el2gfx(int element) @@ -1781,6 +1978,7 @@ int el2gfx(int element) case EL_MORAST_VOLL: return GFX_MORAST_VOLL; case EL_TROPFEN: return GFX_TROPFEN; case EL_BOMBE: return GFX_BOMBE; + case EL_SIEB_INAKTIV: return GFX_SIEB_INAKTIV; case EL_SIEB_LEER: return GFX_SIEB_LEER; case EL_SIEB_VOLL: return GFX_SIEB_VOLL; case EL_SIEB_TOT: return GFX_SIEB_TOT; @@ -1841,6 +2039,7 @@ int el2gfx(int element) case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT; case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA; case EL_MAMPFER2: return GFX_MAMPFER2; + case EL_SIEB2_INAKTIV: return GFX_SIEB2_INAKTIV; case EL_SIEB2_LEER: return GFX_SIEB2_LEER; case EL_SIEB2_VOLL: return GFX_SIEB2_VOLL; case EL_SIEB2_TOT: return GFX_SIEB2_TOT; @@ -1860,10 +2059,25 @@ int el2gfx(int element) case EL_PFEIL_R: return GFX_PFEIL_R; case EL_PFEIL_O: return GFX_PFEIL_O; case EL_PFEIL_U: return GFX_PFEIL_U; + 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: { if (IS_CHAR(element)) return GFX_CHAR_START + (element - EL_CHAR_START); + else if (element >= EL_SP_START && element <= EL_SP_END) + { + int nr_element = element - EL_SP_START; + int gfx_per_line = 8; + int nr_graphic = + (nr_element / gfx_per_line) * MORE_PER_LINE + + (nr_element % gfx_per_line); + + return GFX_START_ROCKSMORE + nr_graphic; + } else return -1; }