From 2f22fd155b9549a96b64455e915abd58ac03fdab Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 1 Oct 2008 11:48:57 +0000 Subject: [PATCH] (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) --- src/console.cpp | 2 +- src/music/win32_m.cpp | 1 + src/namegen.cpp | 2 +- src/newgrf_industries.cpp | 66 ++++++++++++++++++++++++--------------- src/openttd.cpp | 6 ++-- src/rail_cmd.cpp | 4 +-- src/train_cmd.cpp | 2 +- src/video/dedicated_v.cpp | 3 +- src/video/win32_v.cpp | 2 +- src/win32.cpp | 14 ++++----- 10 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 885f5eaf41..350dd95fdb 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -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; } diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp index 8ad9649778..57bd20cf7d 100644 --- a/src/music/win32_m.cpp +++ b/src/music/win32_m.cpp @@ -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; diff --git a/src/namegen.cpp b/src/namegen.cpp index 26b1171268..57b97e0344 100644 --- a/src/namegen.cpp +++ b/src/namegen.cpp @@ -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) diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index b84762230d..df09ef2322 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -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 diff --git a/src/openttd.cpp b/src/openttd.cpp index 47fad621dc..3de1f539cb 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -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; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 3426f27229..11301defa8 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -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)) { diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 34ec74460d..c9fcb2cb86 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -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); diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 2b5028791a..13c54cdfde 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -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 diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 42ebf98811..d43bb73607 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -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"); diff --git a/src/win32.cpp b/src/win32.cpp index e54a21d486..f86a6e9ad2 100644 --- a/src/win32.cpp +++ b/src/win32.cpp @@ -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);