From 85ba434599d675cccf21a9662422e7520dd00d19 Mon Sep 17 00:00:00 2001 From: Instafluff Date: Fri, 19 Jun 2026 09:39:07 -0700 Subject: [PATCH 1/4] Implement no-cache seasonal & day-night cycle --- injected_code.c | 419 +++++++++++++++++++++++++----------------------- 1 file changed, 215 insertions(+), 204 deletions(-) diff --git a/injected_code.c b/injected_code.c index 5b81a7ab..d02e9c2c 100644 --- a/injected_code.c +++ b/injected_code.c @@ -17332,11 +17332,13 @@ read_in_dir(PCX_Image *img, snprintf(store->S, sizeof store->S, "%s", pbuf); } - char temp_path[2*MAX_PATH]; - - snprintf(temp_path, sizeof temp_path, "%s\\%s", art_dir, filename); - PCX_Image_read_file(img, __, temp_path, NULL, 0, 0x100, 2); -} + 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); +} bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, const char *art_dir, const char *season, const char *hour) { @@ -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 +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; + + Sprite * sprites = (Sprite *)set; + int sprite_count = sizeof *set / sizeof sprites[0]; + for (int i = 0; i < sprite_count; i++) + Sprite_construct (&sprites[i]); +} + +void +deinit_day_night_cycle_img_set (struct day_night_cycle_img_set * set) +{ + if (set == NULL) + return; + + 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); +} + +void build_sprite_proxies(Map_Renderer *mr) { if (is->cycle_imgs == NULL || is->day_night_sprite_proxy_by_season_and_hour == 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; - - 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); - } - } + 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->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); + 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_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->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); + 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 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_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_str); + pop_up_in_game_error (ss); - 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; - - 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]); - - 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); - - 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; } From 5dec76f02138e0a6c9e20e81c95433d01a4b672a Mon Sep 17 00:00:00 2001 From: Instafluff Date: Fri, 19 Jun 2026 09:43:22 -0700 Subject: [PATCH 2/4] Fix line endings --- injected_code.c | 430 ++++++++++++++++++++++++------------------------ 1 file changed, 215 insertions(+), 215 deletions(-) diff --git a/injected_code.c b/injected_code.c index d02e9c2c..f2a19de0 100644 --- a/injected_code.c +++ b/injected_code.c @@ -17332,13 +17332,13 @@ read_in_dir(PCX_Image *img, snprintf(store->S, sizeof store->S, "%s", pbuf); } - 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); -} + 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); +} bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, const char *art_dir, const char *season, const char *hour) { @@ -17800,7 +17800,7 @@ get_cycle_sprite_proxy(Sprite *s) { return NULL; int v; - if (itable_look_up (is->day_night_sprite_proxy_by_season_and_hour, (int)s, &v)) + if (itable_look_up (is->day_night_sprite_proxy_by_season_and_hour, (int)s, &v)) return (Sprite *)v; return NULL; } @@ -17814,7 +17814,7 @@ insert_spritelist_proxies(SpriteList *ss, SpriteList *ps, int season, int hour, 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, (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } } @@ -17828,7 +17828,7 @@ insert_sprite_proxies(Sprite *ss, Sprite *ps, int season, int hour, int len) { Sprite *s = &ss[i]; Sprite *p = &ps[i]; if (s && p) { - itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } } @@ -17838,7 +17838,7 @@ insert_sprite_proxy(Sprite *s, Sprite *p, int season, int hour) { if (is->day_night_sprite_proxy_by_season_and_hour == NULL) return; if (s && p) { - itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); + itable_insert(is->day_night_sprite_proxy_by_season_and_hour, (int)s, (int)p); } } @@ -17846,17 +17846,17 @@ bool allocate_day_night_cycle_runtime_storage () { if (is->cycle_imgs == NULL) { - is->cycle_imgs = malloc (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, 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 (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, 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; @@ -17909,162 +17909,162 @@ get_current_local_season () return CS_FALL; } -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; - - Sprite * sprites = (Sprite *)set; - int sprite_count = sizeof *set / sizeof sprites[0]; - for (int i = 0; i < sprite_count; i++) - Sprite_construct (&sprites[i]); -} - -void -deinit_day_night_cycle_img_set (struct day_night_cycle_img_set * set) -{ - if (set == NULL) - return; - - 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); -} - -void +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; + + Sprite * sprites = (Sprite *)set; + int sprite_count = sizeof *set / sizeof sprites[0]; + for (int i = 0; i < sprite_count; i++) + Sprite_construct (&sprites[i]); +} + +void +deinit_day_night_cycle_img_set (struct day_night_cycle_img_set * set) +{ + if (set == NULL) + return; + + 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); +} + +void build_sprite_proxies(Map_Renderer *mr) { if (is->cycle_imgs == NULL || is->day_night_sprite_proxy_by_season_and_hour == NULL) return; - 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->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); + 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->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); + 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_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->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->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); - } + + 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 @@ -18075,25 +18075,25 @@ init_day_night_and_seasonal_images() if (is->cycle_imgs == NULL) return; - 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_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_str); - pop_up_in_game_error (ss); + 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_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_str); + pop_up_in_game_error (ss); - deinit_day_night_cycle_img_set (is->cycle_imgs); - 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; @@ -18108,31 +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; - table_deinit (is->day_night_sprite_proxy_by_season_and_hour); + 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; -} - +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) { @@ -22300,9 +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->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 ()) { @@ -22314,7 +22314,7 @@ 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) { + if (is->cycle_imgs != NULL) { free (is->cycle_imgs); is->cycle_imgs = NULL; } @@ -27433,8 +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 && ! 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); } @@ -31174,18 +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). After all mod save chunks have been read, we reload the exact saved - // hour/season art in one pass. + // 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; - + } else if (match_save_chunk_name (&cursor, "turns_in_current_season")) { is->turns_in_current_season = not_below (0, *((int *)cursor)++); @@ -31822,12 +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); - + 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; } From 44f0ff0c4a7fd60afd48760ddb0036c328c81d02 Mon Sep 17 00:00:00 2001 From: Instafluff Date: Mon, 22 Jun 2026 16:12:02 -0700 Subject: [PATCH 3/4] Make cycle resources dynamic, not fixed at 36 --- C3X.h | 4 +-- injected_code.c | 68 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/C3X.h b/C3X.h index 5c26c8aa..51dc1e85 100644 --- a/C3X.h +++ b/C3X.h @@ -2072,8 +2072,6 @@ struct injected_state { SpriteList LM_Terrain_Images[9]; Sprite City_Images[80]; Sprite Destroyed_City_Images[3]; - Sprite Resources[36]; - Sprite ResourcesShadows[36]; Sprite Terrain_Buldings_Barbarian_Camp; Sprite Terrain_Buldings_Mines; Sprite Victory_Image; @@ -2139,6 +2137,8 @@ struct injected_state { Sprite Abandoned_Maritime_District_Image; struct wonder_district_image_set Wonder_District_Images[MAX_WONDER_DISTRICT_TYPES]; struct natural_wonder_district_image_set Natural_Wonder_Images[MAX_NATURAL_WONDER_DISTRICT_TYPES]; + Sprite * Resources; + int ResourceCount; } * cycle_imgs; // Districts diff --git a/injected_code.c b/injected_code.c index f2a19de0..b8dfde9b 100644 --- a/injected_code.c +++ b/injected_code.c @@ -17320,7 +17320,7 @@ join_path(char *out, size_t out_sz, const char *dir, const char *file) snprintf(out, out_sz, "%s%s%s", dir, need_sep ? "\\" : "", file); } -void +void read_in_dir(PCX_Image *img, const char *art_dir, const char *filename, @@ -17340,6 +17340,25 @@ read_in_dir(PCX_Image *img, PCX_Image_read_file(img, __, temp_path, NULL, 0, 0x100, 2); } +bool +construct_cycle_sprite_array (Sprite ** out_sprites, int count) +{ + *out_sprites = NULL; + if (count <= 0) + return true; + + Sprite * sprites = malloc (count * sizeof sprites[0]); + if (sprites == NULL) + return false; + + memset (sprites, 0, count * sizeof sprites[0]); + for (int i = 0; i < count; i++) + Sprite_construct (&sprites[i]); + + *out_sprites = sprites; + return true; +} + bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, const char *art_dir, const char *season, const char *hour) { char ss[200]; @@ -17574,15 +17593,22 @@ bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, if (img.JGL.Image == NULL) return false; Sprite_slice_pcx(&this->Victory_Image, __, &img, 0, 0, 0x80, 0x40, 1, 1); - // Resources - read_in_dir(&img, art_dir, "resources.pcx", NULL); + // Resources + read_in_dir(&img, art_dir, "resources.pcx", NULL); if (img.JGL.Image == NULL) return false; - size_t k = 0; - for (int r = 0, y = 1; r < 6; ++r, y += 50) { - for (int c = 0, x = 1; c < 6; ++c, x += 50) { - Sprite_slice_pcx(&this->Resources[k++], __, &img, x, y, 49, 49, 1, 1); - } - } + int resource_cols = img.JGL.Image->vtable->m54_Get_Width (img.JGL.Image) / 50; + int resource_rows = img.JGL.Image->vtable->m55_Get_Height (img.JGL.Image) / 50; + int resource_count = resource_cols * resource_rows; + if ((resource_cols <= 0) || (resource_rows <= 0) || + ! construct_cycle_sprite_array (&this->Resources, resource_count)) + return false; + this->ResourceCount = resource_count; + int k = 0; + for (int r = 0, y = 1; r < resource_rows; ++r, y += 50) { + for (int c = 0, x = 1; c < resource_cols; ++c, x += 50) { + Sprite_slice_pcx(&this->Resources[k++], __, &img, x, y, 49, 49, 1, 1); + } + } // Base cities static const char *CITY_BASE[5] = { @@ -17927,6 +17953,18 @@ deinit_sprite_if_needed (Sprite * sprite) sprite->vtable->destruct (sprite, __, 0); } +void +deinit_cycle_sprite_array (Sprite ** sprites, int count) +{ + if (*sprites == NULL) + return; + + for (int i = 0; i < count; i++) + deinit_sprite_if_needed (&(*sprites)[i]); + free (*sprites); + *sprites = NULL; +} + void construct_day_night_cycle_img_set (struct day_night_cycle_img_set * set) { @@ -17934,7 +17972,7 @@ construct_day_night_cycle_img_set (struct day_night_cycle_img_set * set) return; Sprite * sprites = (Sprite *)set; - int sprite_count = sizeof *set / sizeof sprites[0]; + int sprite_count = (int)(((char *)&set->Resources - (char *)set) / sizeof sprites[0]); for (int i = 0; i < sprite_count; i++) Sprite_construct (&sprites[i]); } @@ -17946,9 +17984,10 @@ deinit_day_night_cycle_img_set (struct day_night_cycle_img_set * set) return; Sprite * sprites = (Sprite *)set; - int sprite_count = sizeof *set / sizeof sprites[0]; + int sprite_count = (int)(((char *)&set->Resources - (char *)set) / sizeof sprites[0]); for (int i = 0; i < sprite_count; i++) deinit_sprite_if_needed (&sprites[i]); + deinit_cycle_sprite_array (&set->Resources, set->ResourceCount); memset (set, 0, sizeof *set); } @@ -17963,7 +18002,12 @@ build_sprite_proxies(Map_Renderer *mr) { 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); + if ((mr->Resources != NULL) && (set->Resources != NULL)) { + int resource_count = ((int *)mr->Resources)[-1]; + if (resource_count > set->ResourceCount) + resource_count = set->ResourceCount; + insert_sprite_proxies(mr->Resources, set->Resources, season, h, resource_count); + } 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); From 3e6eb3a1f6a5fe8e06e79823ce691ebc3d6a132f Mon Sep 17 00:00:00 2001 From: Instafluff Date: Thu, 25 Jun 2026 07:54:23 -0700 Subject: [PATCH 4/4] Fix day-night/seasonal cycle parser to handle tall wonder districts; Double allowed num of wonder districts & natural wonders --- C3X.h | 4 ++-- injected_code.c | 26 ++++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/C3X.h b/C3X.h index 51dc1e85..b2b3f1be 100644 --- a/C3X.h +++ b/C3X.h @@ -20,8 +20,8 @@ typedef unsigned char byte; #define USED_SPECIAL_DISTRICT_TYPES 11 #define MAX_DYNAMIC_DISTRICT_TYPES 22 #define COUNT_DISTRICT_TYPES (COUNT_SPECIAL_DISTRICT_TYPES + MAX_DYNAMIC_DISTRICT_TYPES) -#define MAX_WONDER_DISTRICT_TYPES 32 -#define MAX_NATURAL_WONDER_DISTRICT_TYPES 32 +#define MAX_WONDER_DISTRICT_TYPES 64 +#define MAX_NATURAL_WONDER_DISTRICT_TYPES 64 #define MAX_DISTRICT_VARIANT_COUNT 5 #define MAX_DISTRICT_ERA_COUNT 4 #define MAX_DISTRICT_COLUMN_COUNT 10 diff --git a/injected_code.c b/injected_code.c index b8dfde9b..14fbef53 100644 --- a/injected_code.c +++ b/injected_code.c @@ -17715,6 +17715,8 @@ bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, char const * img_path = cfg->img_path; if (img_path == NULL) img_path = "Wonders.pcx"; + int sprite_width = (cfg->custom_width > 0) ? cfg->custom_width : 128; + int sprite_height = (cfg->custom_height > 0) ? cfg->custom_height : 64; // Load new image file if different from previous if ((last_img_path == NULL) || (strcmp (img_path, last_img_path) != 0)) { @@ -17738,25 +17740,25 @@ bool load_day_night_hour_and_season_images(struct day_night_cycle_img_set *this, struct wonder_district_image_set * set = &this->Wonder_District_Images[wi]; Sprite_construct (&set->img); - int x = 128 * cfg->img_column; - int y = 64 * cfg->img_row; - Sprite_slice_pcx (&set->img, __, &wpcx, x, y, 128, 64, 1, 1); + int x = sprite_width * cfg->img_column; + int y = sprite_height * cfg->img_row; + Sprite_slice_pcx (&set->img, __, &wpcx, x, y, sprite_width, sprite_height, 1, 1); Sprite_construct (&set->construct_img); - int cx = 128 * cfg->img_construct_column; - int cy = 64 * cfg->img_construct_row; - Sprite_slice_pcx (&set->construct_img, __, &wpcx, cx, cy, 128, 64, 1, 1); + int cx = sprite_width * cfg->img_construct_column; + int cy = sprite_height * cfg->img_construct_row; + Sprite_slice_pcx (&set->construct_img, __, &wpcx, cx, cy, sprite_width, sprite_height, 1, 1); if (cfg->enable_img_alt_dir) { Sprite_construct (&set->alt_dir_img); - int ax = 128 * cfg->img_alt_dir_column; - int ay = 64 * cfg->img_alt_dir_row; - Sprite_slice_pcx (&set->alt_dir_img, __, &wpcx, ax, ay, 128, 64, 1, 1); + int ax = sprite_width * cfg->img_alt_dir_column; + int ay = sprite_height * cfg->img_alt_dir_row; + Sprite_slice_pcx (&set->alt_dir_img, __, &wpcx, ax, ay, sprite_width, sprite_height, 1, 1); Sprite_construct (&set->alt_dir_construct_img); - int acx = 128 * cfg->img_alt_dir_construct_column; - int acy = 64 * cfg->img_alt_dir_construct_row; - Sprite_slice_pcx (&set->alt_dir_construct_img, __, &wpcx, acx, acy, 128, 64, 1, 1); + int acx = sprite_width * cfg->img_alt_dir_construct_column; + int acy = sprite_height * cfg->img_alt_dir_construct_row; + Sprite_slice_pcx (&set->alt_dir_construct_img, __, &wpcx, acx, acy, sprite_width, sprite_height, 1, 1); } }