mirror of https://github.com/OpenTTD/OpenTTD
(svn r16355) [0.7] -Backport from trunk:
- Fix: Invalid read when OTTD savegame contains VEH_INVALID (r16353) - Fix: Signal handler could end in endless loop (r16351) - Fix: [NewGRF] When overriding 'original sounds', only allow overriding of the 'original sounds' and not any other that is already loaded (r16339) - Fix: Desyncs when removing lots of stations/towns (r16329, r16328) [0.7] -Cleanup: unify style of changelogrelease/0.7
parent
ab7b117c50
commit
498e5989d1
1759
changelog.txt
1759
changelog.txt
File diff suppressed because it is too large
Load Diff
|
@ -2038,8 +2038,8 @@ static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, b
|
|||
case 0x0A: { // Override old sound
|
||||
uint orig_sound = grf_load_byte(&buf);
|
||||
|
||||
if (orig_sound >= GetNumSounds()) {
|
||||
grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, GetNumSounds());
|
||||
if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
|
||||
grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
|
||||
} else {
|
||||
FileEntry *newfe = GetSound(sound);
|
||||
FileEntry *oldfe = GetSound(orig_sound);
|
||||
|
|
|
@ -235,14 +235,41 @@ static bool InitializeWindowsAndCaches()
|
|||
return true;
|
||||
}
|
||||
|
||||
typedef void (CDECL *SignalHandlerPointer)(int);
|
||||
static SignalHandlerPointer _prev_segfault = NULL;
|
||||
static SignalHandlerPointer _prev_abort = NULL;
|
||||
|
||||
static void CDECL HandleSavegameLoadCrash(int signum);
|
||||
|
||||
/**
|
||||
* Replaces signal handlers of SIGSEGV and SIGABRT
|
||||
* and stores pointers to original handlers in memory.
|
||||
*/
|
||||
static void SetSignalHandlers()
|
||||
{
|
||||
_prev_segfault = signal(SIGSEGV, HandleSavegameLoadCrash);
|
||||
_prev_abort = signal(SIGABRT, HandleSavegameLoadCrash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets signal handlers back to original handlers.
|
||||
*/
|
||||
static void ResetSignalHandlers()
|
||||
{
|
||||
signal(SIGSEGV, _prev_segfault);
|
||||
signal(SIGABRT, _prev_abort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal handler used to give a user a more useful report for crashes during
|
||||
* the savegame loading process; especially when there's problems with the
|
||||
* NewGRFs that are required by the savegame.
|
||||
* @param unused well... unused
|
||||
* @param signum received signal
|
||||
*/
|
||||
void CDECL HandleSavegameLoadCrash(int unused)
|
||||
static void CDECL HandleSavegameLoadCrash(int signum)
|
||||
{
|
||||
ResetSignalHandlers();
|
||||
|
||||
char buffer[8192];
|
||||
char *p = buffer;
|
||||
p += seprintf(p, lastof(buffer),
|
||||
|
@ -272,6 +299,9 @@ void CDECL HandleSavegameLoadCrash(int unused)
|
|||
}
|
||||
|
||||
ShowInfo(buffer);
|
||||
|
||||
SignalHandlerPointer call = signum == SIGSEGV ? _prev_segfault : _prev_abort;
|
||||
if (call != NULL) call(signum);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,9 +352,7 @@ static void FixOwnerOfRailTrack(TileIndex t)
|
|||
|
||||
bool AfterLoadGame()
|
||||
{
|
||||
typedef void (CDECL *SignalHandlerPointer)(int);
|
||||
SignalHandlerPointer prev_segfault = signal(SIGSEGV, HandleSavegameLoadCrash);
|
||||
SignalHandlerPointer prev_abort = signal(SIGABRT, HandleSavegameLoadCrash);
|
||||
SetSignalHandlers();
|
||||
|
||||
TileIndex map_size = MapSize();
|
||||
Company *c;
|
||||
|
@ -433,8 +461,7 @@ bool AfterLoadGame()
|
|||
if (_networking && gcf_res != GLC_ALL_GOOD) {
|
||||
SetSaveLoadError(STR_NETWORK_ERR_CLIENT_NEWGRF_MISMATCH);
|
||||
/* Restore the signals */
|
||||
signal(SIGSEGV, prev_segfault);
|
||||
signal(SIGABRT, prev_abort);
|
||||
ResetSignalHandlers();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -486,8 +513,7 @@ bool AfterLoadGame()
|
|||
if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, UINT_MAX)) {
|
||||
SetSaveLoadError(STR_NO_TOWN_IN_SCENARIO);
|
||||
/* Restore the signals */
|
||||
signal(SIGSEGV, prev_segfault);
|
||||
signal(SIGABRT, prev_abort);
|
||||
ResetSignalHandlers();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -550,8 +576,7 @@ bool AfterLoadGame()
|
|||
SetStationGfx(t, gfx - 170 + GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
|
||||
} else {
|
||||
/* Restore the signals */
|
||||
signal(SIGSEGV, prev_segfault);
|
||||
signal(SIGABRT, prev_abort);
|
||||
ResetSignalHandlers();
|
||||
return false;
|
||||
}
|
||||
SB(_m[t].m6, 3, 3, st);
|
||||
|
@ -1801,8 +1826,7 @@ bool AfterLoadGame()
|
|||
|
||||
bool ret = InitializeWindowsAndCaches();
|
||||
/* Restore the signals */
|
||||
signal(SIGSEGV, prev_segfault);
|
||||
signal(SIGABRT, prev_abort);
|
||||
ResetSignalHandlers();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,17 +65,17 @@ static const SaveLoadGlobVarList _date_desc[] = {
|
|||
SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLEG_VAR(_disaster_delay, SLE_UINT16),
|
||||
SLEG_VAR(_station_tick_ctr, SLE_UINT16),
|
||||
SLE_CONDNULL(2, 0, 119),
|
||||
SLEG_VAR(_random.state[0], SLE_UINT32),
|
||||
SLEG_VAR(_random.state[1], SLE_UINT32),
|
||||
SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9),
|
||||
SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(1, 0, 9),
|
||||
SLE_CONDNULL(4, 10, 119),
|
||||
SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
|
||||
SLEG_CONDVAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32, 0, 108),
|
||||
SLEG_CONDVAR(_next_competitor_start, SLE_UINT32, 109, SL_MAX_VERSION),
|
||||
SLEG_VAR(_trees_tick_ctr, SLE_UINT8),
|
||||
SLEG_CONDVAR(_pause_game, SLE_UINT8, 4, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(4, 11, 119),
|
||||
SLEG_END()
|
||||
};
|
||||
|
||||
|
|
|
@ -1260,7 +1260,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
|
|||
uint type = ReadByte(ls);
|
||||
switch (type) {
|
||||
default: return false;
|
||||
case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break;
|
||||
case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break;
|
||||
case 0x25 /* MONORAIL */:
|
||||
case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
|
||||
case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
|
||||
|
@ -1583,7 +1583,6 @@ static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
|
|||
}
|
||||
|
||||
extern TileIndex _cur_tileloop_tile;
|
||||
static uint32 _old_cur_town_ctr;
|
||||
static const OldChunks main_chunk[] = {
|
||||
OCL_ASSERT( OC_TTD, 0 ),
|
||||
OCL_ASSERT( OC_TTO, 0 ),
|
||||
|
@ -1618,7 +1617,7 @@ static const OldChunks main_chunk[] = {
|
|||
OCL_ASSERT( OC_TTD, 0x4B26 ),
|
||||
OCL_ASSERT( OC_TTO, 0x3A20 ),
|
||||
|
||||
OCL_VAR ( OC_UINT32, 1, &_old_cur_town_ctr ),
|
||||
OCL_NULL( 4 ), ///< town counter, no longer in use
|
||||
OCL_NULL( 2 ), ///< timer_counter, no longer in use
|
||||
OCL_NULL( 2 ), ///< land_code, no longer in use
|
||||
|
||||
|
@ -1707,8 +1706,7 @@ static const OldChunks main_chunk[] = {
|
|||
|
||||
OCL_CNULL( OC_TTD, 144 ), ///< AI cargo-stuff, calculated in InitializeLandscapeVariables
|
||||
OCL_NULL( 2 ), ///< Company indexes of companies, no longer in use
|
||||
|
||||
OCL_VAR ( OC_FILE_U8 | OC_VAR_U16, 1, &_station_tick_ctr ),
|
||||
OCL_NULL( 1 ), ///< Station tick counter, no longer in use
|
||||
|
||||
OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
|
||||
OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.units ),
|
||||
|
@ -1775,9 +1773,6 @@ bool LoadTTDMain(LoadgameState *ls)
|
|||
/* Fix some general stuff */
|
||||
_settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
|
||||
|
||||
/* Remap some pointers */
|
||||
_cur_town_ctr = RemapTownIndex(_old_cur_town_ctr);
|
||||
|
||||
/* Fix the game to be compatible with OpenTTD */
|
||||
FixOldTowns();
|
||||
FixOldVehicles();
|
||||
|
@ -1814,8 +1809,6 @@ bool LoadTTOMain(LoadgameState *ls)
|
|||
_settings_game.game_creation.landscape = 0;
|
||||
_trees_tick_ctr = 0xFF;
|
||||
|
||||
_cur_town_ctr = RemapTownIndex(_old_cur_town_ctr);
|
||||
|
||||
if (!FixTTOMapArray() || !FixTTOEngines()) {
|
||||
DEBUG(oldloader, 0, "Conversion failed");
|
||||
return false;
|
||||
|
|
|
@ -195,9 +195,6 @@ static void Load_STNS()
|
|||
|
||||
SaveLoad_STNS(st);
|
||||
}
|
||||
|
||||
/* This is to ensure all pointers are within the limits of _stations_size */
|
||||
if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
|
||||
}
|
||||
|
||||
static void Save_ROADSTOP()
|
||||
|
|
|
@ -189,11 +189,6 @@ static void Load_TOWN()
|
|||
|
||||
_total_towns++;
|
||||
}
|
||||
|
||||
/* This is to ensure all pointers are within the limits of
|
||||
* the size of the TownPool */
|
||||
if (_cur_town_ctr > GetMaxTownIndex())
|
||||
_cur_town_ctr = 0;
|
||||
}
|
||||
|
||||
extern const ChunkHandler _town_chunk_handlers[] = {
|
||||
|
|
|
@ -698,7 +698,7 @@ void Load_VEHS()
|
|||
case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
|
||||
case VEH_EFFECT: v = new (index) EffectVehicle(); break;
|
||||
case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
|
||||
case VEH_INVALID: v = new (index) InvalidVehicle(); break;
|
||||
case VEH_INVALID: /* Savegame shouldn't contain invalid vehicles */
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ MusicFileSettings msf;
|
|||
/* Number of levels of panning per side */
|
||||
#define PANNING_LEVELS 16
|
||||
|
||||
/** The number of sounds in the original sample.cat */
|
||||
static const uint ORIGINAL_SAMPLE_COUNT = 73;
|
||||
|
||||
static void OpenBankFile(const char *filename)
|
||||
{
|
||||
FileEntry *fe = CallocT<FileEntry>(ORIGINAL_SAMPLE_COUNT);
|
||||
|
|
|
@ -110,4 +110,7 @@ enum SoundFx {
|
|||
template <> struct EnumPropsT<SoundFx> : MakeEnumPropsT<SoundFx, byte, SND_BEGIN, SND_END, SND_END> {};
|
||||
typedef TinyEnumT<SoundFx> SoundFxByte;
|
||||
|
||||
/** The number of sounds in the original sample.cat */
|
||||
static const uint ORIGINAL_SAMPLE_COUNT = 73;
|
||||
|
||||
#endif /* SOUND_TYPE_H */
|
||||
|
|
|
@ -2086,8 +2086,8 @@ bool HasStationInUse(StationID station, CompanyID company)
|
|||
|
||||
static CommandCost RemoveBuoy(Station *st, DoCommandFlag flags)
|
||||
{
|
||||
/* XXX: strange stuff */
|
||||
if (!IsValidCompanyID(_current_company)) return_cmd_error(INVALID_STRING_ID);
|
||||
/* XXX: strange stuff, allow clearing as invalid company when clearing landscape */
|
||||
if (!IsValidCompanyID(_current_company) && !(flags & DC_BANKRUPT)) return_cmd_error(INVALID_STRING_ID);
|
||||
|
||||
TileIndex tile = st->dock_tile;
|
||||
|
||||
|
@ -2689,7 +2689,11 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
|
|||
return VETSB_CONTINUE;
|
||||
}
|
||||
|
||||
/* this function is called for one station each tick */
|
||||
/**
|
||||
* This function is called for each station once every 250 ticks.
|
||||
* Not all stations will get the tick at the same time.
|
||||
* @param st the station receiving the tick.
|
||||
*/
|
||||
static void StationHandleBigTick(Station *st)
|
||||
{
|
||||
UpdateStationAcceptance(st, true);
|
||||
|
@ -2829,11 +2833,6 @@ void OnTick_Station()
|
|||
{
|
||||
if (_game_mode == GM_EDITOR) return;
|
||||
|
||||
uint i = _station_tick_ctr;
|
||||
if (++_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
|
||||
|
||||
if (IsValidStationID(i)) StationHandleBigTick(GetStation(i));
|
||||
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
StationHandleSmallTick(st);
|
||||
|
@ -2842,6 +2841,7 @@ void OnTick_Station()
|
|||
* Station index is included so that triggers are not all done
|
||||
* at the same time. */
|
||||
if ((_tick_counter + st->index) % 250 == 0) {
|
||||
StationHandleBigTick(st);
|
||||
StationAnimationTrigger(st, st->xy, STAT_ANIM_250_TICKS);
|
||||
}
|
||||
}
|
||||
|
@ -3201,8 +3201,6 @@ void InitializeStations()
|
|||
/* Clean the roadstop pool and create 1 block in it */
|
||||
_RoadStop_pool.CleanPool();
|
||||
_RoadStop_pool.AddBlockToPool();
|
||||
|
||||
_station_tick_ctr = 0;
|
||||
}
|
||||
|
||||
static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
|
||||
|
|
|
@ -589,8 +589,8 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed)
|
|||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
/* There can be buoys, remove them */
|
||||
if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
delete st;
|
||||
if (st->IsBuoy() && IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
|
||||
if (st->facilities == 0) delete st;
|
||||
}
|
||||
|
||||
/* The same for waypoints */
|
||||
|
|
|
@ -352,8 +352,6 @@ Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
|
|||
|
||||
extern Town *_cleared_town;
|
||||
extern int _cleared_town_rating;
|
||||
extern uint32 _cur_town_ctr;
|
||||
extern uint32 _cur_town_iter;
|
||||
|
||||
void ResetHouses();
|
||||
|
||||
|
|
|
@ -683,17 +683,12 @@ void OnTick_Town()
|
|||
{
|
||||
if (_game_mode == GM_EDITOR) return;
|
||||
|
||||
/* Make sure each town's tickhandler invocation frequency is about the
|
||||
* same - TOWN_GROWTH_FREQUENCY - independent on the number of towns. */
|
||||
for (_cur_town_iter += GetMaxTownIndex() + 1;
|
||||
_cur_town_iter >= TOWN_GROWTH_FREQUENCY;
|
||||
_cur_town_iter -= TOWN_GROWTH_FREQUENCY) {
|
||||
uint32 i = _cur_town_ctr;
|
||||
|
||||
if (++_cur_town_ctr > GetMaxTownIndex())
|
||||
_cur_town_ctr = 0;
|
||||
|
||||
if (IsValidTownID(i)) TownTickHandler(GetTown(i));
|
||||
Town *t;
|
||||
FOR_ALL_TOWNS(t) {
|
||||
/* Run town tick at regular intervals, but not all at once. */
|
||||
if ((_tick_counter + t->index) % TOWN_GROWTH_FREQUENCY == 0) {
|
||||
TownTickHandler(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2751,8 +2746,6 @@ void InitializeTowns()
|
|||
s->cargo_type = CT_INVALID;
|
||||
}
|
||||
|
||||
_cur_town_ctr = 0;
|
||||
_cur_town_iter = 0;
|
||||
_total_towns = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,6 @@ VARDEF byte _age_cargo_skip_counter;
|
|||
/* Also save scrollpos_x, scrollpos_y and zoom */
|
||||
VARDEF uint16 _disaster_delay;
|
||||
|
||||
/* Determines what station to operate on in the
|
||||
* tick handler. */
|
||||
VARDEF uint16 _station_tick_ctr;
|
||||
|
||||
/* Determines how often to run the tree loop */
|
||||
VARDEF byte _trees_tick_ctr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue