X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fmain_bd.c;h=77af13a28c158a4e59ce6f43e1607d09af895325;hb=b6b5d3fe94b178e8e48e9c51b61f3b1b8383a42f;hp=8f80b4f485e6d40bb4407ab930bc802df1cb1788;hpb=c3f4524693a17a8d75c7d25da24d4003b234d114;p=rocksndiamonds.git diff --git a/src/game_bd/main_bd.c b/src/game_bd/main_bd.c index 8f80b4f4..77af13a2 100644 --- a/src/game_bd/main_bd.c +++ b/src/game_bd/main_bd.c @@ -69,6 +69,11 @@ void setLevelInfoToDefaults_BD_Ext(int width, int height) { cave->w = width; cave->h = height; + + cave->x1 = 0; + cave->y1 = 0; + cave->x2 = cave->w - 1; + cave->y2 = cave->h - 1; } gd_flatten_cave(cave, 0); @@ -90,6 +95,30 @@ void setLevelInfoToDefaults_BD(void) setLevelInfoToDefaults_BD_Ext(0, 0); } +static List *getNativeLevelReplay_BD_Ext(List *item, boolean only_successful_replays) +{ + // look for replay that was recorded for the current difficulty level + while (item != NULL && + (item->data == NULL || + (((GdReplay *)item->data)->success == FALSE && only_successful_replays) || + ((GdReplay *)item->data)->level != native_bd_level.level_nr)) + item = item->next; + + return item; +} + +static List *getNativeLevelReplay_BD(List *replays) +{ + // 1st try: look for successful replay + List *item = getNativeLevelReplay_BD_Ext(replays, TRUE); + + if (item != NULL) + return item; + + // 2nd try: look for any replay + return getNativeLevelReplay_BD_Ext(replays, FALSE); +} + boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_only) { static char *filename_loaded = NULL; @@ -132,16 +161,9 @@ boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_onl // check if this cave has any replays if (native_bd_level.cave->replays != NULL) { - GList *item = native_bd_level.cave->replays; + List *item = getNativeLevelReplay_BD(native_bd_level.cave->replays); - // try to find replay that was recorded for this difficulty level - while (item != NULL && - (item->data == NULL || - ((GdReplay *)item->data)->success == FALSE || - ((GdReplay *)item->data)->level != native_bd_level.level_nr)) - item = item->next; - - // matching replay found + // check if any matching replay was found if (item != NULL) native_bd_level.replay = (GdReplay *)item->data; } @@ -149,6 +171,16 @@ boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_onl return TRUE; } +boolean SaveNativeLevel_BD(char *filename) +{ + GdCave *cave = gd_cave_new_from_cave(native_bd_level.cave); + + gd_caveset_clear(); + gd_caveset = list_append(gd_caveset, cave); + + return gd_caveset_save_to_file(filename); +} + // ============================================================================ // game engine functions @@ -233,12 +265,36 @@ static void UpdateGameDoorValues_BD(void) } } +static void PrepareGameTileBitmap_BD(void) +{ + struct GraphicInfo_BD *g_template = &graphic_info_bd_color_template; + struct GraphicInfo_BD *g_default = &graphic_info_bd_object[O_STONE][0]; + + gd_prepare_tile_bitmap(native_bd_level.cave, g_template->bitmap, 1); + gd_set_tile_bitmap_reference(g_default->bitmap); +} + +void PreparePreviewTileBitmap_BD(Bitmap *bitmap, int scale_down_factor) +{ + gd_prepare_tile_bitmap(native_bd_level.cave, bitmap, scale_down_factor); +} + +void SetPreviewTileBitmapReference_BD(Bitmap *bitmap) +{ + gd_set_tile_bitmap_reference(bitmap); +} + +Bitmap *GetPreviewTileBitmap_BD(Bitmap *bitmap) +{ + return gd_get_tile_bitmap(bitmap); +} + unsigned int InitEngineRandom_BD(int seed) { if (seed == NEW_RANDOMIZE) { // get randomly selected seed to render the cave - seed = g_random_int_range(0, GD_CAVE_SEED_MAX); + seed = gd_random_int_range(0, GD_CAVE_SEED_MAX); } game_bd.random_seed = seed; @@ -264,6 +320,13 @@ void InitGameEngine_BD(void) game_bd.game = gd_game_new(native_bd_level.cave_nr, native_bd_level.level_nr); + game_bd.game->itercycle = 0; + game_bd.game->itermax = 8; // default; dynamically changed at runtime + game_bd.game->itermax_last = game_bd.game->itermax; + + // prepare tile bitmap with level-specific colors, if available + PrepareGameTileBitmap_BD(); + // default: start with completely covered playfield int next_state = GAME_INT_START_UNCOVER + 1; @@ -282,6 +345,8 @@ void InitGameEngine_BD(void) if (setup.bd_skip_uncovering) gd_scroll(game_bd.game, TRUE, TRUE); + ClearRectangle(gd_screen_bitmap, 0, 0, SXSIZE, SYSIZE); + RedrawPlayfield_BD(TRUE); UpdateGameDoorValues_BD(); @@ -338,6 +403,19 @@ void GameActions_BD(byte action[MAX_PLAYERS]) play_game_func(game_bd.game, action[0]); + // scroll without iterating engine if player out of sight (mainly due to wrap-around) + // (this is needed to prevent broken tapes in case of viewport or tile size changes) + while (game_bd.game->out_of_window) + { + RedrawPlayfield_BD(TRUE); + + BlitScreenToBitmap_BD(backbuffer); + + BackToFront(); + + play_game_func(game_bd.game, action[0]); + } + RedrawPlayfield_BD(FALSE); UpdateGameDoorValues_BD(); @@ -348,6 +426,11 @@ void GameActions_BD(byte action[MAX_PLAYERS]) // graphics functions // ============================================================================ +Bitmap *GetTitleScreen_BD(void) +{ + return gd_get_title_screen_bitmap(); +} + void CoverScreen_BD(void) { game_bd.cover_screen = FALSE; @@ -375,10 +458,11 @@ void CoverScreen_BD(void) void BlitScreenToBitmap_BD(Bitmap *target_bitmap) { + GdCave *cave = native_bd_level.cave; int xsize = SXSIZE; int ysize = SYSIZE; - int full_xsize = native_bd_level.cave->w * TILESIZE_VAR; - int full_ysize = native_bd_level.cave->h * TILESIZE_VAR; + int full_xsize = (cave->x2 - cave->x1 + 1) * TILESIZE_VAR; + int full_ysize = (cave->y2 - cave->y1 + 1) * TILESIZE_VAR; int sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0); int sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0); int sxsize = (full_xsize < xsize ? full_xsize : xsize);