Changeset - r3626:e3e02bed72be
[Not reviewed]
master
0 1 0
Darkvater - 18 years ago 2006-04-22 12:53:35
darkvater@openttd.org
(svn r4525) - Codechange: Do a little cleanup; also fix a typo while here: _old_vehicle_multipler should be _old_vehicle_multiplier
1 file changed with 52 insertions and 51 deletions:
0 comments (0 inline, 0 general)
oldloader.c
Show inline comments
 
@@ -157,48 +157,41 @@ static byte ReadByte(LoadgameState *ls)
 
 */
 
static bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
 
{
 
	const OldChunks *chunk = chunks;
 
	byte *ptr;
 
	byte *base_ptr = base;
 
	uint i;
 

	
 
	while (chunk->type != OC_END) {
 
		ptr = chunk->ptr;
 

	
 
		for (i = 0; i < chunk->amount; i++) {
 
			if (ls->failed)
 
				return false;
 
			if (ls->failed) return false;
 

	
 
			/* Handle simple types */
 
			if ((chunk->type & 0xFF) != 0) {
 
				switch (chunk->type & 0xFF) {
 
					case OC_NULL:
 
						/* Just read the byte and forget about it */
 
						ReadByte(ls);
 
						break;
 
					/* Just read the byte and forget about it */
 
					case OC_NULL: ReadByte(ls); break;
 

	
 
					case OC_CHUNK:
 
						/* Call function, with 'i' as parameter to tell which item we
 
						 * are going to read */
 
						if (!chunk->proc(ls, i)) return false;
 
						break;
 

	
 
					case OC_ASSERT:
 
						DEBUG(oldloader, 4)("[OldLoader] Assert point: %x / %x", ls->total_read, chunk->offset + _bump_assert_value);
 
						if (ls->total_read != chunk->offset + _bump_assert_value) {
 
							ls->failed = true;
 
						}
 
						break;
 

	
 
						if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
 
				}
 
			} else {
 
				uint32 res = 0;
 

	
 
				/* Reading from the file: bit 16 to 23 have the FILE */
 
				switch (GB(chunk->type, 16, 8) << 16) {
 
					case OC_FILE_I8:
 
						res = ReadByte(ls);
 
						res = (int8)res;
 
						break;
 

	
 
					case OC_FILE_U8:
 
@@ -386,25 +379,25 @@ static void FixOldStations(void)
 
			st->truck_stops->prev = NULL;
 
			st->truck_stops->num_vehicles = 0;
 
		}
 
	}
 
}
 

	
 
static void FixOldVehicles(void)
 
{
 
	/* Check for shared orders, and link them correctly */
 
	Vehicle* v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		Vehicle* u;
 
		Vehicle *u;
 

	
 
		if (v->type == 0) continue;
 

	
 
		FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
 
			if (u->type == 0) continue;
 

	
 
			/* If a vehicle has the same orders, add the link to eachother
 
			 * in both vehicles */
 
			if (v->orders == u->orders) {
 
				v->next_shared = u;
 
				u->prev_shared = v;
 
				break;
 
@@ -436,63 +429,63 @@ static void FixOldVehicles(void)
 

	
 
/* The savegames has some hard-coded pointers, because it always enters the same
 
    piece of memory.. we don't.. so we need to remap ;)
 
   Old Towns are 94 bytes big
 
   Old Orders are 2 bytes big */
 
#define REMAP_TOWN_IDX(x) ((x) - (0x0459154 - 0x0458EF0)) / 94
 
#define REMAP_ORDER_IDX(x) ((x) - (0x045AB08 - 0x0458EF0)) / 2
 

	
 
extern TileIndex _animated_tile_list[256];
 
extern char _name_array[512][32];
 
extern uint16 _custom_sprites_base;
 

	
 
static byte   _old_vehicle_multipler;
 
static byte   _old_vehicle_multiplier;
 
static uint8  _old_map3[OLD_MAP_SIZE * 2];
 
static bool   _new_ttdpatch_format;
 
static uint32 _old_town_index;
 
static uint16 _old_string_id;
 
static uint16 _old_string_id_2;
 

	
 
static void ReadTTDPatchFlags(void)
 
{
 
	int i;
 

	
 
	if (_read_ttdpatch_flags) return;
 

	
 
	_read_ttdpatch_flags = true;
 

	
 
	/* TTDPatch misuses _old_map3 for flags.. read them! */
 
	_old_vehicle_multipler = _old_map3[0];
 
	_old_vehicle_multiplier = _old_map3[0];
 
	/* Somehow.... there was an error in some savegames, so 0 becomes 1
 
	and 1 becomes 2. The rest of the values are okay */
 
	if (_old_vehicle_multipler < 2) _old_vehicle_multipler++;
 
	if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
 

	
 
	/* TTDPatch incraeses the Vehicle-part in the middle of the game,
 
	so if the multipler is anything else but 1, the assert fails..
 
	bump the assert value so it doesn't!
 
	(1 multipler == 850 vehicles
 
	1 vehicle   == 128 bytes */
 
	_bump_assert_value = (_old_vehicle_multipler - 1) * 850 * 128;
 
	_bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
 

	
 
	/* Check if we have a modern TTDPatch savegame (has extra data all around) */
 
	_new_ttdpatch_format = (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0);
 

	
 
	/* Clean the misused places */
 
	for (i = 0;       i < 17;      i++) _old_map3[i] = 0;
 
	for (i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
 

	
 
	if (_new_ttdpatch_format)
 
		DEBUG(oldloader, 1)("[OldLoader] Found TTDPatch game");
 

	
 
	DEBUG(oldloader, 1)("[OldLoader] Vehicle-multipler is set to %d (%d vehicles)", _old_vehicle_multipler, _old_vehicle_multipler * 850);
 
	DEBUG(oldloader, 1)("[OldLoader] Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
 
}
 

	
 
static const OldChunks town_chunk[] = {
 
	OCL_SVAR(   OC_TILE, Town, xy ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, population ),
 
	OCL_SVAR( OC_UINT16, Town, townnametype ),
 
	OCL_SVAR( OC_UINT32, Town, townnameparts ),
 
	OCL_SVAR(  OC_UINT8, Town, grow_counter ),
 
	OCL_NULL( 1 ),         // sort_index,        no longer in use
 
	OCL_NULL( 4 ),         // sign-coordinates,  no longer in use
 
	OCL_NULL( 2 ),         // namewidth,         no longer in use
 
	OCL_SVAR( OC_UINT16, Town, flags12 ),
 
@@ -543,115 +536,116 @@ static bool LoadOldTown(LoadgameState *l
 
{
 
	if (!AddBlockIfNeeded(&_town_pool, num))
 
		error("Towns: failed loading savegame: too many towns");
 

	
 
	return LoadChunk(ls, GetTown(num), town_chunk);
 
}
 

	
 
static uint16 _old_order;
 
static const OldChunks order_chunk[] = {
 
	OCL_VAR ( OC_UINT16,   1, &_old_order ),
 
	OCL_END()
 
};
 

	
 
static bool LoadOldOrder(LoadgameState *ls, int num)
 
{
 
	if (!AddBlockIfNeeded(&_order_pool, num))
 
		error("Orders: failed loading savegame: too many orders");
 

	
 
	if (!LoadChunk(ls, NULL, order_chunk))
 
		return false;
 
	if (!LoadChunk(ls, NULL, order_chunk)) return false;
 

	
 
	AssignOrder(GetOrder(num), UnpackOldOrder(_old_order));
 

	
 
	/* Relink the orders to eachother (in TTD(Patch) the orders for one
 
	vehicle are behind eachother, with OT_NOTHING as indication that
 
	it is the last order */
 
	if (num > 0 && GetOrder(num)->type != OT_NOTHING)
 
		GetOrder(num - 1)->next = GetOrder(num);
 

	
 
	return true;
 
}
 

	
 
static const OldChunks depot_chunk[] = {
 
	OCL_SVAR(   OC_TILE, Depot, xy ),
 
	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
 
	OCL_END()
 
};
 

	
 
static bool LoadOldDepot(LoadgameState *ls, int num)
 
{
 
	if (!AddBlockIfNeeded(&_depot_pool, num))
 
		error("Depots: failed loading savegame: too many depots");
 

	
 
	if (!LoadChunk(ls, GetDepot(num), depot_chunk))
 
		return false;
 
	if (!LoadChunk(ls, GetDepot(num), depot_chunk)) return false;
 

	
 
	if (GetDepot(num)->xy != 0) {
 
		GetDepot(num)->town_index = REMAP_TOWN_IDX(_old_town_index);
 
	}
 

	
 
	return true;
 
}
 

	
 
static int32 _old_price;
 
static uint16 _old_price_frac;
 
static const OldChunks price_chunk[] = {
 
	OCL_VAR (  OC_INT32,   1, &_old_price ),
 
	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
 
	OCL_END()
 
};
 

	
 
static bool LoadOldPrice(LoadgameState *ls, int num)
 
{
 
	if (!LoadChunk(ls, NULL, price_chunk))
 
		return false;
 
	if (!LoadChunk(ls, NULL, price_chunk)) return false;
 

	
 
	/* We use a struct to store the prices, but they are ints in a row..
 
	so just access the struct as an array of int32's */
 
	((int32*)&_price)[num] = _old_price;
 
	_price_frac[num] = _old_price_frac;
 

	
 
	return true;
 
}
 

	
 
static const OldChunks cargo_payment_rate_chunk[] = {
 
	OCL_VAR (  OC_INT32,   1, &_old_price ),
 
	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
 

	
 
	OCL_NULL( 2 ),         // Junk
 
	OCL_END()
 
};
 

	
 
static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
 
{
 
	if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk))
 
		return false;
 
	if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
 

	
 
	_cargo_payment_rates[num] = -_old_price;
 
	_cargo_payment_rates_frac[num] = _old_price_frac;
 

	
 
	return true;
 
}
 

	
 
static uint8 _old_platforms;
 
static uint _current_station_id;
 

	
 
static const OldChunks goods_chunk[] = {
 
	OCL_SVAR( OC_UINT16, GoodsEntry, waiting_acceptance ),
 
	OCL_SVAR(  OC_UINT8, GoodsEntry, days_since_pickup ),
 
	OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, GoodsEntry, enroute_from ),
 
	OCL_SVAR(  OC_UINT8, GoodsEntry, enroute_time ),
 
	OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
 
	OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldGood(LoadgameState *ls, int num)
 
{
 
	Station *st = GetStation(_current_station_id);
 
	return LoadChunk(ls, &st->goods[num], goods_chunk);
 
}
 

	
 
static const OldChunks station_chunk[] = {
 
	OCL_SVAR(   OC_TILE, Station, xy ),
 
	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
 

	
 
	OCL_SVAR(   OC_TILE, Station, bus_tile_obsolete ),
 
	OCL_SVAR(   OC_TILE, Station, lorry_tile_obsolete ),
 
@@ -752,113 +746,113 @@ static const OldChunks industry_chunk[] 
 

	
 
	OCL_SVAR(  OC_UINT8, Industry, type ),
 
	OCL_SVAR(  OC_UINT8, Industry, owner ),
 
	OCL_SVAR(  OC_UINT8, Industry, color_map ),
 
	OCL_SVAR(  OC_UINT8, Industry, last_prod_year ),
 
	OCL_SVAR( OC_UINT16, Industry, counter ),
 
	OCL_SVAR(  OC_UINT8, Industry, was_cargo_delivered ),
 

	
 
	OCL_NULL( 9 ), // Random junk at the end of this chunk
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldIndustry(LoadgameState *ls, int num)
 
{
 
	Industry *i;
 

	
 
	if (!AddBlockIfNeeded(&_industry_pool, num))
 
		error("Industries: failed loading savegame: too many industries");
 

	
 
	i = GetIndustry(num);
 
	if (!LoadChunk(ls, i, industry_chunk))
 
		return false;
 
	if (!LoadChunk(ls, i, industry_chunk)) return false;
 

	
 
	if (i->xy != 0) {
 
		i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
 
	}
 

	
 
	return true;
 
}
 

	
 
static PlayerID _current_player_id;
 
static uint16 _old_inaugurated_year;
 
static int32 _old_yearly;
 

	
 
static const OldChunks player_yearly_chunk[] = {
 
	OCL_VAR(  OC_INT32,   1, &_old_yearly ),
 
	OCL_END()
 
};
 

	
 
static bool OldPlayerYearly(LoadgameState *ls, int num)
 
{
 
	int i;
 
	Player *p = GetPlayer(_current_player_id);
 

	
 
	for (i = 0; i < 13; i++) {
 
		if (!LoadChunk(ls, NULL, player_yearly_chunk))
 
			return false;
 
		if (!LoadChunk(ls, NULL, player_yearly_chunk)) return false;
 

	
 
		p->yearly_expenses[num][i] = _old_yearly;
 
	}
 

	
 
	return true;
 
}
 

	
 
static const OldChunks player_economy_chunk[] = {
 
	OCL_SVAR( OC_INT32, PlayerEconomyEntry, income ),
 
	OCL_SVAR( OC_INT32, PlayerEconomyEntry, expenses ),
 
	OCL_SVAR( OC_INT32, PlayerEconomyEntry, delivered_cargo ),
 
	OCL_SVAR( OC_INT32, PlayerEconomyEntry, performance_history ),
 
	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, PlayerEconomyEntry, company_value ),
 

	
 
	OCL_END()
 
};
 

	
 
static bool OldPlayerEconomy(LoadgameState *ls, int num)
 
{
 
	int i;
 
	Player *p = GetPlayer(_current_player_id);
 

	
 
	if (!LoadChunk(ls, &p->cur_economy, player_economy_chunk))
 
		return false;
 
	if (!LoadChunk(ls, &p->cur_economy, player_economy_chunk)) return false;
 

	
 
	/* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
 
	p->cur_economy.income   = -p->cur_economy.income;
 
	p->cur_economy.expenses = -p->cur_economy.expenses;
 

	
 
	for (i = 0; i < 24; i++) {
 
		if (!LoadChunk(ls, &p->old_economy[i], player_economy_chunk))
 
			return false;
 
		if (!LoadChunk(ls, &p->old_economy[i], player_economy_chunk)) return false;
 

	
 
		p->old_economy[i].income   = -p->old_economy[i].income;
 
		p->old_economy[i].expenses = -p->old_economy[i].expenses;
 
	}
 

	
 
	return true;
 
}
 

	
 
static const OldChunks player_ai_build_rec_chunk[] = {
 
	OCL_SVAR(   OC_TILE, AiBuildRec, spec_tile ),
 
	OCL_SVAR(   OC_TILE, AiBuildRec, use_tile ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, rand_rng ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, cur_building_rule ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, unk6 ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, unk7 ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_a ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_b ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, direction ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, cargo ),
 

	
 
	OCL_NULL( 8 ),  // Junk...
 

	
 
	OCL_END()
 
};
 

	
 
static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
 
{
 
	Player *p = GetPlayer(_current_player_id);
 

	
 
	switch (num) {
 
		case 0: return LoadChunk(ls, &p->ai.src, player_ai_build_rec_chunk);
 
		case 1: return LoadChunk(ls, &p->ai.dst, player_ai_build_rec_chunk);
 
		case 2: return LoadChunk(ls, &p->ai.mid1, player_ai_build_rec_chunk);
 
		case 3: return LoadChunk(ls, &p->ai.mid2, player_ai_build_rec_chunk);
 
	}
 

	
 
	return false;
 
@@ -956,24 +950,25 @@ static const OldChunks player_ai_chunk[]
 
	OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[13] ),
 
	OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[13] ),
 
	OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[14] ),
 
	OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[14] ),
 
	OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[15] ),
 
	OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[15] ),
 

	
 
	OCL_SVAR(  OC_UINT8, PlayerAI, railtype_to_use ),
 
	OCL_SVAR(  OC_UINT8, PlayerAI, route_type_mask ),
 

	
 
	OCL_END()
 
};
 

	
 
static bool OldPlayerAI(LoadgameState *ls, int num)
 
{
 
	Player *p = GetPlayer(_current_player_id);
 

	
 
	return LoadChunk(ls, &p->ai, player_ai_chunk);
 
}
 

	
 
static const OldChunks player_chunk[] = {
 
	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
 
	OCL_SVAR( OC_UINT32, Player, name_2 ),
 
	OCL_SVAR( OC_UINT32, Player, face ),
 
	OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
 
@@ -1011,26 +1006,25 @@ static const OldChunks player_chunk[] = 
 

	
 
	OCL_NULL( 8 ), // junk at end of chunk
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldPlayer(LoadgameState *ls, int num)
 
{
 
	Player *p = GetPlayer(num);
 

	
 
	_current_player_id = num;
 

	
 
	if (!LoadChunk(ls, p, player_chunk))
 
		return false;
 
	if (!LoadChunk(ls, p, player_chunk)) return false;
 

	
 
	p->name_1 = RemapOldStringID(_old_string_id);
 
	p->president_name_1 = RemapOldStringID(_old_string_id_2);
 
	p->money64 = p->player_money;
 

	
 
	if (num == 0) {
 
		/* If the first player has no name, make sure we call it UNNAMED */
 
		if (p->name_1 == 0)
 
			p->name_1 = STR_SV_UNNAMED;
 
	} else {
 
		/* Beside some multiplayer maps (1 on 1), which we don't official support,
 
		all other players are an AI.. mark them as such */
 
@@ -1067,75 +1061,82 @@ static uint16 _old_next_ptr;
 
static uint32 _current_vehicle_id;
 

	
 
static const OldChunks vehicle_train_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleRail, track ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
 
	OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
 

	
 
	OCL_NULL( 5 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_road_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, state ),
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, frame ),
 
	OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking ),
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking_ctr ),
 
	OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
 
	OCL_SVAR(  OC_UINT8, VehicleRoad, reverse_ctr ),
 

	
 
	OCL_NULL( 1 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_ship_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleShip, state ),
 

	
 
	OCL_NULL( 9 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_air_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleAir, pos ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
 
	OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
 
	OCL_SVAR(  OC_UINT8, VehicleAir, state ),
 

	
 
	OCL_NULL( 5 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_special_chunk[] = {
 
	OCL_SVAR( OC_UINT16, VehicleSpecial, unk0 ),
 
	OCL_SVAR(  OC_UINT8, VehicleSpecial, unk2 ),
 

	
 
	OCL_NULL( 7 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_disaster_chunk[] = {
 
	OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
 
	OCL_SVAR( OC_UINT16, VehicleDisaster, unk2 ),
 

	
 
	OCL_NULL( 6 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static const OldChunks vehicle_empty_chunk[] = {
 
	OCL_NULL( 10 ), // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
 
{
 
	Vehicle *v = GetVehicle(_current_vehicle_id);
 
	uint temp = ls->total_read;
 
	bool res;
 

	
 
	switch (v->type) {
 
		case VEH_Train:    res = LoadChunk(ls, &v->u.rail,     vehicle_train_chunk);    break;
 
		case VEH_Road:     res = LoadChunk(ls, &v->u.road,     vehicle_road_chunk);     break;
 
		case VEH_Ship:     res = LoadChunk(ls, &v->u.ship,     vehicle_ship_chunk);     break;
 
		case VEH_Aircraft: res = LoadChunk(ls, &v->u.air,      vehicle_air_chunk);      break;
 
		case VEH_Special:  res = LoadChunk(ls, &v->u.special,  vehicle_special_chunk);  break;
 
@@ -1224,42 +1225,42 @@ static const OldChunks vehicle_chunk[] =
 
	OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
 

	
 
	OCL_SVAR( OC_UINT32, Vehicle, value ),
 

	
 
	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
 

	
 
	OCL_CHUNK( 1, LoadOldVehicleUnion ),
 

	
 
	OCL_NULL( 20 ), // Junk at end of struct (TTDPatch has some data in it)
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldVehicle(LoadgameState *ls, int num)
 
{
 
	uint i;
 

	
 
	/* Read the TTDPatch flags, because we need some info from it */
 
	ReadTTDPatchFlags();
 

	
 
	for (i = 0; i < _old_vehicle_multipler; i++) {
 
	for (i = 0; i < _old_vehicle_multiplier; i++) {
 
		Vehicle *v;
 

	
 
		_current_vehicle_id = num * _old_vehicle_multipler + i;
 
		_current_vehicle_id = num * _old_vehicle_multiplier + i;
 

	
 
		if (!AddBlockIfNeeded(&_vehicle_pool, _current_vehicle_id))
 
			error("Vehicles: failed loading savegame: too many vehicles");
 

	
 
		v = GetVehicle(_current_vehicle_id);
 
		if (!LoadChunk(ls, v, vehicle_chunk))
 
			return false;
 
		if (!LoadChunk(ls, v, vehicle_chunk)) return false;
 

	
 
		/* This should be consistent, else we have a big problem... */
 
		if (v->index != _current_vehicle_id) {
 
			DEBUG(oldloader, 0)("[OldLoader] -- Loading failed - vehicle-array is invalid");
 
			return false;
 
		}
 

	
 
		if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
 
			v->orders = GetOrder(REMAP_ORDER_IDX(_old_order_ptr));
 
		}
 
		AssignOrder(&v->current_order, UnpackOldOrder(_old_order));
 
		/* TTDPatch maps sprites from 0x2000 up. */
 
@@ -1270,41 +1271,41 @@ static bool LoadOldVehicle(LoadgameState
 
		switch (v->spritenum) {
 
			case 0xfd: break;
 
			case 0xff: v->spritenum = 0xfe; break;
 
			default:   v->spritenum >>= 1; break;
 
		}
 

	
 
		if (_old_next_ptr != 0xFFFF)
 
			v->next = GetVehicle(_old_next_ptr);
 

	
 
		v->string_id = RemapOldStringID(_old_string_id);
 

	
 
		/* Vehicle-subtype is different in TTD(Patch) */
 
		if (v->type == VEH_Special)
 
			v->subtype = v->subtype >> 1;
 
		if (v->type == VEH_Special) v->subtype = v->subtype >> 1;
 
	}
 

	
 
	return true;
 
}
 

	
 
static const OldChunks sign_chunk[] = {
 
	OCL_SVAR( OC_UINT16, SignStruct, str ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32,SignStruct, x ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32,SignStruct, y ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, SignStruct, z ),
 

	
 
	OCL_NULL( 6 ),         // Width of sign, no longer in use
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldSign(LoadgameState *ls, int num)
 
{
 
	if (!AddBlockIfNeeded(&_sign_pool, num))
 
		error("Signs: failed loading savegame: too many signs");
 

	
 
	return LoadChunk(ls, GetSign(num), sign_chunk);
 
}
 

	
 
static const OldChunks engine_chunk[] = {
 
	OCL_SVAR( OC_UINT16, Engine, player_avail ),
 
	OCL_SVAR( OC_UINT16, Engine, intro_date ),
 
	OCL_SVAR( OC_UINT16, Engine, age ),
 
@@ -1318,69 +1319,72 @@ static const OldChunks engine_chunk[] = 
 
	OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
 

	
 
	OCL_SVAR(  OC_UINT8, Engine, lifelength ),
 
	OCL_SVAR(  OC_UINT8, Engine, flags ),
 
	OCL_SVAR(  OC_UINT8, Engine, preview_player ),
 
	OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
 
	OCL_SVAR(  OC_UINT8, Engine, railtype ),
 

	
 
	OCL_NULL( 1 ),         // Junk
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldEngine(LoadgameState *ls, int num)
 
{
 
	if (!LoadChunk(ls, GetEngine(num), engine_chunk)) return false;
 

	
 
	/* Make sure wagons are marked as do-not-age */
 
	if ((num >= 27 && num < 54) || (num >= 57 && num < 84) || (num >= 89 && num < 116))
 
		GetEngine(num)->age = 0xFFFF;
 

	
 
	return true;
 
}
 

	
 
static const OldChunks subsidy_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
 
	OCL_SVAR(  OC_UINT8, Subsidy, age ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
 

	
 
	OCL_END()
 
};
 
static bool LoadOldSubsidy(LoadgameState *ls, int num)
 

	
 
static inline bool LoadOldSubsidy(LoadgameState *ls, int num)
 
{
 
	return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
 
}
 

	
 
static const OldChunks game_difficulty_chunk[] = {
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, max_no_competitors ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_start_time ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, number_towns ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, number_industries ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, max_loan ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, initial_interest ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, vehicle_costs ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_speed ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, competitor_intelligence ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, vehicle_breakdowns ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, subsidy_multiplier ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, construction_cost ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, terrain_type ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, quantity_sea_lakes ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, economy ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, line_reverse_mode ),
 
	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, GameDifficulty, disasters ),
 
	OCL_END()
 
};
 
static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
 

	
 
static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
 
{
 
	return LoadChunk(ls, &_opt.diff, game_difficulty_chunk);
 
}
 

	
 

	
 
static bool LoadOldMapPart1(LoadgameState *ls, int num)
 
{
 
	uint i;
 

	
 
	for (i = 0; i < OLD_MAP_SIZE; i++) {
 
		_m[i].m1 = ReadByte(ls);
 
	}
 
@@ -1392,39 +1396,39 @@ static bool LoadOldMapPart1(LoadgameStat
 
		_old_map3[i * 2 + 1] = ReadByte(ls);
 
	}
 
	for (i = 0; i < OLD_MAP_SIZE / 4; i++) {
 
		byte b = ReadByte(ls);
 
		_m[i * 4 + 0].extra = GB(b, 0, 2);
 
		_m[i * 4 + 1].extra = GB(b, 2, 2);
 
		_m[i * 4 + 2].extra = GB(b, 4, 2);
 
		_m[i * 4 + 3].extra = GB(b, 6, 2);
 
	}
 

	
 
	return !ls->failed;
 
}
 

	
 
static bool LoadOldMapPart2(LoadgameState *ls, int num)
 
{
 
	uint i;
 

	
 
	for (i = 0; i < OLD_MAP_SIZE; i++) {
 
		_m[i].type_height = ReadByte(ls);
 
	}
 
	for (i = 0; i < OLD_MAP_SIZE; i++) {
 
		_m[i].m5 = ReadByte(ls);
 
	}
 

	
 
	return !ls->failed;
 
}
 

	
 

	
 
static uint32 _old_cur_town_ctr;
 
static const OldChunks main_chunk[] = {
 
	OCL_ASSERT( 0 ),
 
	OCL_VAR ( OC_UINT16,   1, &_date ),
 
	OCL_VAR ( OC_UINT16,   1, &_date_fract ),
 
	OCL_NULL( 600 ),            // TextEffects
 
	OCL_VAR ( OC_UINT32,   2, &_random_seeds[0] ),
 

	
 
	OCL_ASSERT( 0x264 ),
 
	OCL_CHUNK(  70, LoadOldTown ),
 
	OCL_ASSERT( 0x1C18 ),
 
	OCL_CHUNK(5000, LoadOldOrder ),
 
@@ -1523,24 +1527,25 @@ static const OldChunks main_chunk[] = {
 
	OCL_NULL( 36 ),              // cargo-stuff, calculated in InitializeLandscapeVariables
 

	
 
	OCL_ASSERT( 0x77179 ),
 

	
 
	OCL_CHUNK( 1, LoadOldMapPart2 ),
 

	
 
	OCL_ASSERT( 0x97179 ),
 

	
 
	/* Below any (if available) extra chunks from TTDPatch can follow */
 

	
 
	OCL_END()
 
};
 

	
 
static bool LoadOldMain(LoadgameState *ls)
 
{
 
	int i;
 

	
 
	/* The first 49 is the name of the game + checksum, skip it */
 
	fseek(ls->file, HEADER_SIZE, SEEK_SET);
 

	
 
	DEBUG(oldloader, 4)("[OldLoader] Going to read main chunk..");
 
	/* Load the biggest chunk */
 
	if (!LoadChunk(ls, NULL, main_chunk)) {
 
		DEBUG(oldloader, 0)("[OldLoader] Loading failed!");
 
		return false;
 
@@ -1608,31 +1613,27 @@ bool LoadOldSaveGame(const char *file)
 
	/* Load the main chunk */
 
	if (!LoadOldMain(&ls)) return false;
 

	
 
	fclose(ls.file);
 

	
 
	_pause = 2;
 

	
 
	return true;
 
}
 

	
 
void GetOldSaveGameName(char *title, const char *file)
 
{
 
	FILE *f;
 

	
 
	f = fopen(file, "rb");
 
	FILE *f = fopen(file, "rb");
 
	title[0] = 0;
 
	title[48] = 0;
 

	
 
	if (f == NULL)
 
		return;
 
	if (f == NULL) return;
 

	
 
	if (fread(title, 1, 48, f) != 48)
 
		snprintf(title, 48, "Corrupt file");
 
	if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file");
 

	
 
	fclose(f);
 
}
 

	
 
void GetOldScenarioGameName(char *title, const char *file)
 
{
 
	GetOldSaveGameName(title, file);
 
}
0 comments (0 inline, 0 general)