X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=258c99a6517a72c65b3c205214920884a8483bcf;hb=72b2940bea34cebf61175bc62a474cb78dcec467;hp=797befefd672ee8451de8d191e3c35dbef241e7f;hpb=6db563bee95da1c0a791bc5f425edae162628c13;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 797befef..258c99a6 100644 --- a/src/tools.c +++ b/src/tools.c @@ -43,6 +43,7 @@ extern boolean wait_for_vsync; #define NUM_TOOL_BUTTONS 7 /* forward declaration for internal use */ +static int getGraphicAnimationPhase(int, int, int); static void UnmapToolButtons(); static void HandleToolButtons(struct GadgetInfo *); @@ -117,9 +118,9 @@ void BackToFront() if (redraw_mask & REDRAW_ALL) { - XCopyArea(display,backbuffer,window,gc, - 0,0, WIN_XSIZE,WIN_YSIZE, - 0,0); + XCopyArea(display, backbuffer, window, gc, + 0, 0, WIN_XSIZE, WIN_YSIZE, + 0, 0); redraw_mask = 0; } @@ -127,9 +128,9 @@ void BackToFront() { if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER) { - XCopyArea(display,backbuffer,window,gc, - REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, - REAL_SX,REAL_SY); + XCopyArea(display, backbuffer, window, gc, + REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + REAL_SX, REAL_SY); } else { @@ -169,9 +170,9 @@ void BackToFront() if (redraw_mask & REDRAW_DOORS) { if (redraw_mask & REDRAW_DOOR_1) - XCopyArea(display,backbuffer,window,gc, - DX,DY, DXSIZE,DYSIZE, - DX,DY); + XCopyArea(display, backbuffer, window, gc, + DX, DY, DXSIZE, DYSIZE, + DX, DY); if (redraw_mask & REDRAW_DOOR_2) { if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2) @@ -419,7 +420,7 @@ void DrawTextExt(Drawable d, GC gc, int x, int 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], + XCopyArea(display, pix[font_pixmap], d, clip_gc[font_pixmap], 0, 0, font_width, font_height, dest_x, dest_y); } else @@ -455,8 +456,9 @@ void DrawPlayer(struct PlayerInfo *player) int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy); int sx = SCREENX(jx), sy = SCREENY(jy); int sxx = 0, syy = 0; - int element = Feld[jx][jy]; + int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy]; int graphic, phase; + boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE); if (!player->active || player->gone || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy))) @@ -477,14 +479,18 @@ void DrawPlayer(struct PlayerInfo *player) /* draw things in the field the player is leaving, if needed */ + /* if (last_jx != jx || last_jy != jy) + */ + + if (player_is_moving) { - if (Store[last_jx][last_jy]) + if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element)) { DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]); DrawLevelFieldThruMask(last_jx, last_jy); } - else if (Feld[last_jx][last_jy] == EL_DYNAMIT) + else if (last_element == EL_DYNAMIT) DrawDynamite(last_jx, last_jy); else DrawLevelField(last_jx, last_jy); @@ -518,17 +524,73 @@ void DrawPlayer(struct PlayerInfo *player) /* draw player himself */ - if (player->MovDir == MV_LEFT) - graphic = (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT); - else if (player->MovDir == MV_RIGHT) - graphic = (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT); - else if (player->MovDir == MV_UP) - graphic = GFX_SPIELER1_UP; - else /* MV_DOWN || MV_NO_MOVING */ - graphic = GFX_SPIELER1_DOWN; + if (game_emulation == EMU_SUPAPLEX) + { + static int last_dir = MV_LEFT; + int action = (player->programmed_action ? player->programmed_action : + player->action); + boolean action_moving = + (player_is_moving || + ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) && + !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)))); + + graphic = GFX_SP_MURPHY; + + if (player->Pushing) + { + if (player->MovDir == MV_LEFT) + graphic = GFX_MURPHY_PUSH_LEFT; + else if (player->MovDir == MV_RIGHT) + graphic = GFX_MURPHY_PUSH_RIGHT; + else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT) + graphic = GFX_MURPHY_PUSH_LEFT; + else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT) + graphic = GFX_MURPHY_PUSH_RIGHT; + } + else if (player->snapped) + { + if (player->MovDir == MV_LEFT) + graphic = GFX_MURPHY_SNAP_LEFT; + else if (player->MovDir == MV_RIGHT) + graphic = GFX_MURPHY_SNAP_RIGHT; + else if (player->MovDir == MV_UP) + graphic = GFX_MURPHY_SNAP_UP; + else if (player->MovDir == MV_DOWN) + graphic = GFX_MURPHY_SNAP_DOWN; + } + else if (action_moving) + { + if (player->MovDir == MV_LEFT) + graphic = GFX_MURPHY_GO_LEFT; + else if (player->MovDir == MV_RIGHT) + graphic = GFX_MURPHY_GO_RIGHT; + else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT) + graphic = GFX_MURPHY_GO_LEFT; + else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT) + graphic = GFX_MURPHY_GO_RIGHT; + + graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE); + } + + if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT) + last_dir = player->MovDir; + } + else + { + if (player->MovDir == MV_LEFT) + graphic = + (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT); + else if (player->MovDir == MV_RIGHT) + graphic = + (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT); + else if (player->MovDir == MV_UP) + graphic = GFX_SPIELER1_UP; + else /* MV_DOWN || MV_NO_MOVING */ + graphic = GFX_SPIELER1_DOWN; - graphic += player->index_nr * 3*HEROES_PER_LINE; - graphic += player->Frame; + graphic += player->index_nr * 3 * HEROES_PER_LINE; + graphic += player->Frame; + } if (player->GfxPos) { @@ -547,7 +609,7 @@ void DrawPlayer(struct PlayerInfo *player) { int px = SCREENX(next_jx), py = SCREENY(next_jy); - if (Feld[jx][jy] == EL_SOKOBAN_FELD_LEER || + if (element == EL_SOKOBAN_FELD_LEER || Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL) DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT, NO_CUTTING); @@ -556,21 +618,21 @@ void DrawPlayer(struct PlayerInfo *player) int element = Feld[next_jx][next_jy]; int graphic = el2gfx(element); - if (element == EL_FELSBROCKEN && sxx) + if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK) && sxx) { - int phase = (player->GfxPos / (TILEX/4)); + int phase = (player->GfxPos / (TILEX / 4)); if (player->MovDir == MV_LEFT) graphic += phase; else - graphic += (phase+4)%4; + graphic += (phase + 4) % 4; } DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING); } } - /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */ + /* draw things in front of player (EL_DYNAMIT or EL_DYNABOMB) */ if (element == EL_DYNAMIT || element == EL_DYNABOMB) { @@ -593,8 +655,11 @@ void DrawPlayer(struct PlayerInfo *player) DrawGraphicThruMask(sx, sy, graphic + phase); } - if ((last_jx != jx || last_jy != jy) && - Feld[last_jx][last_jy] == EL_EXPLODING) + /* + if ((last_jx != jx || last_jy != jy) && last_element == EL_EXPLODING) + */ + + if (player_is_moving && last_element == EL_EXPLODING) { int phase = Frame[last_jx][last_jy]; int delay = 2; @@ -604,6 +669,14 @@ void DrawPlayer(struct PlayerInfo *player) GFX_EXPLOSION + ((phase - 1) / delay - 1)); } + /* draw elements that stay over the player */ + /* handle the field the player is leaving ... */ + if (player_is_moving && IS_OVER_PLAYER(last_element)) + DrawLevelField(last_jx, last_jy); + /* ... and the field the player is entering */ + if (IS_OVER_PLAYER(element)) + DrawLevelField(jx, jy); + if (setup.direct_draw) { int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX; @@ -664,6 +737,45 @@ void DrawGraphicAnimationThruMask(int x, int y, int graphic, DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING); } +void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y) +{ + if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) + { + graphic -= GFX_START_ROCKSSCREEN; + *pixmap_nr = PIX_BACK; + *x = SX + (graphic % GFX_PER_LINE) * TILEX; + *y = SY + (graphic / GFX_PER_LINE) * TILEY; + } + else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) + { + graphic -= GFX_START_ROCKSMORE; + *pixmap_nr = PIX_MORE; + *x = (graphic % MORE_PER_LINE) * TILEX; + *y = (graphic / MORE_PER_LINE) * TILEY; + } + else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES) + { + graphic -= GFX_START_ROCKSHEROES; + *pixmap_nr = PIX_HEROES; + *x = (graphic % HEROES_PER_LINE) * TILEX; + *y = (graphic / HEROES_PER_LINE) * TILEY; + } + else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT) + { + graphic -= GFX_START_ROCKSFONT; + *pixmap_nr = PIX_BIGFONT; + *x = (graphic % FONT_CHARS_PER_LINE) * TILEX; + *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY + + FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY); + } + else + { + *pixmap_nr = PIX_MORE; + *x = 0; + *y = 0; + } +} + void DrawGraphic(int x, int y, int graphic) { #if DEBUG @@ -681,6 +793,18 @@ void DrawGraphic(int x, int y, int graphic) void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic) { + +#if 1 + + int pixmap_nr; + int src_x, src_y; + + getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y); + XCopyArea(display, pix[pixmap_nr], d, gc, + src_x, src_y, TILEX, TILEY, x, y); + +#else + if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) { graphic -= GFX_START_ROCKSSCREEN; @@ -716,6 +840,9 @@ void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic) } else XFillRectangle(display, d, gc, x, y, TILEX, TILEY); + +#endif + } void DrawGraphicThruMask(int x, int y, int graphic) @@ -735,6 +862,24 @@ void DrawGraphicThruMask(int x, int y, int graphic) void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic) { + +#if 1 + + int tile = graphic; + int pixmap_nr; + int src_x, src_y; + Pixmap src_pixmap; + GC drawing_gc; + + if (graphic == GFX_LEERRAUM) + return; + + getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y); + src_pixmap = pix[pixmap_nr]; + drawing_gc = clip_gc[pixmap_nr]; + +#else + int src_x, src_y; int tile = graphic; Pixmap src_pixmap; @@ -770,11 +915,14 @@ void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic) return; } +#endif + + if (tile_clipmask[tile] != None) { XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]); XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y); - XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc, + XCopyArea(display, src_pixmap, d, tile_clip_gc, src_x, src_y, TILEX, TILEY, dest_x, dest_y); } else @@ -784,7 +932,7 @@ void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic) #endif XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y); - XCopyArea(display, src_pixmap, drawto_field, drawing_gc, + XCopyArea(display, src_pixmap, d, drawing_gc, src_x, src_y, TILEX, TILEY, dest_x, dest_y); } } @@ -807,6 +955,7 @@ void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y) else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) { graphic -= GFX_START_ROCKSMORE; + graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2; *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; @@ -817,7 +966,7 @@ void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y) *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); + FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT); } else { @@ -829,6 +978,18 @@ void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y) void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic) { + +#if 1 + + Pixmap pixmap; + int src_x, src_y; + + getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y); + XCopyArea(display, pixmap, d, gc, + src_x, src_y, MINI_TILEX, MINI_TILEY, x, y); + +#else + if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN) { graphic -= GFX_START_ROCKSSCREEN; @@ -856,6 +1017,9 @@ void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic) } else XFillRectangle(display, d, gc, x, y, MINI_TILEX, MINI_TILEY); + +#endif + } void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, @@ -1082,10 +1246,35 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element, { graphic += !phase2; } - else if ((element == EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode) + else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK || + IS_GEM(element)) && !cut_mode) { - if (element != EL_SP_INFOTRON) + if (element == EL_FELSBROCKEN || element == EL_SP_ZONK) + { + if (dir == MV_LEFT) + graphic += (4 - phase4) % 4; + else if (dir == MV_RIGHT) + graphic += phase4; + else + graphic += phase2 * 2; + } + else if (element != EL_SP_INFOTRON) + graphic += phase2; + + /* + if (element == EL_SP_ZONK) + { + if (dir == MV_LEFT) + graphic += (4 - phase4) % 4; + else if (dir == MV_RIGHT) + graphic += phase4; + else + graphic += phase2 * 2; + } + else 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) @@ -1453,6 +1642,7 @@ void DrawMicroElement(int xpos, int ypos, int element) if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE) { graphic -= GFX_START_ROCKSMORE; + graphic -= ((graphic / MORE_PER_LINE) * MORE_PER_LINE) / 2; 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, @@ -1672,12 +1862,7 @@ boolean Request(char *text, unsigned int req_state) DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1); /* clear door drawing field */ -#if 0 - XFillRectangle(display, pix[PIX_DB_DOOR], gc, - DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE); -#else XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE); -#endif /* write text for request */ for(ty=0; ty<13; ty++) @@ -1702,37 +1887,12 @@ boolean Request(char *text, unsigned int req_state) } sprintf(txt, text); txt[tl] = 0; -#if 0 - DrawTextExt(pix[PIX_DB_DOOR], gc, - DOOR_GFX_PAGEX1 + 51 - (tl * 14)/2, SY + ty * 16, - txt, FS_SMALL, FC_YELLOW); -#else DrawTextExt(drawto, gc, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16, txt, FS_SMALL, FC_YELLOW); -#endif text += tl + (tc == 32 ? 1 : 0); } -#if 0 - if (req_state & REQ_ASK) - { - DrawYesNoButton(BUTTON_OK, DB_INIT); - DrawYesNoButton(BUTTON_NO, DB_INIT); - } - else if (req_state & REQ_CONFIRM) - { - DrawConfirmButton(BUTTON_CONFIRM, DB_INIT); - } - else if (req_state & REQ_PLAYER) - { - DrawPlayerButton(BUTTON_PLAYER_1, DB_INIT); - DrawPlayerButton(BUTTON_PLAYER_2, DB_INIT); - DrawPlayerButton(BUTTON_PLAYER_3, DB_INIT); - DrawPlayerButton(BUTTON_PLAYER_4, DB_INIT); - } -#else - if (req_state & REQ_ASK) { MapGadget(tool_gadget[TOOL_CTRL_ID_YES]); @@ -1755,8 +1915,6 @@ boolean Request(char *text, unsigned int req_state) DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); -#endif - OpenDoor(DOOR_OPEN_1); ClearEventQueue(); @@ -1784,11 +1942,6 @@ boolean Request(char *text, unsigned int req_state) case ButtonRelease: case MotionNotify: { - -#if 0 - int choice; -#endif - if (event.type == MotionNotify) { Window root, child; @@ -1818,46 +1971,6 @@ boolean Request(char *text, unsigned int req_state) button_status = MB_RELEASED; } - - -#if 0 - if (req_state & REQ_ASK) - choice = CheckYesNoButtons(mx,my,button_status); - else if (req_state & REQ_CONFIRM) - choice = CheckConfirmButton(mx,my,button_status); - else - choice = CheckPlayerButtons(mx,my,button_status); - - switch(choice) - { - case BUTTON_OK: - result = TRUE; - break; - case BUTTON_NO: - result = FALSE; - break; - case BUTTON_CONFIRM: - result = TRUE | FALSE; - break; - - case BUTTON_PLAYER_1: - result = 1; - break; - case BUTTON_PLAYER_2: - result = 2; - break; - case BUTTON_PLAYER_3: - result = 3; - break; - case BUTTON_PLAYER_4: - result = 4; - break; - - default: - break; - } -#else - /* this sets 'request_gadget_id' */ HandleGadgets(mx, my, button_status); @@ -1889,7 +2002,6 @@ boolean Request(char *text, unsigned int req_state) default: break; } -#endif break; } @@ -2265,8 +2377,8 @@ void CreateToolButtons() for (i=0; i