1
0
Fork 0

(svn r14426) [0.6] -Backport from trunk:

- Fix: NewGRF VarAction 2 variable 43 for industries saw MP_VOID tiles as land tiles and was inefficient (r14417, r14416, r14415)
- Fix: Possible buffer overrun/wrong parameter type passed to printf (r14414, r14397)
- Fix: Generation seed set using -G was always overwritten by -g (r14408)
- Fix: Do not allow extending signals by dragging in any direction other than the track direction [FS#2202] (r14013)
release/0.6
rubidium 2008-10-01 11:48:57 +00:00
parent fde71ec047
commit 2f22fd155b
10 changed files with 60 additions and 42 deletions

View File

@ -697,7 +697,7 @@ IConsoleAlias *IConsoleAliasGet(const char *name)
static inline int IConsoleCopyInParams(char *dst, const char *src, uint bufpos)
{
int len = min(ICON_MAX_STREAMSIZE - bufpos, (uint)strlen(src));
strncpy(dst, src, len);
strecpy(dst, src, dst + len - 1);
return len;
}

View File

@ -20,6 +20,7 @@ static FMusicDriver_Win32 iFMusicDriver_Win32;
void MusicDriver_Win32::PlaySong(const char *filename)
{
assert(filename != NULL);
strcpy(_midi.start_song, filename);
_midi.playing = true;
_midi.stop_song = false;

View File

@ -36,7 +36,7 @@ static inline int32 SeedChanceBias(int shift_by, int max, uint32 seed, int bias)
static void ReplaceWords(const char *org, const char *rep, char *buf)
{
if (strncmp(buf, org, 4) == 0) strncpy(buf, rep, 4);
if (strncmp(buf, org, 4) == 0) strncpy(buf, rep, 4); // Safe as the string in buf is always more than 4 characters long.
}
static byte MakeEnglishOriginalTownName(char *buf, uint32 seed, const char *last)

View File

@ -54,41 +54,55 @@ static uint32 GetGRFParameter(IndustryType ind_id, byte parameter)
* Finds the distance for the closest tile with water/land given a tile
* @param tile the tile to find the distance too
* @param water whether to find water or land
* @return distance to nearest water (max 0x7F) / land (max 0x1FF; 0x200 if there is no land)
* @note FAILS when an industry should be seen as water
*/
static uint GetClosestWaterDistance(TileIndex tile, bool water)
{
TileIndex t;
int best_dist;
for (t = 0; t < MapSize(); t++) {
if (IsTileType(t, MP_WATER) == water) break;
}
if (t == MapSize() && !water) return 0x200;
best_dist = DistanceManhattan(tile, t);
if (IsTileType(tile, MP_WATER) == water) return 0;
for (; t < MapSize(); t++) {
int dist = DistanceManhattan(tile, t);
if (dist < best_dist) {
if (IsTileType(t, MP_WATER) == water) best_dist = dist;
} else {
/* When the Y distance between the current row and the 'source' tile
* is larger than the best distance, we've found the best distance */
if ((int)TileY(t) - (int)TileY(tile) > best_dist) break;
if ((int)TileX(t) - (int)TileX(tile) > best_dist) {
/* We can safely skip this many tiles; from here all tiles have a
* higher or equal distance than the best distance */
t |= MapMaxX();
continue;
} else if (TileX(tile) < TileX(t)) {
/* We can safely skip this many tiles; up to here all tiles have a
* higher or equal distance than the best distance */
t += max(best_dist - dist, 0);
continue;
uint max_dist = water ? 0x7F : 0x200;
int x = TileX(tile);
int y = TileY(tile);
uint max_x = MapMaxX();
uint max_y = MapMaxY();
/* go in a 'spiral' with increasing manhattan distance in each iteration */
for (uint dist = 1; dist < max_dist; dist++) {
/* next 'diameter' */
y--;
/* going counter-clockwise around this square */
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
static const int8 ddx[DIAGDIR_END] = { -1, 1, 1, -1};
static const int8 ddy[DIAGDIR_END] = { 1, 1, -1, -1};
int dx = ddx[dir];
int dy = ddy[dir];
/* each side of this square has length 'dist' */
for (uint a = 0; a < dist; a++) {
/* MP_VOID tiles are not checked (interval is [0; max) for IsInsideMM())*/
if (IsInsideMM(x, 0, max_x) && IsInsideMM(y, 0, max_y)) {
TileIndex t = TileXY(x, y);
if (IsTileType(t, MP_WATER) == water) return dist;
}
x += dx;
y += dy;
}
}
}
return min(best_dist, water ? 0x7F : 0x1FF);
if (!water) {
/* no land found - is this a water-only map? */
for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_VOID) && !IsTileType(t, MP_WATER)) return 0x1FF;
}
}
return max_dist;
}
/** Make an analysis of a tile and check for its belonging to the same

View File

@ -425,8 +425,10 @@ int ttd_main(int argc, char *argv[])
}
_switch_mode = SM_NEWGAME;
/* Give a random map */
generation_seed = InteractiveRandom();
/* Give a random map if no seed has been given */
if (generation_seed == GENERATE_NEW_SEED) {
generation_seed = InteractiveRandom();
}
break;
case 'G': generation_seed = atoi(mgo.opt); break;
case 'c': _config_file = strdup(mgo.opt); break;

View File

@ -1002,8 +1002,8 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
Trackdir start_trackdir = trackdir;
/* Autofill must start on a valid track to be able to avoid loops */
if (autofill && !HasTrack(tile, track)) return CMD_ERROR;
/* Must start on a valid track to be able to avoid loops */
if (!HasTrack(tile, track)) return CMD_ERROR;
/* copy the signal-style of the first rail-piece if existing */
if (HasSignals(tile)) {

View File

@ -1124,7 +1124,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
}
/* When we move the front vehicle, the second vehicle might need a unitnumber */
if (!HasBit(p2, 0) && (IsFreeWagon(src) || IsFrontEngine(src)) && (flags & DC_AUTOREPLACE) == 0) {
if (!HasBit(p2, 0) && (IsFreeWagon(src) || (IsFrontEngine(src) && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) {
Vehicle *second = GetNextUnit(src);
if (second != NULL && IsTrainEngine(second) && GetFreeUnitNumber(VEH_TRAIN) > _patches.max_trains) {
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);

View File

@ -223,7 +223,8 @@ static void DedicatedHandleKeyInput()
if (fgets(input_line, lengthof(input_line), stdin) == NULL) return;
#else
/* Handle console input, and singal console thread, it can accept input again */
strncpy(input_line, _win_console_thread_buffer, lengthof(input_line));
assert_compile(lengthof(_win_console_thread_buffer) <= lengthof(input_line));
strcpy(input_line, _win_console_thread_buffer);
SetEvent(_hWaitForInputHandling);
#endif

View File

@ -285,7 +285,7 @@ static bool MakeWindow(bool full_screen)
extern const char _openttd_revision[];
TCHAR Windowtitle[50];
_sntprintf(Windowtitle, sizeof(Windowtitle), _T("OpenTTD %s"), MB_TO_WIDE(_openttd_revision));
_sntprintf(Windowtitle, lengthof(Windowtitle), _T("OpenTTD %s"), MB_TO_WIDE(_openttd_revision));
_wnd.main_wnd = CreateWindow(_T("OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0);
if (_wnd.main_wnd == NULL) error("CreateWindow failed");

View File

@ -526,7 +526,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
ep->ContextRecord->EFlags
);
#else
output += sprintf(output, "Exception %.8X at %.8X\r\n"
output += sprintf(output, "Exception %.8X at %.8p\r\n"
"Registers:\r\n"
" EAX: %.8X EBX: %.8X ECX: %.8X EDX: %.8X\r\n"
" ESI: %.8X EDI: %.8X EBP: %.8X ESP: %.8X\r\n"
@ -592,9 +592,9 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
output = PrintModuleList(output);
{
OSVERSIONINFO os;
_OSVERSIONINFOA os;
os.dwOSVersionInfoSize = sizeof(os);
GetVersionEx(&os);
GetVersionExA(&os);
output += sprintf(output, "\r\nSystem information:\r\n"
" Windows version %d.%d %d %s\r\n",
os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber, os.szCSDVersion);
@ -797,7 +797,7 @@ void FiosGetDrives()
TCHAR drives[256];
const TCHAR *s;
GetLogicalDriveStrings(sizeof(drives), drives);
GetLogicalDriveStrings(lengthof(drives), drives);
for (s = drives; *s != '\0';) {
FiosItem *fios = FiosAlloc();
fios->type = FIOS_TYPE_DRIVE;
@ -1048,14 +1048,14 @@ void DetermineBasePaths(const char *exe)
TCHAR path[MAX_PATH];
#ifdef WITH_PERSONAL_DIR
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path);
strncpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lengthof(tmp));
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp));
AppendPathSeparator(tmp, MAX_PATH);
ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH);
AppendPathSeparator(tmp, MAX_PATH);
_searchpaths[SP_PERSONAL_DIR] = strdup(tmp);
SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path);
strncpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lengthof(tmp));
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp));
AppendPathSeparator(tmp, MAX_PATH);
ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH);
AppendPathSeparator(tmp, MAX_PATH);
@ -1080,7 +1080,7 @@ void DetermineBasePaths(const char *exe)
DEBUG(misc, 0, "GetFullPathName failed (%d)\n", GetLastError());
_searchpaths[SP_BINARY_DIR] = NULL;
} else {
strncpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lengthof(tmp));
strecpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
char *s = strrchr(tmp, PATHSEPCHAR);
*(s + 1) = '\0';
_searchpaths[SP_BINARY_DIR] = strdup(tmp);