diff --git a/injected_code.c b/injected_code.c index 5b81a7ab..f2a19de0 100644 --- a/injected_code.c +++ b/injected_code.c @@ -17335,6 +17335,8 @@ read_in_dir(PCX_Image *img, char temp_path[2*MAX_PATH]; snprintf(temp_path, sizeof temp_path, "%s\\%s", art_dir, filename); + if (img->JGL.Image != NULL) + img->vtable->clear_JGL (img); PCX_Image_read_file(img, __, temp_path, NULL, 0, 0x100, 2); } @@ -17797,11 +17799,8 @@ get_cycle_sprite_proxy(Sprite *s) { if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return NULL; - int season = (is->current_config.seasonal_cycle_mode != SCM_OFF) ? clamp (0, 3, is->current_seasonal_cycle) : CS_SUMMER; - int hour = (is->current_config.day_night_cycle_mode != DNCM_OFF) ? clamp (0, 23, is->current_day_night_cycle) : 12; - int cycle_idx = 24 * season + hour; int v; - if (itable_look_up (&is->day_night_sprite_proxy_by_season_and_hour[cycle_idx], (int)s, &v)) + if (itable_look_up (is->day_night_sprite_proxy_by_season_and_hour, (int)s, &v)) return (Sprite *)v; return NULL; } @@ -17810,13 +17809,12 @@ void insert_spritelist_proxies(SpriteList *ss, SpriteList *ps, int season, int hour, int len1, int len2) { if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return; - int cycle_idx = 24 * season + hour; for (int i = 0; i < len1; i++) { for (int j = 0; j < len2; j++) { Sprite *s = &ss[i].field_0[j]; Sprite *p = &ps[i].field_0[j]; if (s && p) { - itable_insert(&is->day_night_sprite_proxy_by_season_and_hour[cycle_idx], (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } } @@ -17826,12 +17824,11 @@ void insert_sprite_proxies(Sprite *ss, Sprite *ps, int season, int hour, int len) { if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return; - int cycle_idx = 24 * season + hour; for (int i = 0; i < len; i++) { Sprite *s = &ss[i]; Sprite *p = &ps[i]; if (s && p) { - itable_insert(&is->day_night_sprite_proxy_by_season_and_hour[cycle_idx], (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } } @@ -17840,29 +17837,26 @@ void insert_sprite_proxy(Sprite *s, Sprite *p, int season, int hour) { if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return; - int cycle_idx = 24 * season + hour; if (s && p) { - itable_insert(&is->day_night_sprite_proxy_by_season_and_hour[cycle_idx], (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } bool allocate_day_night_cycle_runtime_storage () { - int count = COUNT_CYCLE_SEASONS * 24; - if (is->cycle_imgs == NULL) { - is->cycle_imgs = malloc (count * sizeof is->cycle_imgs[0]); + is->cycle_imgs = malloc (sizeof is->cycle_imgs[0]); if (is->cycle_imgs == NULL) return false; - memset (is->cycle_imgs, 0, count * sizeof is->cycle_imgs[0]); + memset (is->cycle_imgs, 0, sizeof is->cycle_imgs[0]); } if (is->day_night_sprite_proxy_by_season_and_hour == NULL) { - is->day_night_sprite_proxy_by_season_and_hour = malloc (count * sizeof is->day_night_sprite_proxy_by_season_and_hour[0]); + is->day_night_sprite_proxy_by_season_and_hour = malloc (sizeof is->day_night_sprite_proxy_by_season_and_hour[0]); if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return false; - memset (is->day_night_sprite_proxy_by_season_and_hour, 0, count * sizeof is->day_night_sprite_proxy_by_season_and_hour[0]); + memset (is->day_night_sprite_proxy_by_season_and_hour, 0, sizeof is->day_night_sprite_proxy_by_season_and_hour[0]); } return true; @@ -17899,36 +17893,6 @@ get_next_enabled_season (int current_season, int mask) return CS_SUMMER; } -int -get_required_hour_mask_for_cycle_loading () -{ - if (is->current_config.day_night_cycle_mode == DNCM_OFF) - return 1 << 12; - - switch (is->current_config.day_night_cycle_mode) { - case DNCM_SPECIFIED: - return 1 << clamp (0, 23, is->current_config.pinned_hour_for_day_night_cycle); - default: - return (1 << 24) - 1; - } -} - -int -get_required_season_mask_for_cycle_loading () -{ - if (is->current_config.seasonal_cycle_mode == SCM_OFF) - return 1 << CS_SUMMER; - - int enabled_mask = normalize_enabled_season_mask (is->current_config.enabled_seasons_mask); - if (is->current_config.seasonal_cycle_mode == SCM_SPECIFIED) { - int pinned = clamp (CS_SUMMER, CS_SPRING, is->current_config.pinned_season_for_seasonal_cycle); - if ((enabled_mask & (1 << pinned)) != 0) - return 1 << pinned; - return 1 << get_first_enabled_season (enabled_mask); - } - return enabled_mask; -} - int get_current_local_season () { @@ -17945,131 +17909,164 @@ get_current_local_season () return CS_FALL; } -void -build_sprite_proxies(Map_Renderer *mr) { - if (is->cycle_imgs == NULL || is->day_night_sprite_proxy_by_season_and_hour == NULL) +char const * +get_day_night_cycle_hour_str (int hour) +{ + char const * hour_strs[24] = { + "2400", "0100", "0200", "0300", "0400", "0500", "0600", "0700", + "0800", "0900", "1000", "1100", "1200", "1300", "1400", "1500", + "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300" + }; + return hour_strs[clamp (0, 23, hour)]; +} + +void +deinit_sprite_if_needed (Sprite * sprite) +{ + if (sprite->vtable != NULL) + sprite->vtable->destruct (sprite, __, 0); +} + +void +construct_day_night_cycle_img_set (struct day_night_cycle_img_set * set) +{ + if (set == NULL) return; - int required_season_mask = get_required_season_mask_for_cycle_loading (); - int required_hour_mask = get_required_hour_mask_for_cycle_loading (); - for (int season = 0; season < COUNT_CYCLE_SEASONS; season++) { - if ((required_season_mask & (1 << season)) == 0) - continue; - for (int h = 0; h < 24; ++h) { - if ((required_hour_mask & (1 << h)) == 0) - continue; - struct day_night_cycle_img_set * set = &is->cycle_imgs[24 * season + h]; - insert_sprite_proxies(city_sprites, set->City_Images, season, h, 80); - insert_sprite_proxies(destroyed_city_sprites, set->Destroyed_City_Images, season, h, 3); - insert_sprite_proxies(mr->Resources, set->Resources, season, h, 36); - insert_spritelist_proxies(mr->Std_Terrain_Images, set->Std_Terrain_Images, season, h, 9, 81); - insert_spritelist_proxies(mr->LM_Terrain_Images, set->LM_Terrain_Images, season, h, 9, 81); - insert_sprite_proxy(&mr->Terrain_Buldings_Barbarian_Camp, &set->Terrain_Buldings_Barbarian_Camp, season, h); - insert_sprite_proxy(&mr->Terrain_Buldings_Mines, &set->Terrain_Buldings_Mines, season, h); - insert_sprite_proxy(&mr->Victory_Image, &set->Victory_Image, season, h); - insert_sprite_proxy(&mr->Terrain_Buldings_Radar, &set->Terrain_Buldings_Radar, season, h); - insert_sprite_proxies(mr->Flood_Plains_Images, set->Flood_Plains_Images, season, h, 16); - insert_sprite_proxies(mr->Polar_Icecaps_Images, set->Polar_Icecaps_Images, season, h, 32); - insert_sprite_proxies(mr->Roads_Images, set->Roads_Images, season, h, 256); - insert_sprite_proxies(mr->Railroads_Images, set->Railroads_Images, season, h, 272); - insert_sprite_proxies(mr->Terrain_Buldings_Airfields, set->Terrain_Buldings_Airfields, season, h, 2); - insert_sprite_proxies(mr->Terrain_Buldings_Camp, set->Terrain_Buldings_Camp, season, h, 4); - insert_sprite_proxies(mr->Terrain_Buldings_Fortress, set->Terrain_Buldings_Fortress, season, h, 4); - insert_sprite_proxies(mr->Terrain_Buldings_Barricade, set->Terrain_Buldings_Barricade, season, h, 4); - insert_sprite_proxies(mr->Goody_Huts_Images, set->Goody_Huts_Images, season, h, 8); - insert_sprite_proxies(mr->Terrain_Buldings_Outposts, set->Terrain_Buldings_Outposts, season, h, 3); - insert_sprite_proxies(mr->Pollution, set->Pollution, season, h, 25); - insert_sprite_proxies(mr->Craters, set->Craters, season, h, 25); - insert_sprite_proxies(mr->Tnt_Images, set->Tnt_Images, season, h, 18); - insert_sprite_proxies(mr->Waterfalls_Images, set->Waterfalls_Images, season, h, 4); - insert_sprite_proxies(mr->LM_Terrain, set->LM_Terrain, season, h, 7); - insert_sprite_proxies(mr->Marsh_Large, set->Marsh_Large, season, h, 8); - insert_sprite_proxies(mr->Marsh_Small, set->Marsh_Small, season, h, 10); - insert_sprite_proxies(mr->Volcanos_Images, set->Volcanos_Images, season, h, 16); - insert_sprite_proxies(mr->Volcanos_Forests_Images, set->Volcanos_Forests_Images, season, h, 16); - insert_sprite_proxies(mr->Volcanos_Jungles_Images, set->Volcanos_Jungles_Images, season, h, 16); - insert_sprite_proxies(mr->Volcanos_Snow_Images, set->Volcanos_Snow_Images, season, h, 16); - insert_sprite_proxies(mr->Grassland_Forests_Large, set->Grassland_Forests_Large, season, h, 8); - insert_sprite_proxies(mr->Plains_Forests_Large, set->Plains_Forests_Large, season, h, 8); - insert_sprite_proxies(mr->Tundra_Forests_Large, set->Tundra_Forests_Large, season, h, 8); - insert_sprite_proxies(mr->Grassland_Forests_Small, set->Grassland_Forests_Small, season, h, 10); - insert_sprite_proxies(mr->Plains_Forests_Small, set->Plains_Forests_Small, season, h, 10); - insert_sprite_proxies(mr->Tundra_Forests_Small, set->Tundra_Forests_Small, season, h, 10); - insert_sprite_proxies(mr->Grassland_Forests_Pines, set->Grassland_Forests_Pines, season, h, 12); - insert_sprite_proxies(mr->Plains_Forests_Pines, set->Plains_Forests_Pines, season, h, 12); - insert_sprite_proxies(mr->Tundra_Forests_Pines, set->Tundra_Forests_Pines, season, h, 12); - insert_sprite_proxies(mr->Irrigation_Desert_Images, set->Irrigation_Desert_Images, season, h, 16); - insert_sprite_proxies(mr->Irrigation_Plains_Images, set->Irrigation_Plains_Images, season, h, 16); - insert_sprite_proxies(mr->Irrigation_Images, set->Irrigation_Images, season, h, 16); - insert_sprite_proxies(mr->Irrigation_Tundra_Images, set->Irrigation_Tundra_Images, season, h, 16); - insert_sprite_proxies(mr->Grassland_Jungles_Large, set->Grassland_Jungles_Large, season, h, 8); - insert_sprite_proxies(mr->Grassland_Jungles_Small, set->Grassland_Jungles_Small, season, h, 12); - insert_sprite_proxies(mr->Mountains_Images, set->Mountains_Images, season, h, 16); - insert_sprite_proxies(mr->Mountains_Forests_Images, set->Mountains_Forests_Images, season, h, 16); - insert_sprite_proxies(mr->Mountains_Jungles_Images, set->Mountains_Jungles_Images, season, h, 16); - insert_sprite_proxies(mr->Mountains_Snow_Images, set->Mountains_Snow_Images, season, h, 16); - insert_sprite_proxies(mr->Hills_Images, set->Hills_Images, season, h, 16); - insert_sprite_proxies(mr->Hills_Forests_Images, set->Hills_Forests_Images, season, h, 16); - insert_sprite_proxies(mr->Hills_Jungle_Images, set->Hills_Jungle_Images, season, h, 16); - insert_sprite_proxies(mr->Delta_Rivers_Images, set->Delta_Rivers_Images, season, h, 16); - insert_sprite_proxies(mr->Mountain_Rivers_Images, set->Mountain_Rivers_Images, season, h, 16); - insert_sprite_proxies(mr->LM_Mountains_Images, set->LM_Mountains_Images, season, h, 16); - insert_sprite_proxies(mr->LM_Forests_Large_Images, set->LM_Forests_Large_Images, season, h, 8); - insert_sprite_proxies(mr->LM_Forests_Small_Images, set->LM_Forests_Small_Images, season, h, 10); - insert_sprite_proxies(mr->LM_Forests_Pines_Images, set->LM_Forests_Pines_Images, season, h, 12); - insert_sprite_proxies(mr->LM_Hills_Images, set->LM_Hills_Images, season, h, 16); - - if (is->current_config.enable_districts) { - for (int dc = 0; dc < is->district_count; dc++) { - struct district_config const * cfg = &is->district_configs[dc]; - int variant_capacity = ARRAY_LEN (is->district_img_sets[dc].imgs); - int variant_count = cfg->img_path_count; - if (variant_count <= 0) - continue; - if (variant_count > variant_capacity) - variant_count = variant_capacity; + Sprite * sprites = (Sprite *)set; + int sprite_count = sizeof *set / sizeof sprites[0]; + for (int i = 0; i < sprite_count; i++) + Sprite_construct (&sprites[i]); +} - int era_count = cfg->vary_img_by_era ? 4 : 1; - int column_count = cfg->img_column_count; +void +deinit_day_night_cycle_img_set (struct day_night_cycle_img_set * set) +{ + if (set == NULL) + return; - for (int variant_i = 0; variant_i < variant_count; variant_i++) { - if ((cfg->img_paths[variant_i] == NULL) || (cfg->img_paths[variant_i][0] == '\0')) - continue; - for (int era = 0; era < era_count; era++) { - for (int col = 0; col < column_count; col++) { - Sprite * base = &is->district_img_sets[dc].imgs[variant_i][era][col]; - Sprite * proxy = &set->District_Images[dc][variant_i][era][col]; - insert_sprite_proxy (base, proxy, season, h); - } - } - } - } + Sprite * sprites = (Sprite *)set; + int sprite_count = sizeof *set / sizeof sprites[0]; + for (int i = 0; i < sprite_count; i++) + deinit_sprite_if_needed (&sprites[i]); + memset (set, 0, sizeof *set); +} - insert_sprite_proxy (&is->abandoned_district_img, &set->Abandoned_District_Image, season, h); - insert_sprite_proxy (&is->abandoned_maritime_district_img, &set->Abandoned_Maritime_District_Image, season, h); +void +build_sprite_proxies(Map_Renderer *mr) { + if (is->cycle_imgs == NULL || is->day_night_sprite_proxy_by_season_and_hour == NULL) + return; - if (is->current_config.enable_wonder_districts) { - for (int wi = 0; wi < is->wonder_district_count; wi++) { - insert_sprite_proxy (&is->wonder_district_img_sets[wi].img, &set->Wonder_District_Images[wi].img, season, h); - insert_sprite_proxy (&is->wonder_district_img_sets[wi].construct_img, &set->Wonder_District_Images[wi].construct_img, season, h); + int season = (is->current_config.seasonal_cycle_mode != SCM_OFF) ? clamp (0, 3, is->current_seasonal_cycle) : CS_SUMMER; + int h = (is->current_config.day_night_cycle_mode != DNCM_OFF) ? clamp (0, 23, is->current_day_night_cycle) : 12; + struct day_night_cycle_img_set * set = is->cycle_imgs; + + insert_sprite_proxies(city_sprites, set->City_Images, season, h, 80); + insert_sprite_proxies(destroyed_city_sprites, set->Destroyed_City_Images, season, h, 3); + insert_sprite_proxies(mr->Resources, set->Resources, season, h, 36); + insert_spritelist_proxies(mr->Std_Terrain_Images, set->Std_Terrain_Images, season, h, 9, 81); + insert_spritelist_proxies(mr->LM_Terrain_Images, set->LM_Terrain_Images, season, h, 9, 81); + insert_sprite_proxy(&mr->Terrain_Buldings_Barbarian_Camp, &set->Terrain_Buldings_Barbarian_Camp, season, h); + insert_sprite_proxy(&mr->Terrain_Buldings_Mines, &set->Terrain_Buldings_Mines, season, h); + insert_sprite_proxy(&mr->Victory_Image, &set->Victory_Image, season, h); + insert_sprite_proxy(&mr->Terrain_Buldings_Radar, &set->Terrain_Buldings_Radar, season, h); + insert_sprite_proxies(mr->Flood_Plains_Images, set->Flood_Plains_Images, season, h, 16); + insert_sprite_proxies(mr->Polar_Icecaps_Images, set->Polar_Icecaps_Images, season, h, 32); + insert_sprite_proxies(mr->Roads_Images, set->Roads_Images, season, h, 256); + insert_sprite_proxies(mr->Railroads_Images, set->Railroads_Images, season, h, 272); + insert_sprite_proxies(mr->Terrain_Buldings_Airfields, set->Terrain_Buldings_Airfields, season, h, 2); + insert_sprite_proxies(mr->Terrain_Buldings_Camp, set->Terrain_Buldings_Camp, season, h, 4); + insert_sprite_proxies(mr->Terrain_Buldings_Fortress, set->Terrain_Buldings_Fortress, season, h, 4); + insert_sprite_proxies(mr->Terrain_Buldings_Barricade, set->Terrain_Buldings_Barricade, season, h, 4); + insert_sprite_proxies(mr->Goody_Huts_Images, set->Goody_Huts_Images, season, h, 8); + insert_sprite_proxies(mr->Terrain_Buldings_Outposts, set->Terrain_Buldings_Outposts, season, h, 3); + insert_sprite_proxies(mr->Pollution, set->Pollution, season, h, 25); + insert_sprite_proxies(mr->Craters, set->Craters, season, h, 25); + insert_sprite_proxies(mr->Tnt_Images, set->Tnt_Images, season, h, 18); + insert_sprite_proxies(mr->Waterfalls_Images, set->Waterfalls_Images, season, h, 4); + insert_sprite_proxies(mr->LM_Terrain, set->LM_Terrain, season, h, 7); + insert_sprite_proxies(mr->Marsh_Large, set->Marsh_Large, season, h, 8); + insert_sprite_proxies(mr->Marsh_Small, set->Marsh_Small, season, h, 10); + insert_sprite_proxies(mr->Volcanos_Images, set->Volcanos_Images, season, h, 16); + insert_sprite_proxies(mr->Volcanos_Forests_Images, set->Volcanos_Forests_Images, season, h, 16); + insert_sprite_proxies(mr->Volcanos_Jungles_Images, set->Volcanos_Jungles_Images, season, h, 16); + insert_sprite_proxies(mr->Volcanos_Snow_Images, set->Volcanos_Snow_Images, season, h, 16); + insert_sprite_proxies(mr->Grassland_Forests_Large, set->Grassland_Forests_Large, season, h, 8); + insert_sprite_proxies(mr->Plains_Forests_Large, set->Plains_Forests_Large, season, h, 8); + insert_sprite_proxies(mr->Tundra_Forests_Large, set->Tundra_Forests_Large, season, h, 8); + insert_sprite_proxies(mr->Grassland_Forests_Small, set->Grassland_Forests_Small, season, h, 10); + insert_sprite_proxies(mr->Plains_Forests_Small, set->Plains_Forests_Small, season, h, 10); + insert_sprite_proxies(mr->Tundra_Forests_Small, set->Tundra_Forests_Small, season, h, 10); + insert_sprite_proxies(mr->Grassland_Forests_Pines, set->Grassland_Forests_Pines, season, h, 12); + insert_sprite_proxies(mr->Plains_Forests_Pines, set->Plains_Forests_Pines, season, h, 12); + insert_sprite_proxies(mr->Tundra_Forests_Pines, set->Tundra_Forests_Pines, season, h, 12); + insert_sprite_proxies(mr->Irrigation_Desert_Images, set->Irrigation_Desert_Images, season, h, 16); + insert_sprite_proxies(mr->Irrigation_Plains_Images, set->Irrigation_Plains_Images, season, h, 16); + insert_sprite_proxies(mr->Irrigation_Images, set->Irrigation_Images, season, h, 16); + insert_sprite_proxies(mr->Irrigation_Tundra_Images, set->Irrigation_Tundra_Images, season, h, 16); + insert_sprite_proxies(mr->Grassland_Jungles_Large, set->Grassland_Jungles_Large, season, h, 8); + insert_sprite_proxies(mr->Grassland_Jungles_Small, set->Grassland_Jungles_Small, season, h, 12); + insert_sprite_proxies(mr->Mountains_Images, set->Mountains_Images, season, h, 16); + insert_sprite_proxies(mr->Mountains_Forests_Images, set->Mountains_Forests_Images, season, h, 16); + insert_sprite_proxies(mr->Mountains_Jungles_Images, set->Mountains_Jungles_Images, season, h, 16); + insert_sprite_proxies(mr->Mountains_Snow_Images, set->Mountains_Snow_Images, season, h, 16); + insert_sprite_proxies(mr->Hills_Images, set->Hills_Images, season, h, 16); + insert_sprite_proxies(mr->Hills_Forests_Images, set->Hills_Forests_Images, season, h, 16); + insert_sprite_proxies(mr->Hills_Jungle_Images, set->Hills_Jungle_Images, season, h, 16); + insert_sprite_proxies(mr->Delta_Rivers_Images, set->Delta_Rivers_Images, season, h, 16); + insert_sprite_proxies(mr->Mountain_Rivers_Images, set->Mountain_Rivers_Images, season, h, 16); + insert_sprite_proxies(mr->LM_Mountains_Images, set->LM_Mountains_Images, season, h, 16); + insert_sprite_proxies(mr->LM_Forests_Large_Images, set->LM_Forests_Large_Images, season, h, 8); + insert_sprite_proxies(mr->LM_Forests_Small_Images, set->LM_Forests_Small_Images, season, h, 10); + insert_sprite_proxies(mr->LM_Forests_Pines_Images, set->LM_Forests_Pines_Images, season, h, 12); + insert_sprite_proxies(mr->LM_Hills_Images, set->LM_Hills_Images, season, h, 16); - if (is->wonder_district_img_sets[wi].alt_dir_img.vtable != NULL) - insert_sprite_proxy (&is->wonder_district_img_sets[wi].alt_dir_img, &set->Wonder_District_Images[wi].alt_dir_img, season, h); - if (is->wonder_district_img_sets[wi].alt_dir_construct_img.vtable != NULL) - insert_sprite_proxy (&is->wonder_district_img_sets[wi].alt_dir_construct_img, &set->Wonder_District_Images[wi].alt_dir_construct_img, season, h); + if (is->current_config.enable_districts) { + for (int dc = 0; dc < is->district_count; dc++) { + struct district_config const * cfg = &is->district_configs[dc]; + int variant_capacity = ARRAY_LEN (is->district_img_sets[dc].imgs); + int variant_count = cfg->img_path_count; + if (variant_count <= 0) + continue; + if (variant_count > variant_capacity) + variant_count = variant_capacity; + int era_count = cfg->vary_img_by_era ? 4 : 1; + int column_count = cfg->img_column_count; + for (int variant_i = 0; variant_i < variant_count; variant_i++) { + if ((cfg->img_paths[variant_i] == NULL) || (cfg->img_paths[variant_i][0] == '\0')) + continue; + for (int era = 0; era < era_count; era++) { + for (int col = 0; col < column_count; col++) { + Sprite * base = &is->district_img_sets[dc].imgs[variant_i][era][col]; + Sprite * proxy = &set->District_Images[dc][variant_i][era][col]; + insert_sprite_proxy (base, proxy, season, h); } } } + } + + insert_sprite_proxy (&is->abandoned_district_img, &set->Abandoned_District_Image, season, h); + insert_sprite_proxy (&is->abandoned_maritime_district_img, &set->Abandoned_Maritime_District_Image, season, h); + + if (is->current_config.enable_wonder_districts) { + for (int wi = 0; wi < is->wonder_district_count; wi++) { + insert_sprite_proxy (&is->wonder_district_img_sets[wi].img, &set->Wonder_District_Images[wi].img, season, h); + insert_sprite_proxy (&is->wonder_district_img_sets[wi].construct_img, &set->Wonder_District_Images[wi].construct_img, season, h); - if (is->current_config.enable_natural_wonders && (is->natural_wonder_count > 0)) { - for (int ni = 0; ni < is->natural_wonder_count; ni++) - insert_sprite_proxy (&is->natural_wonder_img_sets[ni].img, &set->Natural_Wonder_Images[ni].img, season, h); + if (is->wonder_district_img_sets[wi].alt_dir_img.vtable != NULL) + insert_sprite_proxy (&is->wonder_district_img_sets[wi].alt_dir_img, &set->Wonder_District_Images[wi].alt_dir_img, season, h); + if (is->wonder_district_img_sets[wi].alt_dir_construct_img.vtable != NULL) + insert_sprite_proxy (&is->wonder_district_img_sets[wi].alt_dir_construct_img, &set->Wonder_District_Images[wi].alt_dir_construct_img, season, h); } } } + + if (is->current_config.enable_natural_wonders && (is->natural_wonder_count > 0)) { + for (int ni = 0; ni < is->natural_wonder_count; ni++) + insert_sprite_proxy (&is->natural_wonder_img_sets[ni].img, &set->Natural_Wonder_Images[ni].img, season, h); + } is->day_night_cycle_img_proxies_indexed = true; } - void init_day_night_and_seasonal_images() { @@ -18078,36 +18075,25 @@ init_day_night_and_seasonal_images() if (is->cycle_imgs == NULL) return; - const char *hour_strs[24] = { - "2400", "0100", "0200", "0300", "0400", "0500", "0600", "0700", - "0800", "0900", "1000", "1100", "1200", "1300", "1400", "1500", - "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300" - }; - - int required_season_mask = get_required_season_mask_for_cycle_loading (); - int required_hour_mask = get_required_hour_mask_for_cycle_loading (); - for (int season = 0; season < COUNT_CYCLE_SEASONS; season++) { - if ((required_season_mask & (1 << season)) == 0) - continue; - for (int i = 0; i < 24; i++) { - if ((required_hour_mask & (1 << i)) == 0) - continue; + int season = (is->current_config.seasonal_cycle_mode != SCM_OFF) ? clamp (0, 3, is->current_seasonal_cycle) : CS_SUMMER; + int hour = (is->current_config.day_night_cycle_mode != DNCM_OFF) ? clamp (0, 23, is->current_day_night_cycle) : 12; + char const * hour_str = get_day_night_cycle_hour_str (hour); - char art_dir[200]; - char temp_path[2*MAX_PATH]; - snprintf (art_dir, sizeof art_dir, "DayNight/%s/%s", cycle_season_names[season], hour_strs[i]); - get_mod_art_path (art_dir, temp_path, sizeof temp_path); - bool success = load_day_night_hour_and_season_images (&is->cycle_imgs[24 * season + i], temp_path, cycle_season_names[season], hour_strs[i]); + char art_dir[200]; + char temp_path[2*MAX_PATH]; + snprintf (art_dir, sizeof art_dir, "DayNight/%s/%s", cycle_season_names[season], hour_str); + get_mod_art_path (art_dir, temp_path, sizeof temp_path); + construct_day_night_cycle_img_set (is->cycle_imgs); + bool success = load_day_night_hour_and_season_images (is->cycle_imgs, temp_path, cycle_season_names[season], hour_str); - if (!success) { - char ss[300]; - snprintf (ss, sizeof ss, "Failed to load day/night cycle images for season %s at hour %s, reverting to base game art.", cycle_season_names[season], hour_strs[i]); - pop_up_in_game_error (ss); + if (!success) { + char ss[300]; + snprintf (ss, sizeof ss, "Failed to load day/night cycle images for season %s at hour %s, reverting to base game art.", cycle_season_names[season], hour_str); + pop_up_in_game_error (ss); - is->day_night_cycle_img_state = IS_INIT_FAILED; - return; - } - } + deinit_day_night_cycle_img_set (is->cycle_imgs); + is->day_night_cycle_img_state = IS_INIT_FAILED; + return; } Map_Renderer * mr = &p_bic_data->Map.Renderer; @@ -18122,12 +18108,31 @@ deindex_day_night_image_proxies() if (!is->day_night_cycle_img_proxies_indexed || is->day_night_sprite_proxy_by_season_and_hour == NULL) return; - for (int season = 0; season < COUNT_CYCLE_SEASONS; season++) - for (int i = 0; i < 24; i++) - table_deinit (&is->day_night_sprite_proxy_by_season_and_hour[24 * season + i]); + table_deinit (is->day_night_sprite_proxy_by_season_and_hour); is->day_night_cycle_img_proxies_indexed = false; } +bool +reload_current_day_night_and_seasonal_images (Map_Renderer * mr) +{ + if (! allocate_day_night_cycle_runtime_storage ()) { + is->day_night_cycle_img_state = IS_INIT_FAILED; + return false; + } + + if (is->day_night_cycle_img_proxies_indexed) + deindex_day_night_image_proxies (); + + deinit_day_night_cycle_img_set (is->cycle_imgs); + is->day_night_cycle_img_state = IS_UNINITED; + init_day_night_and_seasonal_images (); + + if ((is->day_night_cycle_img_state == IS_OK) && ! is->day_night_cycle_img_proxies_indexed) + build_sprite_proxies (mr); + + return is->day_night_cycle_img_state == IS_OK; +} + int calculate_current_seasonal_cycle (bool transition_on_day_night_hour_hit) { @@ -22295,6 +22300,9 @@ patch_load_scenario (BIC * this, int edx, char * param_1, unsigned * param_2) is->turns_in_current_season = 0; if (is->day_night_cycle_img_proxies_indexed) deindex_day_night_image_proxies (); + if (is->cycle_imgs != NULL) + deinit_day_night_cycle_img_set (is->cycle_imgs); + is->day_night_cycle_img_state = IS_UNINITED; if ((is->current_config.day_night_cycle_mode != DNCM_OFF) || (is->current_config.seasonal_cycle_mode != SCM_OFF)) { if (! allocate_day_night_cycle_runtime_storage ()) { @@ -22306,11 +22314,10 @@ patch_load_scenario (BIC * this, int edx, char * param_1, unsigned * param_2) free (is->day_night_sprite_proxy_by_season_and_hour); is->day_night_sprite_proxy_by_season_and_hour = NULL; } - if ((is->cycle_imgs != NULL) && (is->day_night_cycle_img_state != IS_OK)) { + if (is->cycle_imgs != NULL) { free (is->cycle_imgs); is->cycle_imgs = NULL; } - is->day_night_cycle_img_state = IS_UNINITED; } return tr; @@ -27426,6 +27433,8 @@ patch_perform_interturn_in_main_loop () redraw = true; } } + if (redraw && ! reload_current_day_night_and_seasonal_images (&p_bic_data->Map.Renderer)) + redraw = false; if (redraw) p_main_screen_form->vtable->m73_call_m22_Draw ((Base_Form *)p_main_screen_form); } @@ -31165,22 +31174,18 @@ patch_move_game_data (byte * buffer, bool save_else_load) // The day/night cycle sprite proxies will have been cleared in patch_load_scenario. They will not necessarily be set // up again in the usual way because Map_Renderer::load_images is not necessarily called when loading a save. The game // skips reloading all graphics when loading a save while in-game with another that uses the same graphics (possibly - // only the standard graphics; I didn't test). If day/night cycle mode is active, restore the proxies now if they - // haven't already been. - if ((is->day_night_cycle_img_state == IS_OK) && ! is->day_night_cycle_img_proxies_indexed) - build_sprite_proxies (&p_bic_data->Map.Renderer); + // only the standard graphics; I didn't test). After all mod save chunks have been read, we reload the exact saved + // hour/season art in one pass. // Because we've restored current_day_night_cycle from the save, set that is is not the first turn so the cycle // doesn't get restarted. is->day_night_cycle_unstarted = false; - + } else if (match_save_chunk_name (&cursor, "current_seasonal_cycle")) { is->current_seasonal_cycle = clamp (CS_SUMMER, CS_SPRING, *((int *)cursor)++); QueryPerformanceCounter (&is->last_seasonal_cycle_update_time); is->seasonal_cycle_unstarted = false; - if ((is->day_night_cycle_img_state == IS_OK) && ! is->day_night_cycle_img_proxies_indexed) - build_sprite_proxies (&p_bic_data->Map.Renderer); - + } else if (match_save_chunk_name (&cursor, "turns_in_current_season")) { is->turns_in_current_season = not_below (0, *((int *)cursor)++); @@ -31817,6 +31822,12 @@ patch_move_game_data (byte * buffer, bool save_else_load) free (seg); } + if ((! save_else_load) && + ((is->current_config.day_night_cycle_mode != DNCM_OFF) || + (is->current_config.seasonal_cycle_mode != SCM_OFF)) && + (is->day_night_cycle_img_state != IS_INIT_FAILED)) + reload_current_day_night_and_seasonal_images (&p_bic_data->Map.Renderer); + return tr; }