From efaeb275f78e18d594d9ee8ff04eccd2dc59512c Mon Sep 17 00:00:00 2001 From: truelight Date: Mon, 9 Aug 2004 17:04:08 +0000 Subject: (svn r1) Import of revision 975 of old (crashed) SVN --- oldloader.c | 1151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1151 insertions(+) create mode 100644 oldloader.c (limited to 'oldloader.c') diff --git a/oldloader.c b/oldloader.c new file mode 100644 index 000000000..4e1542d2a --- /dev/null +++ b/oldloader.c @@ -0,0 +1,1151 @@ +#include "stdafx.h" +#include "ttd.h" + +#include "town.h" +#include "industry.h" +#include "station.h" +#include "economy.h" +#include "player.h" +#include "engine.h" +#include "vehicle.h" + +extern byte _name_array[512][32]; +extern TileIndex _animated_tile_list[256]; + +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif + +typedef struct { + uint16 string_id; + uint16 x; + uint16 right; + uint16 y; + uint16 bottom; + uint16 duration; + uint32 params[2]; +} GCC_PACK OldTextEffect; +assert_compile(sizeof(OldTextEffect) == 0x14); + +typedef struct { + uint16 xy; + uint16 population; + uint16 townnametype; + uint32 townnameparts; + byte grow_counter; + byte sort_index; + int16 sign_left, sign_top; + byte namewidth_1, namewidth_2; + uint16 flags12; + uint16 radius[5]; + uint16 ratings[8]; + uint32 have_ratings; + uint32 statues; + uint16 num_houses; + byte time_until_rebuild; + byte growth_rate; + uint16 new_max_pass, new_max_mail; + uint16 new_act_pass, new_act_mail; + uint16 max_pass, max_mail; + uint16 act_pass, act_mail; + byte pct_pass_transported, pct_mail_transported; + uint16 new_act_food, new_act_paper; + uint16 act_food, act_paper; + byte road_build_months; + byte fund_buildings_months; + uint32 unk56; + uint32 unk5A; +} GCC_PACK OldTown; +assert_compile(sizeof(OldTown) == 0x5E); + +typedef struct { + uint16 xy; + uint32 town; +} GCC_PACK OldDepot; +assert_compile(sizeof(OldDepot) == 0x6); + +typedef struct { + uint32 price; + uint16 frac; +} GCC_PACK OldPrice; +assert_compile(sizeof(OldPrice) == 0x6); + +typedef struct { + uint32 price; + uint16 frac; + uint16 unused; +} GCC_PACK OldPaymentRate; +assert_compile(sizeof(OldPaymentRate) == 8); + +typedef struct { + uint16 waiting_acceptance; + byte days_since_pickup; + byte rating; + byte enroute_from; + byte enroute_time; + byte last_speed; + byte last_age; +} GCC_PACK OldGoodsEntry; +assert_compile(sizeof(OldGoodsEntry) == 8); + +typedef struct { + uint16 xy; + uint32 town; + uint16 bus_tile, lorry_tile, train_tile, airport_tile, dock_tile; + byte platforms; + byte alpha_order_obsolete; // alpha_order is obsolete since savegame format 4 + byte namewidth_1, namewidth_2; + uint16 string_id; + int16 sign_left, sign_top; + uint16 had_vehicle_of_type; + OldGoodsEntry goods[12]; + byte time_since_load, time_since_unload; + byte delete_ctr; + byte owner; + byte facilities; + byte airport_type; + byte truck_stop_status, bus_stop_status; + byte blocked_months; + byte unk85; + uint16 airport_flags; + uint16 last_vehicle; + uint32 unk8A; +} GCC_PACK OldStation; +assert_compile(sizeof(OldStation) == 0x8E); + +typedef struct { + uint16 xy; + uint32 town; + byte width; + byte height; + byte produced_cargo[2]; + uint16 cargo_waiting[2]; + byte production_rate[2]; + byte accepts_cargo[3]; + byte prod_level; + uint16 last_mo_production[2]; + uint16 last_mo_transported[2]; + byte pct_transported[2]; + uint16 total_production[2]; + uint16 total_transported[2]; + byte type; + byte owner; + byte color_map; + byte last_prod_year; + uint16 counter; + byte was_cargo_delivered; + byte nothing; + uint32 unk2E; + uint32 unk32; +} GCC_PACK OldIndustry; +assert_compile(sizeof(OldIndustry) == 0x36); + +typedef struct { + int32 cost[13]; +} GCC_PACK OldPlayerExpenses; +assert_compile(sizeof(OldPlayerExpenses) == 0x34); + +typedef struct { + int32 income; + int32 expenses; + uint32 delivered_cargo; + uint32 performance_history; + uint32 company_value; +} GCC_PACK OldPlayerEconomy; +assert_compile(sizeof(OldPlayerEconomy) == 0x14); + +typedef struct { + uint16 spec_tile; + uint16 use_tile; + byte rand_rng; + byte cur_rule; + byte unk6; + byte unk7; + byte buildcmd_a; + byte buildcmd_b; + byte direction; + byte cargo; + byte unused[8]; +} GCC_PACK OldAiBuildRec; +assert_compile(sizeof(OldAiBuildRec) == 0x14); + +typedef struct { + uint16 tile; + byte data; +} GCC_PACK OldAiBannedTile; +assert_compile(sizeof(OldAiBannedTile) == 3); + +typedef struct { + uint16 name_1; + uint32 name_2; + uint32 face; + uint16 pres_name_1; + uint32 pres_name_2; + uint32 money; + uint32 loan; + byte color; + byte money_fract; + byte quarters_of_bankrupcy; + byte bankrupt_asked; + uint32 bankrupt_value; + uint16 bankrupt_timeout; + uint32 cargo_types; + OldPlayerExpenses expenses[3]; + OldPlayerEconomy economy[24 + 1]; + uint16 inaugurated_date; + uint16 last_build_coordinate; + byte num_valid_stat_ent; + byte ai_state; + byte unused; + byte ai_state_mode; + uint16 ai_state_counter; + uint16 ai_timeout_counter; + OldAiBuildRec ai_src, ai_dst, ai_mid1, ai_mid2; + byte unused_2[20]; + byte ai_cargo_type; + byte ai_num_wagons; + byte ai_build_kind; + byte ai_num_build_rec; + byte ai_num_loco_to_build; + byte ai_num_want_fullload; + byte unused_3[14]; + uint16 ai_loco_id; // NOT USED + uint16 ai_wagonlist[9]; + byte ai_order_list_blocks[20]; + uint16 ai_start_tile_a; + uint16 ai_start_tile_b; + uint16 ai_cur_tile_a; + uint16 ai_cur_tile_b; + byte ai_start_dir_a; + byte ai_start_dir_b; + byte ai_cur_dir_a; + byte ai_cur_dir_b; + byte ai_banned_tile_count; + OldAiBannedTile banned_tiles[16]; + byte ai_railtype_to_use; + byte ai_route_type_mask; + byte block_preview; + byte ai_tick; + byte max_railtype; + uint16 location_of_house; + byte share_owners[4]; + uint32 unk3AA; + uint32 unk3AE; +} GCC_PACK OldPlayer; +assert_compile(sizeof(OldPlayer) == 0x3B2); + +typedef struct { + byte track; + byte force_proceed; + uint16 crash_anim_pos; + byte railtype; +} GCC_PACK OldVehicleRailUnion; +assert_compile(sizeof(OldVehicleRailUnion) == 5); + +typedef struct { + byte unk0; + byte targetairport; + uint16 crashed_counter; + byte state; +} GCC_PACK OldVehicleAirUnion; +assert_compile(sizeof(OldVehicleAirUnion) == 5); + +typedef struct { + byte state; + byte frame; + uint16 unk2; + byte overtaking; + byte overtaking_ctr; + uint16 crashed_ctr; + byte reverse_ctr; +} GCC_PACK OldVehicleRoadUnion; +assert_compile(sizeof(OldVehicleRoadUnion) == 9); + +typedef struct { + uint16 unk0; + byte unk2; +} GCC_PACK OldVehicleSpecialUnion; +assert_compile(sizeof(OldVehicleSpecialUnion) == 3); + +typedef struct { + uint16 image_override; + uint16 unk2; +} GCC_PACK OldVehicleDisasterUnion; +assert_compile(sizeof(OldVehicleDisasterUnion) == 4); + +typedef struct { + byte state; +} OldVehicleShipUnion; +assert_compile(sizeof(OldVehicleShipUnion) == 1); + +typedef union { + OldVehicleRailUnion rail; + OldVehicleAirUnion air; + OldVehicleRoadUnion road; + OldVehicleSpecialUnion special; + OldVehicleDisasterUnion disaster; + OldVehicleShipUnion ship; + byte pad[10]; +} GCC_PACK OldVehicleUnion; +assert_compile(sizeof(OldVehicleUnion) == 10); + +typedef struct { + byte type; + byte subtype; + uint16 next_hash; // NOLOAD, calculated automatically. + uint16 index; // NOLOAD, calculated automatically. + uint32 schedule_ptr; + byte next_order, next_order_param; + byte num_orders; + byte cur_order_index; + uint16 dest_tile; + uint16 load_unload_time_rem; + uint16 date_of_last_service; + uint16 service_interval; + byte last_station_visited; + byte tick_counter; + uint16 max_speed; + uint16 x_pos, y_pos; + byte z_pos; + byte direction; + byte x_offs, y_offs; + byte sprite_width, sprite_height, z_height; + byte owner; + uint16 tile; + uint16 cur_image; + + int16 left_coord, right_coord, top_coord, bottom_coord; // NOLOAD, calculated automatically. + uint16 vehstatus; + uint16 cur_speed; + byte subspeed; + byte acceleration; + byte progress; + byte cargo_type; + uint16 capacity; + uint16 number_of_pieces; + byte source_of_pieces; + byte days_in_transit; + uint16 age_in_days, max_age_in_days; + byte build_year; + byte unitnumber; + uint16 engine_type; + byte spritenum; + byte day_counter; + byte breakdowns_since_last_service; + byte breakdown_ctr, breakdown_delay, breakdown_chance; + uint16 reliability, reliability_spd_dec; + uint32 profit_this_year, profit_last_year; + uint16 next_in_chain; + uint32 value; + uint16 string_id; + OldVehicleUnion u; + byte unused[20]; +} GCC_PACK OldVehicle; +assert_compile(sizeof(OldVehicle) == 0x80); + +typedef struct { + byte name[32]; +} GCC_PACK OldName; + +typedef struct { + uint16 text; + int16 x,y,z; + byte namewidth_1, namewidth_2; + int16 sign_left, sign_top; +} GCC_PACK OldSign; +assert_compile(sizeof(OldSign) == 0xE); + +typedef struct { + uint16 player_avail; + uint16 intro_date; + uint16 age; + uint16 reliability, reliability_spd_dec, reliability_start, reliability_max, reliability_final; + uint16 duration_phase_1, duration_phase_2, duration_phase_3; + byte lifelength; + byte flags; + byte preview_player; + byte preview_wait; + byte railtype; + byte unk1B; +} GCC_PACK OldEngine; +assert_compile(sizeof(OldEngine) == 0x1C); + +typedef struct { + byte cargo_type; + byte age; + byte from; + byte to; +} GCC_PACK OldSubsidy; +assert_compile(sizeof(OldSubsidy) == 4); + +typedef struct { + uint16 max_no_competitors; + uint16 competitor_start_time; + uint16 number_towns; + uint16 number_industries; + uint16 max_loan; + uint16 initial_interest; + uint16 vehicle_costs; + uint16 competitor_speed; + uint16 competitor_intelligence; + uint16 vehicle_breakdowns; + uint16 subsidy_multiplier; + uint16 construction_cost; + uint16 terrain_type; + uint16 quantity_sea_lakes; + uint16 economy; + uint16 line_reverse_mode; + uint16 disasters; +} GCC_PACK OldGameSettings; +assert_compile(sizeof(OldGameSettings) == 0x22); + +typedef struct { + uint16 date; + uint16 date_fract; + + OldTextEffect te_list[30]; // NOLOAD: not so important. + uint32 seed_1, seed_2; + + OldTown town_list[70]; + uint16 order_list[5000]; + + uint16 animated_tile_list[256]; + uint32 ptr_to_next_order; + OldDepot depots[255]; + + uint32 cur_town_ptr; + uint16 timer_counter; + uint16 land_code; // NOLOAD: never needed in game + uint16 age_cargo_skip_counter; + uint16 tick_counter; + uint16 cur_tileloop_tile; + + OldPrice prices[49]; + OldPaymentRate cargo_payment_rates[12]; + + byte map_owner[256*256]; + byte map2[256*256]; + uint16 map3[256*256]; + byte map_extra[256*256/4]; + + OldStation stations[250]; + OldIndustry industries[90]; + OldPlayer players[8]; + OldVehicle vehicles[850]; + OldName names[500]; + + uint16 vehicle_position_hash[0x1000]; // NOLOAD, calculated automatically. + + OldSign signs[40]; + OldEngine engines[256]; + + uint16 vehicle_id_ctr_day; + OldSubsidy subsidies[8]; + + uint16 next_competitor_start; + + uint16 saved_main_scrollpos_x, saved_main_scrollpos_y, saved_main_scrollpos_zoom; + uint32 maximum_loan, maximum_loan_unround; + uint16 economy_fluct; + uint16 disaster_delay; + + //NOLOAD. These are calculated from InitializeLandscapeVariables + uint16 cargo_names_s[12], cargo_names_p[12], cargo_names_long_s[12], cargo_names_long_p[12], cargo_names_short[12]; + uint16 cargo_sprites[12]; + + uint16 engine_name_strings[256]; + + //NOLOAD. These are calculated from InitializeLandscapeVariables + uint16 railveh_by_cargo_1[12], railveh_by_cargo_2[12], railveh_by_cargo_3[12]; + uint16 roadveh_by_cargo_start[12]; + byte roadveh_by_cargo_count[12]; + uint16 ship_of_type_start[12]; + byte ship_of_type_count[12]; + + byte human_player_1, human_player_2; //NOLOAD. Calculated automatically. + byte station_tick_ctr; + byte currency; + byte use_kilometers; + byte cur_player_tick_index; + byte cur_year, cur_month; //NOLOAD. Calculated automatically. + byte player_colors[8]; //NOLOAD. Calculated automatically + + byte inflation_amount; + byte inflation_amount_payment_rates; + byte interest_rate; + + byte avail_aircraft; + byte road_side; + byte town_name_type; + OldGameSettings game_diff; + byte difficulty_level; + byte landscape_type; + byte trees_tick_ctr; + byte vehicle_design_names; + byte snow_line_height; + + byte new_industry_randtable[32]; // NOLOAD. Not needed due to different code design. + + //NOLOAD. Initialized by InitializeLandscapeVariables + byte cargo_weights[12]; + byte transit_days_table_1[12]; + byte transit_days_table_2[12]; + + byte map_type_and_height[256*256]; + byte map5[256*256]; +} GCC_PACK OldMain; +assert_compile(sizeof(OldMain) == 487801 + 256*256*2); + +#if defined(_MSC_VER) +#pragma pack(pop) +#endif + +#define REMAP_TOWN_IDX(x) (x - (0x0459154 - 0x0458EF0)) / sizeof(OldTown) +#define REMAP_TOWN_PTR(x) DEREF_TOWN( REMAP_TOWN_IDX(x) ) + +#define REMAP_ORDER_IDX(x) (x - (0x045AB08 - 0x0458EF0)) / sizeof(uint16) + +typedef struct LoadSavegameState { + int8 mode; + byte rep_char; + + size_t count; + size_t buffer_count; + FILE *fin; + + byte *buffer_cur; + + byte buffer[4096]; + +} LoadSavegameState; + +static LoadSavegameState *_cur_state; + +static byte GetSavegameByteFromBuffer() +{ + LoadSavegameState *lss = _cur_state; + + if (lss->buffer_count == 0) { + int count = fread(lss->buffer, 1, 4096, lss->fin) ; +/* if (count == 0) { + memset(lss->buffer, 0, sizeof(lss->buffer)); + count = 4096; + }*/ + assert(count != 0); + lss->buffer_count = count; + lss->buffer_cur = lss->buffer; + } + + lss->buffer_count--; + return *lss->buffer_cur++; +} + +static byte DecodeSavegameByte() +{ + LoadSavegameState *lss = _cur_state; + int8 x; + + if (lss->mode < 0) { + if (lss->count != 0) { + lss->count--; + return lss->rep_char; + } + } else if (lss->mode > 0) { + if (lss->count != 0) { + lss->count--; + return GetSavegameByteFromBuffer(); + } + } + + x = GetSavegameByteFromBuffer(); + if (x >= 0) { + lss->count = x; + lss->mode = 1; + return GetSavegameByteFromBuffer(); + } else { + lss->mode = -1; + lss->count = -x; + lss->rep_char = GetSavegameByteFromBuffer(); + return lss->rep_char; + } +} + +static void LoadSavegameBytes(void *p, size_t count) +{ + byte *ptr = (byte*)p; + assert(count > 0); + do { + *ptr++ = DecodeSavegameByte(); + } while (--count); +} + +static void FixTown(Town *t, OldTown *o, int num) +{ + do { + t->xy = o->xy; + t->population = o->population; + t->townnametype = o->townnametype; + t->townnameparts = o->townnameparts; + if (IS_INT_INSIDE(o->townnametype, 0x20C1, 0x20C2 + 1)) + t->townnametype = SPECSTR_TOWNNAME_ENGLISH; + + t->grow_counter = o->grow_counter; + t->flags12 = o->flags12; + memcpy(t->ratings,o->ratings,sizeof(t->ratings)); + t->have_ratings = o->have_ratings; + t->statues = o->statues; + t->num_houses = o->num_houses; + t->time_until_rebuild = o->time_until_rebuild; + t->growth_rate = o->growth_rate; + t->new_max_pass = o->new_max_pass; + t->new_max_mail = o->new_max_mail; + t->new_act_pass = o->new_act_pass; + t->new_act_mail = o->new_act_mail; + t->max_pass = o->max_pass; + t->max_mail = o->max_mail; + t->act_pass = o->act_pass; + t->act_mail = o->act_mail; + t->pct_pass_transported = o->pct_pass_transported; + t->pct_mail_transported = o->pct_mail_transported; + t->new_act_food = o->new_act_food; + t->new_act_paper = o->new_act_paper; + t->act_food = o->act_food; + t->act_paper = o->act_paper; + t->road_build_months = o->road_build_months; + t->fund_buildings_months = o->fund_buildings_months; + } while (t++,o++,--num); +} + +static void FixIndustry(Industry *i, OldIndustry *o, int num) +{ + do { + i->xy = o->xy; + i->town = REMAP_TOWN_PTR(o->town); + i->width = o->width; + i->height = o->height; + i->produced_cargo[0] = o->produced_cargo[0]; + i->produced_cargo[1] = o->produced_cargo[1]; + i->cargo_waiting[0] = o->cargo_waiting[0]; + i->cargo_waiting[1] = o->cargo_waiting[1]; + i->production_rate[0] = o->production_rate[0]; + i->production_rate[1] = o->production_rate[1]; + i->accepts_cargo[0] = o->accepts_cargo[0]; + i->accepts_cargo[1] = o->accepts_cargo[1]; + i->accepts_cargo[2] = o->accepts_cargo[2]; + i->prod_level = o->prod_level; + i->last_mo_production[0] = o->last_mo_production[0]; + i->last_mo_production[1] = o->last_mo_production[1]; + + i->last_mo_transported[0] = o->last_mo_transported[0]; + i->last_mo_transported[1] = o->last_mo_transported[1]; + i->last_mo_transported[2] = o->last_mo_transported[2]; + + i->pct_transported[0] = o->pct_transported[0]; + i->pct_transported[1] = o->pct_transported[1]; + + i->total_production[0] = o->total_production[0]; + i->total_production[1] = o->total_production[1]; + + i->total_transported[0] = i->total_transported[0]; + i->total_transported[1] = i->total_transported[1]; + + i->type = o->type; + i->owner = o->owner; + i->color_map = o->color_map; + i->last_prod_year = o->last_prod_year; + i->counter = o->counter; + i->was_cargo_delivered = o->was_cargo_delivered; + } while (i++,o++,--num); +} + +static void FixGoodsEntry(GoodsEntry *g, OldGoodsEntry *o, int num) +{ + do { + g->waiting_acceptance = o->waiting_acceptance; + g->days_since_pickup = o->days_since_pickup; + g->rating = o->rating; + g->enroute_from = o->enroute_from; + g->enroute_time = o->enroute_time; + g->last_speed = o->last_speed; + g->last_age = o->last_age; + } while (g++,o++,--num); +} + +static void FixStation(Station *s, OldStation *o, int num) +{ + do { + s->xy = o->xy; + s->town = REMAP_TOWN_PTR(o->town); + s->bus_tile = o->bus_tile; + s->lorry_tile = o->lorry_tile; + s->train_tile = o->train_tile; + s->airport_tile = o->airport_tile; + s->dock_tile = o->dock_tile; + + if (o->train_tile) { + int w = (o->platforms >> 3) & 0x7; + int h = (o->platforms & 0x7); + if (_map5[o->train_tile]&1) intswap(w,h); + s->trainst_w = w; + s->trainst_h = h; + } + + s->string_id = RemapOldStringID(o->string_id); + s->had_vehicle_of_type = o->had_vehicle_of_type; + FixGoodsEntry(s->goods, o->goods, lengthof(o->goods)); + s->time_since_load = o->time_since_load; + s->time_since_unload = o->time_since_unload; + s->delete_ctr = o->delete_ctr; + s->owner = o->owner; + s->facilities = o->facilities; + s->airport_type = o->airport_type; + s->truck_stop_status = o->truck_stop_status; + s->bus_stop_status = o->bus_stop_status; + s->blocked_months = o->blocked_months; + s->airport_flags = o->airport_flags; + s->last_vehicle = o->last_vehicle; + } while (s++,o++,--num); +} + +static void FixDepot(Depot *n, OldDepot *o, int num) +{ + do { + n->town_index = REMAP_TOWN_IDX(o->town); + n->xy = o->xy; + } while (n++,o++,--num); +} + +static void FixVehicle(Vehicle *n, OldVehicle *o, int num) +{ + do { + n->type = o->type; + n->subtype = o->subtype; + + if (o->schedule_ptr == 0xFFFFFFFF || o->schedule_ptr == 0) { + n->schedule_ptr = NULL; + } else { + n->schedule_ptr = _order_array + REMAP_ORDER_IDX(o->schedule_ptr); + assert(n->schedule_ptr >= _order_array && n->schedule_ptr < _ptr_to_next_order); + } + + n->next_order = o->next_order; + n->next_order_param = o->next_order_param; + n->num_orders = o->num_orders; + n->cur_order_index = o->cur_order_index; + n->dest_tile = o->dest_tile; + n->load_unload_time_rem = o->load_unload_time_rem; + n->date_of_last_service = o->date_of_last_service; + n->service_interval = o->service_interval; + n->last_station_visited = o->last_station_visited; + n->tick_counter = o->tick_counter; + n->max_speed = o->max_speed; + n->x_pos = o->x_pos; + n->y_pos = o->y_pos; + n->z_pos = o->z_pos; + n->direction = o->direction; + n->x_offs = o->x_offs; + n->y_offs = o->y_offs; + n->sprite_width = o->sprite_width; + n->sprite_height = o->sprite_height; + n->z_height = o->z_height; + n->owner = o->owner; + n->tile = o->tile; + n->cur_image = o->cur_image; + + n->vehstatus = o->vehstatus; + n->cur_speed = o->cur_speed; + n->subspeed = o->subspeed; + n->acceleration = o->acceleration; + n->progress = o->progress; + n->cargo_type = o->cargo_type; + n->cargo_cap = o->capacity; + n->cargo_count = o->number_of_pieces; + n->cargo_source = o->source_of_pieces; + n->cargo_days = o->days_in_transit; + n->age = o->age_in_days; + n->max_age = o->max_age_in_days; + n->build_year = o->build_year; + n->unitnumber = o->unitnumber; + n->engine_type = o->engine_type; + n->spritenum = o->spritenum>>1; + n->day_counter = o->day_counter; + n->breakdowns_since_last_service = o->breakdowns_since_last_service; + n->breakdown_ctr = o->breakdown_ctr; + n->breakdown_delay = o->breakdown_delay; + n->breakdown_chance = o->breakdown_chance; + n->reliability = o->reliability; + n->reliability_spd_dec = o->reliability_spd_dec; + n->profit_this_year = o->profit_this_year; + n->profit_last_year = o->profit_last_year; + n->next = o->next_in_chain == 0xffff ? NULL : &_vehicles[o->next_in_chain]; + n->value = o->value; + n->string_id = RemapOldStringID(o->string_id); + + switch(o->type) { + case VEH_Train: + n->u.rail.track = o->u.rail.track; + n->u.rail.force_proceed = o->u.rail.force_proceed; + n->u.rail.crash_anim_pos = o->u.rail.crash_anim_pos; + n->u.rail.railtype = o->u.rail.railtype; + break; + + case VEH_Road: + n->u.road.state = o->u.road.state; + n->u.road.frame = o->u.road.frame; + n->u.road.unk2 = o->u.road.unk2; + n->u.road.overtaking = o->u.road.overtaking; + n->u.road.overtaking_ctr = o->u.road.overtaking_ctr; + n->u.road.crashed_ctr = o->u.road.crashed_ctr; + n->u.road.reverse_ctr = o->u.road.reverse_ctr; + break; + case VEH_Ship: + n->u.ship.state = o->u.ship.state; + break; + case VEH_Aircraft: + n->u.air.crashed_counter = o->u.air.crashed_counter; + n->u.air.pos = o->u.air.unk0; + n->u.air.targetairport = o->u.air.targetairport; + n->u.air.state = o->u.air.state; + break; + case VEH_Special: + n->u.special.unk0 = o->u.special.unk0; + n->u.special.unk2 = o->u.special.unk2; + n->subtype = o->subtype >> 1; + break; + case VEH_Disaster: + n->u.disaster.image_override = o->u.disaster.image_override; + n->u.disaster.unk2 = o->u.disaster.unk2; + break; + } + } while (n++,o++,--num); +} + +static void FixSubsidy(Subsidy *n, OldSubsidy *o, int num) +{ + do { + n->age = o->age; + n->cargo_type = o->cargo_type; + n->from = o->from; + n->to = o->to; + } while (n++,o++,--num); +} + +static void FixEconomy(PlayerEconomyEntry *n, OldPlayerEconomy *o) +{ + n->company_value = o->company_value; + n->delivered_cargo = o->delivered_cargo; + n->income = -o->income; + n->expenses = -o->expenses; + n->performance_history = o->performance_history; +} + +static void FixAiBuildRec(AiBuildRec *n, OldAiBuildRec *o) +{ + n->spec_tile = o->spec_tile; + n->use_tile = o->use_tile; + n->rand_rng = o->rand_rng; + n->cur_building_rule = o->cur_rule; + n->unk6 = o->unk6; + n->unk7 = o->unk7; + n->buildcmd_a = o->buildcmd_a; + n->buildcmd_b = o->buildcmd_b; + n->direction = o->direction; + n->cargo = o->cargo; +} + +static void FixPlayer(Player *n, OldPlayer *o, int num) +{ + int i, j; + int x = 0; + + do { + n->name_1 = RemapOldStringID(o->name_1); + n->name_2 = o->name_2; + if (o->name_1 == 0 && x == 0) + n->name_1 = STR_SV_UNNAMED; + else + n->is_active=true; + + n->face = o->face; + n->president_name_1 = o->pres_name_1; + n->president_name_2 = o->pres_name_2; + + n->money64 = n->player_money = o->money; + n->current_loan = o->loan; + + // Correct money for scenario loading. + // It's always 893288 pounds (and no loan), if not corrected + if(o->money==0xda168) + n->money64 = n->player_money = n->current_loan =100000; + + n->player_color = o->color; + _player_colors[x] = o->color; + x++; + + n->player_money_fraction = o->money_fract; + n->quarters_of_bankrupcy = o->quarters_of_bankrupcy; + n->bankrupt_asked = o->bankrupt_asked; + n->bankrupt_value = o->bankrupt_value; + n->bankrupt_timeout = o->bankrupt_timeout; + n->cargo_types = o->cargo_types; + + for(i=0; i!=3; i++) + for(j=0; j!=13; j++) + n->yearly_expenses[i][j] = o->expenses[i].cost[j]; + + FixEconomy(&n->cur_economy, &o->economy[0]); + for(i=0; i!=24; i++) FixEconomy(&n->old_economy[i], &o->economy[i+1]); + n->inaugurated_year = o->inaugurated_date - 1920; + n->last_build_coordinate = o->last_build_coordinate; + n->num_valid_stat_ent = o->num_valid_stat_ent; + + n->ai.state = o->ai_state; + n->ai.state_mode = o->ai_state_mode; + n->ai.state_counter = o->ai_state_counter; + n->ai.timeout_counter = o->ai_timeout_counter; + n->ai.banned_tile_count = o->ai_banned_tile_count; + n->ai.railtype_to_use = o->ai_railtype_to_use; + + FixAiBuildRec(&n->ai.src, &o->ai_src); + FixAiBuildRec(&n->ai.dst, &o->ai_dst); + FixAiBuildRec(&n->ai.mid1, &o->ai_mid1); + FixAiBuildRec(&n->ai.mid2, &o->ai_mid2); + + n->ai.cargo_type = o->ai_cargo_type; + n->ai.num_wagons = o->ai_num_wagons; + n->ai.num_build_rec = o->ai_num_build_rec; + n->ai.num_loco_to_build = o->ai_num_loco_to_build; + n->ai.num_want_fullload = o->ai_num_want_fullload; + + for(i=0; i!=9; i++) n->ai.wagon_list[i] = o->ai_wagonlist[i]; + memcpy(n->ai.order_list_blocks, o->ai_order_list_blocks, 20); + n->ai.start_tile_a = o->ai_start_tile_a; + n->ai.start_tile_b = o->ai_start_tile_b; + n->ai.cur_tile_a = o->ai_cur_tile_a; + n->ai.cur_tile_b = o->ai_cur_tile_b; + n->ai.start_dir_a = o->ai_start_dir_a; + n->ai.start_dir_b = o->ai_start_dir_b; + n->ai.cur_dir_a = o->ai_cur_dir_a; + n->ai.cur_dir_b = o->ai_cur_dir_b; + + for(i=0; i!=16; i++) { + n->ai.banned_tiles[i] = o->banned_tiles[i].tile; + n->ai.banned_val[i] = o->banned_tiles[i].data; + } + + n->ai.build_kind = o->ai_build_kind; + n->ai.route_type_mask = o->ai_route_type_mask; + n->ai.tick = o->ai_tick; + + n->block_preview = o->block_preview; + n->max_railtype = (o->max_railtype == 0) ? 1 : o->max_railtype; + n->location_of_house = o->location_of_house; + if (o->location_of_house == 0xFFFF) n->location_of_house = 0; + + n->share_owners[0] = o->share_owners[0]; + n->share_owners[1] = o->share_owners[1]; + n->share_owners[2] = o->share_owners[2]; + n->share_owners[3] = o->share_owners[3]; + + if (o->ai_state == 2) { + n->ai.cur_veh = NULL; + } + } while (n++,o++,--num); +} + +static void FixName(OldName *o, int num) +{ + int i; + for(i=0; i!=num; i++) { + memcpy(_name_array[i], o[i].name, sizeof(o[i].name)); + } +} + +static void FixSign(SignStruct *n, OldSign *o, int num) +{ + do { + n->str = o->text; + n->x = o->x; + n->y = o->y; + n->z = o->z; + } while (n++,o++,--num); +} + +static void FixEngine(Engine *n, OldEngine *o, int num) +{ + int i = 0; + + do { + n->player_avail = o->player_avail; + n->intro_date = o->intro_date; + n->age = o->age; + if ((i >= 27 && i < 54) || (i >= 57 && i < 84) || (i >= 89 && i < 116)) + n->age = 0xffff; + n->reliability = o->reliability; + n->reliability_spd_dec = o->reliability_spd_dec; + n->reliability_start = o->reliability_start; + n->reliability_max = o->reliability_max; + n->reliability_final = o->reliability_final; + n->duration_phase_1 = o->duration_phase_1; + n->duration_phase_2 = o->duration_phase_2; + n->duration_phase_3 = o->duration_phase_3; + n->lifelength = o->lifelength; + n->flags = o->flags; + n->preview_player = o->preview_player; + n->preview_wait = o->preview_wait; + n->railtype = o->railtype; + } while (n++,o++,i++,--num); +} + +void FixGameDifficulty(GameDifficulty *n, OldGameSettings *o) +{ + n->max_no_competitors = o->max_no_competitors; + n->competitor_start_time = o->competitor_start_time; + n->number_towns = o->number_towns; + n->number_industries = o->number_industries; + n->max_loan = o->max_loan; + n->initial_interest = o->initial_interest; + n->vehicle_costs = o->vehicle_costs; + n->competitor_speed = o->competitor_speed; + n->competitor_intelligence = o->competitor_intelligence; + n->vehicle_breakdowns = o->vehicle_breakdowns; + n->subsidy_multiplier = o->subsidy_multiplier; + n->construction_cost = o->construction_cost; + n->terrain_type = o->terrain_type; + n->quantity_sea_lakes = o->quantity_sea_lakes; + n->economy = o->economy; + n->line_reverse_mode = o->line_reverse_mode; + n->disasters = o->disasters; +} + + +// loader for old style savegames +bool LoadOldSaveGame(const char *file) +{ + LoadSavegameState lss; + OldMain *m; + int i; + + _cur_state = &lss; + memset(&lss, 0, sizeof(lss)); + + lss.fin = fopen(file, "rb"); + if (lss.fin == NULL) return false; + + fseek(lss.fin, 49, SEEK_SET); + + // load the file into memory + m = (OldMain *)malloc(sizeof(OldMain)); + LoadSavegameBytes(m, sizeof(OldMain)); + + // copy sections of it to our datastructures. + memcpy(_map_owner, m->map_owner, sizeof(_map_owner)); + memcpy(_map2, m->map2, sizeof(_map2)); + memcpy(_map_type_and_height, m->map_type_and_height, sizeof(_map_type_and_height)); + memcpy(_map5, m->map5, sizeof(_map5)); + for(i=0; i!=256*256; i++) { + _map3_lo[i] = m->map3[i] & 0xFF; + _map3_hi[i] = m->map3[i] >> 8; + } + memcpy(_map_extra_bits, m->map_extra, sizeof(_map_extra_bits)); + + // go through the tables and see if we can find any ttdpatch presignals. Then convert those to our format. + for(i=0; i!=256*256; i++) { + if (IS_TILETYPE(i, MP_RAILWAY) && (_map5[i] & 0xC0) == 0x40) { + // this byte is always zero in real ttd. + if (_map3_hi[i]) { + // convert ttdpatch presignal format to openttd presignal format. + _map3_hi[i] = (_map3_hi[i] >> 1) & 7; + } + } + } + + memcpy(_order_array, m->order_list, sizeof(m->order_list)); + _ptr_to_next_order = _order_array + REMAP_ORDER_IDX(m->ptr_to_next_order); + + FixTown(_towns, m->town_list, lengthof(m->town_list)); + FixIndustry(_industries, m->industries, lengthof(m->industries)); + FixStation(_stations, m->stations, lengthof(m->stations)); + + FixDepot(_depots, m->depots, lengthof(m->depots)); + FixVehicle(_vehicles, m->vehicles, lengthof(m->vehicles)); + FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies)); + + FixPlayer(_players, m->players, lengthof(m->players)); + FixName(m->names, lengthof(m->names)); + FixSign(_sign_list, m->signs, lengthof(m->signs)); + FixEngine(_engines, m->engines, lengthof(m->engines)); + + _opt.diff_level = m->difficulty_level; + _opt.currency = m->currency; + _opt.kilometers = m->use_kilometers; + _opt.town_name = m->town_name_type; + _opt.landscape = m->landscape_type; + _opt.snow_line = m->snow_line_height; + _opt.autosave = 0; + _opt.road_side = m->road_side; + FixGameDifficulty(&_opt.diff, &m->game_diff); + + // Load globals + _date = m->date; + _date_fract = m->date_fract; + _tick_counter = m->tick_counter; + _vehicle_id_ctr_day = m->vehicle_id_ctr_day; + _age_cargo_skip_counter = m->age_cargo_skip_counter; + _avail_aircraft = m->avail_aircraft; + _cur_tileloop_tile = m->cur_tileloop_tile; + _disaster_delay = m->disaster_delay; + _station_tick_ctr = m->station_tick_ctr; + _random_seed_1 = m->seed_1; + _random_seed_2 = m->seed_2; + _cur_town_ctr = REMAP_TOWN_IDX(m->cur_town_ptr); + _cur_player_tick_index = m->cur_player_tick_index; + _next_competitor_start = m->next_competitor_start; + _trees_tick_ctr = m->trees_tick_ctr; + _saved_scrollpos_x = m->saved_main_scrollpos_x; + _saved_scrollpos_y = m->saved_main_scrollpos_y; + _saved_scrollpos_zoom = m->saved_main_scrollpos_zoom; + + // Load economy stuff + _economy.max_loan = m->maximum_loan; + _economy.max_loan_unround = m->maximum_loan_unround; + _economy.fluct = m->economy_fluct; + _economy.interest_rate = m->interest_rate; + _economy.infl_amount = m->inflation_amount; + _economy.infl_amount_pr = m->inflation_amount_payment_rates; + + memcpy(_animated_tile_list, m->animated_tile_list, sizeof(m->animated_tile_list)); + memcpy(_engine_name_strings, m->engine_name_strings, sizeof(m->engine_name_strings)); + + for(i=0; i!=lengthof(m->prices); i++) { + ((uint32*)&_price)[i] = m->prices[i].price; + _price_frac[i] = m->prices[i].frac; + } + + for(i=0; i!=lengthof(m->cargo_payment_rates); i++) { + _cargo_payment_rates[i] = -(int32)m->cargo_payment_rates[i].price; + _cargo_payment_rates_frac[i] = m->cargo_payment_rates[i].frac; + } + + free(m); + fclose(lss.fin); + return true; +} + +void GetOldSaveGameName(char *title, const char *file) +{ + FILE *f; + + f = fopen(file, "rb"); + title[0] = 0; + title[48] = 0; + + if (!f) return; + if (fread(title, 1, 48, f) != 48) title[0] = 0; + fclose(f); +} + +void GetOldScenarioGameName(char *title, const char *file) +{ + GetOldSaveGameName(title, file); +} -- cgit v1.2.3-54-g00ecf