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) static inline int IConsoleCopyInParams(char *dst, const char *src, uint bufpos)
{ {
int len = min(ICON_MAX_STREAMSIZE - bufpos, (uint)strlen(src)); int len = min(ICON_MAX_STREAMSIZE - bufpos, (uint)strlen(src));
strncpy(dst, src, len); strecpy(dst, src, dst + len - 1);
return len; return len;
} }

View File

@ -20,6 +20,7 @@ static FMusicDriver_Win32 iFMusicDriver_Win32;
void MusicDriver_Win32::PlaySong(const char *filename) void MusicDriver_Win32::PlaySong(const char *filename)
{ {
assert(filename != NULL);
strcpy(_midi.start_song, filename); strcpy(_midi.start_song, filename);
_midi.playing = true; _midi.playing = true;
_midi.stop_song = false; _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) 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) 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 * Finds the distance for the closest tile with water/land given a tile
* @param tile the tile to find the distance too * @param tile the tile to find the distance too
* @param water whether to find water or land * @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 * @note FAILS when an industry should be seen as water
*/ */
static uint GetClosestWaterDistance(TileIndex tile, bool water) static uint GetClosestWaterDistance(TileIndex tile, bool water)
{ {
TileIndex t; if (IsTileType(tile, MP_WATER) == water) return 0;
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);
for (; t < MapSize(); t++) { uint max_dist = water ? 0x7F : 0x200;
int dist = DistanceManhattan(tile, t);
if (dist < best_dist) { int x = TileX(tile);
if (IsTileType(t, MP_WATER) == water) best_dist = dist; int y = TileY(tile);
} else {
/* When the Y distance between the current row and the 'source' tile uint max_x = MapMaxX();
* is larger than the best distance, we've found the best distance */ uint max_y = MapMaxY();
if ((int)TileY(t) - (int)TileY(tile) > best_dist) break;
if ((int)TileX(t) - (int)TileX(tile) > best_dist) { /* go in a 'spiral' with increasing manhattan distance in each iteration */
/* We can safely skip this many tiles; from here all tiles have a for (uint dist = 1; dist < max_dist; dist++) {
* higher or equal distance than the best distance */ /* next 'diameter' */
t |= MapMaxX(); y--;
continue;
} else if (TileX(tile) < TileX(t)) { /* going counter-clockwise around this square */
/* We can safely skip this many tiles; up to here all tiles have a for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
* higher or equal distance than the best distance */ static const int8 ddx[DIAGDIR_END] = { -1, 1, 1, -1};
t += max(best_dist - dist, 0); static const int8 ddy[DIAGDIR_END] = { 1, 1, -1, -1};
continue;
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 /** 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; _switch_mode = SM_NEWGAME;
/* Give a random map */ /* Give a random map if no seed has been given */
generation_seed = InteractiveRandom(); if (generation_seed == GENERATE_NEW_SEED) {
generation_seed = InteractiveRandom();
}
break; break;
case 'G': generation_seed = atoi(mgo.opt); break; case 'G': generation_seed = atoi(mgo.opt); break;
case 'c': _config_file = strdup(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 */ track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
Trackdir start_trackdir = trackdir; Trackdir start_trackdir = trackdir;
/* Autofill must start on a valid track to be able to avoid loops */ /* Must start on a valid track to be able to avoid loops */
if (autofill && !HasTrack(tile, track)) return CMD_ERROR; if (!HasTrack(tile, track)) return CMD_ERROR;
/* copy the signal-style of the first rail-piece if existing */ /* copy the signal-style of the first rail-piece if existing */
if (HasSignals(tile)) { 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 */ /* 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); Vehicle *second = GetNextUnit(src);
if (second != NULL && IsTrainEngine(second) && GetFreeUnitNumber(VEH_TRAIN) > _patches.max_trains) { if (second != NULL && IsTrainEngine(second) && GetFreeUnitNumber(VEH_TRAIN) > _patches.max_trains) {
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); 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; if (fgets(input_line, lengthof(input_line), stdin) == NULL) return;
#else #else
/* Handle console input, and singal console thread, it can accept input again */ /* 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); SetEvent(_hWaitForInputHandling);
#endif #endif

View File

@ -285,7 +285,7 @@ static bool MakeWindow(bool full_screen)
extern const char _openttd_revision[]; extern const char _openttd_revision[];
TCHAR Windowtitle[50]; 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); _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"); if (_wnd.main_wnd == NULL) error("CreateWindow failed");

View File

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