X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=6f2c96e21840bccbc7aefb193e3f0d710fe6b253;hb=6d7ebf6db8a9a57f2e3e398da1d2f7d8d084523f;hp=e49e0937a4ca0d879c7f42e09719033e5ccd0882;hpb=d9b86b7b2ebe0b2be3926656c3bbdcd060ee5811;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index e49e0937..6f2c96e2 100644 --- a/src/tools.c +++ b/src/tools.c @@ -20,6 +20,10 @@ #include "network.h" #include "tape.h" + +/* select level set with EMC X11 graphics before activating EM GFX debugging */ +#define DEBUG_EM_GFX 0 + /* tool button identifiers */ #define TOOL_CTRL_ID_YES 0 #define TOOL_CTRL_ID_NO 1 @@ -63,6 +67,12 @@ void DumpTile(int x, int y) int sx = SCREENX(x); int sy = SCREENY(y); + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + { + x--; + y--; + } + printf_line("-", 79); printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y); printf_line("-", 79); @@ -127,11 +137,9 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height) if (game_status == GAME_MODE_PLAYING && level.game_engine_type == GAME_ENGINE_TYPE_EM) { -#if 1 - RedrawPlayfield_EM(force_redraw); -#else - BlitScreenToBitmap_EM(backbuffer); -#endif + /* currently there is no partial redraw -- always redraw whole playfield */ + + RedrawPlayfield_EM(TRUE); } else if (game_status == GAME_MODE_PLAYING && !game.envelope_active) { @@ -233,7 +241,8 @@ void BackToFront() if (redraw_mask & REDRAW_ALL) { BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - redraw_mask = 0; + + redraw_mask = REDRAW_NONE; } if (redraw_mask & REDRAW_FIELD) @@ -405,6 +414,114 @@ void FadeToFront() BackToFront(); } +#define FADE_MODE_FADE_IN 0 +#define FADE_MODE_FADE_OUT 1 +#define FADE_MODE_CROSSFADE 2 + +static void FadeExt(Bitmap *bitmap_cross, int fade_ms, int fade_mode) +{ + SDL_Surface *surface_screen = backbuffer->surface; + SDL_Surface *surface_screen_copy = NULL; + SDL_Surface *surface_black = NULL; + SDL_Surface *surface_cross; /* initialized later */ + boolean fade_reverse; /* initialized later */ + unsigned int flags = SDL_SRCALPHA; + unsigned int time_last, time_current; + float alpha; + int alpha_final; + + /* use same surface type as screen surface */ + if ((surface_screen->flags & SDL_HWSURFACE)) + flags |= SDL_HWSURFACE; + else + flags |= SDL_SWSURFACE; + + /* create surface for copy of screen buffer */ + if ((surface_screen_copy = + SDL_CreateRGBSurface(flags, + surface_screen->w, + surface_screen->h, + surface_screen->format->BitsPerPixel, + surface_screen->format->Rmask, + surface_screen->format->Gmask, + surface_screen->format->Bmask, + surface_screen->format->Amask)) == NULL) + Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); + + SDL_BlitSurface(surface_screen, NULL, surface_screen_copy, NULL); + + /* create black surface for fading from/to black */ + if ((surface_black = + SDL_CreateRGBSurface(flags, + surface_screen->w, + surface_screen->h, + surface_screen->format->BitsPerPixel, + surface_screen->format->Rmask, + surface_screen->format->Gmask, + surface_screen->format->Bmask, + surface_screen->format->Amask)) == NULL) + Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); + + SDL_FillRect(surface_black, NULL, SDL_MapRGB(surface_screen->format, 0,0,0)); + + fade_reverse = (fade_mode == FADE_MODE_FADE_IN ? TRUE : FALSE); + surface_cross = (fade_mode == FADE_MODE_CROSSFADE ? bitmap_cross->surface : + surface_black); + + time_current = SDL_GetTicks(); + + for (alpha = 0.0; alpha < 255.0;) + { + time_last = time_current; + time_current = SDL_GetTicks(); + alpha += 255 * ((float)(time_current - time_last) / fade_ms); + alpha_final = (int)(fade_reverse ? 255.0 - alpha : alpha); + alpha_final = MIN(MAX(0, alpha_final), 255); + + /* draw existing image to screen buffer */ + SDL_BlitSurface(surface_screen_copy, NULL, surface_screen, NULL); + + /* draw new image to screen buffer using alpha blending */ + SDL_SetAlpha(surface_cross, SDL_SRCALPHA, alpha_final); + SDL_BlitSurface(surface_cross, NULL, surface_screen, NULL); + + /* draw screen buffer to visible display */ + SDL_Flip(surface_screen); + } + + SDL_FreeSurface(surface_screen_copy); + SDL_FreeSurface(surface_black); + + redraw_mask = REDRAW_NONE; +} + +void FadeIn(int fade_ms) +{ +#ifdef TARGET_SDL + FadeExt(NULL, fade_ms, FADE_MODE_FADE_IN); +#else + BackToFront(); +#endif +} + +void FadeOut(int fade_ms) +{ +#ifdef TARGET_SDL + FadeExt(NULL, fade_ms, FADE_MODE_FADE_OUT); +#else + BackToFront(); +#endif +} + +void FadeCross(Bitmap *bitmap, int fade_ms) +{ +#ifdef TARGET_SDL + FadeExt(bitmap, fade_ms, FADE_MODE_CROSSFADE); +#else + BackToFront(); +#endif +} + void SetMainBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) @@ -495,6 +612,17 @@ inline int getGraphicAnimationFrame(int graphic, int sync_frame) if (graphic_info[graphic].anim_global_sync || sync_frame < 0) sync_frame = FrameCounter; +#if 0 + if (graphic == element_info[EL_CUSTOM_START + 255].graphic[ACTION_DEFAULT] && + sync_frame == 0 && + FrameCounter > 10) + { + int x = 1 / 0; + + printf("::: FOO!\n"); + } +#endif + return getAnimationFrame(graphic_info[graphic].anim_frames, graphic_info[graphic].anim_delay, graphic_info[graphic].anim_mode, @@ -903,10 +1031,6 @@ void DrawLevelFieldThruMask(int x, int y) DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING); } -#define TILE_GFX_ELEMENT(x, y) \ - (GfxElement[x][y] != EL_UNDEFINED && Feld[x][y] != EL_EXPLOSION ? \ - GfxElement[x][y] : Feld[x][y]) - static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) { Bitmap *src_bitmap; @@ -1041,10 +1165,19 @@ void DrawLevelFieldCrumbledSand(int x, int y) return; #if 1 + /* !!! CHECK THIS !!! */ + + /* + if (Feld[x][y] == EL_ELEMENT_SNAPPING && + GFX_CRUMBLED(GfxElement[x][y])) + */ + if (Feld[x][y] == EL_ELEMENT_SNAPPING && + GfxElement[x][y] != EL_UNDEFINED && GFX_CRUMBLED(GfxElement[x][y])) { DrawLevelFieldCrumbledSandDigging(x, y, GfxDir[x][y], GfxFrame[x][y]); + return; } #endif @@ -1639,9 +1772,9 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart) /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */ /* redraw micro level label, if needed */ - if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 && - strcmp(level.author, ANONYMOUS_NAME) != 0 && - strcmp(level.author, leveldir_current->name) != 0 && + if (!strEqual(level.name, NAMELESS_LEVEL_NAME) && + !strEqual(level.author, ANONYMOUS_NAME) && + !strEqual(level.author, leveldir_current->name) && DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY)) { int max_label_counter = 23; @@ -1822,6 +1955,7 @@ void DrawPlayer(struct PlayerInfo *player) int next_jx = jx + dx; int next_jy = jy + dy; boolean player_is_moving = (player->MovPos ? TRUE : FALSE); + boolean player_is_opaque = FALSE; int sx = SCREENX(jx), sy = SCREENY(jy); int sxx = 0, syy = 0; int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy]; @@ -1862,6 +1996,11 @@ void DrawPlayer(struct PlayerInfo *player) player->is_dropping ? ACTION_DROPPING : player->is_waiting ? player->action_waiting : ACTION_DEFAULT); +#if 1 + if (player->is_waiting) + move_dir = player->dir_waiting; +#endif + InitPlayerGfxAnimation(player, action, move_dir); /* ----------------------------------------------------------------------- */ @@ -1910,16 +2049,17 @@ void DrawPlayer(struct PlayerInfo *player) { if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED) { - if (GFX_CRUMBLED(GfxElement[jx][jy])) + int old_element = GfxElement[jx][jy]; + int old_graphic = el_act_dir2img(old_element, action, move_dir); + int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame); + + if (GFX_CRUMBLED(old_element)) DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame); else - { - int old_element = GfxElement[jx][jy]; - int old_graphic = el_act_dir2img(old_element, action, move_dir); - int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame); - DrawGraphic(sx, sy, old_graphic, frame); - } + + if (graphic_info[old_graphic].anim_mode & ANIM_OPAQUE_PLAYER) + player_is_opaque = TRUE; } else { @@ -1957,7 +2097,10 @@ void DrawPlayer(struct PlayerInfo *player) if (!setup.soft_scrolling && ScreenMovPos) sxx = syy = 0; - DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); + if (player_is_opaque) + DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING); + else + DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING); if (SHIELD_ON(player)) { @@ -2020,7 +2163,9 @@ void DrawPlayer(struct PlayerInfo *player) if (player_is_moving && last_element == EL_EXPLOSION) { - int graphic = el_act2img(GfxElement[last_jx][last_jy], ACTION_EXPLODING); + int element = (GfxElement[last_jx][last_jy] != EL_UNDEFINED ? + GfxElement[last_jx][last_jy] : EL_EMPTY); + int graphic = el_act2img(element, ACTION_EXPLODING); int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2); int phase = ExplodePhase[last_jx][last_jy] - 1; int frame = getGraphicAnimationFrame(graphic, phase - delay); @@ -2477,7 +2622,7 @@ unsigned int MoveDoor(unsigned int door_state) door_2.height = VYSIZE; if (door_state == DOOR_GET_STATE) - return(door1 | door2); + return (door1 | door2); if (door_state & DOOR_SET_STATE) { @@ -2486,7 +2631,7 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION_2) door2 = door_state & DOOR_ACTION_2; - return(door1 | door2); + return (door1 | door2); } if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1) @@ -2729,13 +2874,15 @@ unsigned int MoveDoor(unsigned int door_state) door_2_done = (a == VXSIZE); } - BackToFront(); + if (!(door_state & DOOR_NO_DELAY)) + { + BackToFront(); - if (game_status == GAME_MODE_MAIN) - DoAnimation(); + if (game_status == GAME_MODE_MAIN) + DoAnimation(); - if (!(door_state & DOOR_NO_DELAY)) WaitUntilDelayReached(&door_delay, door_delay_value); + } } } @@ -3469,19 +3616,19 @@ em_object_mapping_list[] = }, { Xeater_n, TRUE, FALSE, - EL_YAMYAM, -1, -1 + EL_YAMYAM_UP, -1, -1 }, { - Xeater_e, FALSE, FALSE, - EL_YAMYAM, -1, -1 + Xeater_e, TRUE, FALSE, + EL_YAMYAM_RIGHT, -1, -1 }, { - Xeater_w, FALSE, FALSE, - EL_YAMYAM, -1, -1 + Xeater_w, TRUE, FALSE, + EL_YAMYAM_LEFT, -1, -1 }, { - Xeater_s, FALSE, FALSE, - EL_YAMYAM, -1, -1 + Xeater_s, TRUE, FALSE, + EL_YAMYAM_DOWN, -1, -1 }, { Yeater_n, FALSE, FALSE, @@ -4152,19 +4299,19 @@ em_object_mapping_list[] = EL_QUICKSAND_FULL, -1, -1 }, { - Xsand_stonein_1, FALSE, FALSE, + Xsand_stonein_1, FALSE, TRUE, EL_ROCK, ACTION_FILLING, -1 }, { - Xsand_stonein_2, FALSE, FALSE, + Xsand_stonein_2, FALSE, TRUE, EL_ROCK, ACTION_FILLING, -1 }, { - Xsand_stonein_3, FALSE, FALSE, + Xsand_stonein_3, FALSE, TRUE, EL_ROCK, ACTION_FILLING, -1 }, { - Xsand_stonein_4, FALSE, FALSE, + Xsand_stonein_4, FALSE, TRUE, EL_ROCK, ACTION_FILLING, -1 }, { @@ -4591,10 +4738,6 @@ em_object_mapping_list[] = Xalpha_copyr, TRUE, FALSE, EL_CHAR('©'), -1, -1 }, - { - Xalpha_copyr, TRUE, FALSE, - EL_CHAR('©'), -1, -1 - }, { Xboom_bug, FALSE, FALSE, @@ -5114,26 +5257,19 @@ int font2baseimg(int font_nr) return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT]; } -int getGameFrameDelay_EM(int native_em_game_frame_delay) +#if 0 +void setCenteredPlayerNr_EM(int centered_player_nr) { - int game_frame_delay_value; - - game_frame_delay_value = - (tape.playing && tape.fast_forward ? FfwdFrameDelay : - GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay : - GameFrameDelay); - - if (tape.playing && tape.warp_forward && !tape.pausing) - game_frame_delay_value = 0; - - return game_frame_delay_value; + game.centered_player_nr = game.centered_player_nr_next = centered_player_nr; } int getCenteredPlayerNr_EM() { +#if 0 if (game.centered_player_nr_next >= 0 && !native_em_level.ply[game.centered_player_nr_next]->alive) game.centered_player_nr_next = game.centered_player_nr; +#endif if (game.centered_player_nr != game.centered_player_nr_next) game.centered_player_nr = game.centered_player_nr_next; @@ -5141,7 +5277,18 @@ int getCenteredPlayerNr_EM() return game.centered_player_nr; } -int getActivePlayers_EM() +void setSetCenteredPlayer_EM(boolean set_centered_player) +{ + game.set_centered_player = set_centered_player; +} + +boolean getSetCenteredPlayer_EM() +{ + return game.set_centered_player; +} +#endif + +int getNumActivePlayers_EM() { int num_players = 0; int i; @@ -5156,6 +5303,23 @@ int getActivePlayers_EM() return num_players; } +#if 1 +int getGameFrameDelay_EM(int native_em_game_frame_delay) +{ + int game_frame_delay_value; + + game_frame_delay_value = + (tape.playing && tape.fast_forward ? FfwdFrameDelay : + GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay : + GameFrameDelay); + + if (tape.playing && tape.warp_forward && !tape.pausing) + game_frame_delay_value = 0; + + return game_frame_delay_value; +} +#endif + unsigned int InitRND(long seed) { if (level.game_engine_type == GAME_ENGINE_TYPE_EM) @@ -5164,8 +5328,6 @@ unsigned int InitRND(long seed) return InitEngineRND(seed); } -#define DEBUG_EM_GFX 0 - void InitGraphicInfo_EM(void) { struct Mapping_EM_to_RND_object object_mapping[TILE_MAX]; @@ -5173,12 +5335,16 @@ void InitGraphicInfo_EM(void) int i, j, p; #if DEBUG_EM_GFX + int num_em_gfx_errors = 0; + if (graphic_info_em_object[0][0].bitmap == NULL) { /* EM graphics not yet initialized in em_open_all() */ return; } + + printf("::: [4 errors can be ignored (1 x 'bomb', 3 x 'em_dynamite']\n"); #endif /* always start with reliable default values */ @@ -5272,12 +5438,12 @@ void InitGraphicInfo_EM(void) i == Ymagnify_eat ? element : i == Ygrass_eat ? element : i == Ydirt_eat ? element : - i == Yspring_kill_e ? EL_SPRING : - i == Yspring_kill_w ? EL_SPRING : i == Yemerald_stone ? EL_EMERALD : i == Ydiamond_stone ? EL_ROCK : - i == Xsand_stonein_4 ? EL_EMPTY : - i == Xsand_stoneout_2 ? EL_ROCK : + i == Xsand_stonein_1 ? element : + i == Xsand_stonein_2 ? element : + i == Xsand_stonein_3 ? element : + i == Xsand_stonein_4 ? element : is_backside ? EL_EMPTY : action_removing ? EL_EMPTY : element); @@ -5319,6 +5485,7 @@ void InitGraphicInfo_EM(void) direction)); int base_graphic = el_act2img(effective_element, ACTION_DEFAULT); int base_crumbled = el_act2crm(effective_element, ACTION_DEFAULT); + boolean has_action_graphics = (graphic != base_graphic); boolean has_crumbled_graphics = (base_crumbled != base_graphic); struct GraphicInfo *g = &graphic_info[graphic]; struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j]; @@ -5486,23 +5653,43 @@ void InitGraphicInfo_EM(void) g_em->crumbled_border_size = graphic_info[crumbled].border_size; } - if (!g->double_movement && (effective_action == ACTION_FALLING || - effective_action == ACTION_MOVING || - effective_action == ACTION_PUSHING || - effective_action == ACTION_EATING)) +#if 0 + if (element == EL_ROCK && + effective_action == ACTION_FILLING) + printf("::: has_action_graphics == %d\n", has_action_graphics); +#endif + + if ((!g->double_movement && (effective_action == ACTION_FALLING || + effective_action == ACTION_MOVING || + effective_action == ACTION_PUSHING || + effective_action == ACTION_EATING)) || + (!has_action_graphics && (effective_action == ACTION_FILLING || + effective_action == ACTION_EMPTYING))) { int move_dir = - (effective_action == ACTION_FALLING ? MV_DOWN : direction); + (effective_action == ACTION_FALLING || + effective_action == ACTION_FILLING || + effective_action == ACTION_EMPTYING ? MV_DOWN : direction); int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0); int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0); - int num_steps = (i == Ydrip_s1 || - i == Ydrip_s1B || - i == Ydrip_s2 || - i == Ydrip_s2B ? 16 : 8); + int num_steps = (i == Ydrip_s1 ? 16 : + i == Ydrip_s1B ? 16 : + i == Ydrip_s2 ? 16 : + i == Ydrip_s2B ? 16 : + i == Xsand_stonein_1 ? 32 : + i == Xsand_stonein_2 ? 32 : + i == Xsand_stonein_3 ? 32 : + i == Xsand_stonein_4 ? 32 : + i == Xsand_stoneout_1 ? 16 : + i == Xsand_stoneout_2 ? 16 : 8); int cx = ABS(dx) * (TILEX / num_steps); int cy = ABS(dy) * (TILEY / num_steps); - int step_frame = (i == Ydrip_s2 || - i == Ydrip_s2B ? j + 8 : j) + 1; + int step_frame = (i == Ydrip_s2 ? j + 8 : + i == Ydrip_s2B ? j + 8 : + i == Xsand_stonein_2 ? j + 8 : + i == Xsand_stonein_3 ? j + 16 : + i == Xsand_stonein_4 ? j + 24 : + i == Xsand_stoneout_2 ? j + 8 : j) + 1; int step = (is_backside ? step_frame : num_steps - step_frame); if (is_backside) /* tile where movement starts */ @@ -5624,6 +5811,8 @@ void InitGraphicInfo_EM(void) printf(" %d (%d): size %d,%d should be %d,%d\n", j, is_backside, g_em->width, g_em->height, TILEX, TILEY); + + num_em_gfx_errors++; } #endif @@ -5770,6 +5959,8 @@ void InitGraphicInfo_EM(void) g_em->src_x / 32, g_em->src_y / 32, debug_src_x, debug_src_y, debug_src_x / 32, debug_src_y / 32); + + num_em_gfx_errors++; } #endif @@ -5778,6 +5969,9 @@ void InitGraphicInfo_EM(void) } #if DEBUG_EM_GFX + printf("\n"); + printf("::: [%d errors found]\n", num_em_gfx_errors); + exit(0); #endif }