Merge upstream branch 1.8

This commit is contained in:
Sergii Pylypenko
2018-05-31 22:59:50 +03:00
240 changed files with 9656 additions and 2536 deletions

View File

@@ -12,6 +12,7 @@
#include "stdafx.h"
#include <stdarg.h>
#include <algorithm>
#include "debug.h"
#include "fileio_func.h"
@@ -2969,7 +2970,7 @@ static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteRea
case 0x0B: cs->town_effect = TE_FOOD; break;
default:
grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
/* FALL THROUGH */
FALLTHROUGH;
case 0xFF: cs->town_effect = TE_NONE; break;
}
break;
@@ -3672,6 +3673,9 @@ static void DuplicateTileTable(AirportSpec *as)
HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
MemCpyT(depot_table, as->depot_table, as->nof_depots);
as->depot_table = depot_table;
Direction *rotation = MallocT<Direction>(as->num_table);
MemCpyT(rotation, as->rotation, as->num_table);
as->rotation = rotation;
}
/**
@@ -3741,6 +3745,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
}
case 0x0A: { // Set airport layout
free(as->rotation);
as->num_table = buf->ReadByte(); // Number of layaouts
as->rotation = MallocT<Direction>(as->num_table);
uint32 defsize = buf->ReadDWord(); // Total size of the definition
@@ -3750,7 +3755,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
const AirportTileTable *copy_from;
try {
for (byte j = 0; j < as->num_table; j++) {
as->rotation[j] = (Direction)buf->ReadByte();
const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
for (int k = 0;; k++) {
att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
att[k].ti.y = buf->ReadByte();
@@ -4094,7 +4099,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
if (rt != INVALID_RAILTYPE) {
switch (prop) {
case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
case 0x19: SetBit(rti->introduces_railtypes, rt); break;
@@ -4211,7 +4216,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
break;
}
grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
/* FALL THROUGH */
FALLTHROUGH;
case 0x0E: // Compatible railtype list
case 0x0F: // Powered railtype list
@@ -4350,7 +4355,7 @@ static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uin
case CIR_UNKNOWN:
grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
/* FALL THROUGH */
FALLTHROUGH;
case CIR_INVALID_ID: {
/* No debug message for an invalid ID, as it has already been output */
@@ -4683,16 +4688,63 @@ static void NewSpriteGroup(ByteReader *buf)
group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
group->num_ranges = buf->ReadByte();
if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
for (uint i = 0; i < group->num_ranges; i++) {
group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
group->ranges[i].low = buf->ReadVarSize(varsize);
group->ranges[i].high = buf->ReadVarSize(varsize);
std::vector<DeterministicSpriteGroupRange> ranges;
ranges.resize(buf->ReadByte());
for (uint i = 0; i < ranges.size(); i++) {
ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
ranges[i].low = buf->ReadVarSize(varsize);
ranges[i].high = buf->ReadVarSize(varsize);
}
group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
/* nvar == 0 is a special case -- we turn our value into a callback result */
group->calculated_result = ranges.size() == 0;
/* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
std::vector<uint32> bounds;
for (uint i = 0; i < ranges.size(); i++) {
bounds.push_back(ranges[i].low);
if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
}
std::sort(bounds.begin(), bounds.end());
bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
std::vector<const SpriteGroup *> target;
for (uint j = 0; j < bounds.size(); ++j) {
uint32 v = bounds[j];
const SpriteGroup *t = group->default_group;
for (uint i = 0; i < ranges.size(); i++) {
if (ranges[i].low <= v && v <= ranges[i].high) {
t = ranges[i].group;
break;
}
}
target.push_back(t);
}
assert(target.size() == bounds.size());
std::vector<DeterministicSpriteGroupRange> optimised;
for (uint j = 0; j < bounds.size(); ) {
if (target[j] != group->default_group) {
DeterministicSpriteGroupRange r;
r.group = target[j];
r.low = bounds[j];
while (j < bounds.size() && target[j] == r.group) {
j++;
}
r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
optimised.push_back(r);
} else {
j++;
}
}
group->num_ranges = optimised.size();
if (group->num_ranges > 0) {
group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
}
break;
}
@@ -7915,6 +7967,7 @@ static void ResetCustomAirports()
}
free(as->table);
free(as->depot_table);
free(as->rotation);
free(as);
}