(svn r25170) [1.3] -Backport from trunk:

- Fix: Original train and rv acceleration did no longer respect bridge speed limits [FS#5523] (r25167)
- Fix: [Win32] Do not statically link to SHGetFolderPath as it may not exist, and improve its emulation [FS#5522] (r25155, r25153)
- Fix: [Win32] Do not store invalid paths in the search path list (r25154)
- Fix: Remove stray reservation from savegames affected by FS#5510 et al. upon loading [FS#5520] (r25152)
- Fix: [Script] XXBase::Chance function did not work for large values (>65535) [FS#5517] (r25148)
This commit is contained in:
rubidium 2013-04-08 20:59:42 +00:00
parent 283ab728f2
commit 7daff778f9
8 changed files with 59 additions and 34 deletions

View File

@ -173,7 +173,7 @@ static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
}
}
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
if (!SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
goto folder_error;
}

View File

@ -17,6 +17,7 @@
#include "../../fios.h"
#include <windows.h>
#include <fcntl.h>
#include <regstr.h>
#include <shlobj.h> /* SHGetFolderPath */
#include <Shellapi.h>
#include "win32.h"
@ -505,19 +506,25 @@ void DetermineBasePaths(const char *exe)
char tmp[MAX_PATH];
TCHAR path[MAX_PATH];
#ifdef WITH_PERSONAL_DIR
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path);
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);
if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) {
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);
} else {
_searchpaths[SP_PERSONAL_DIR] = NULL;
}
SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path);
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_SHARED_DIR] = strdup(tmp);
if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) {
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_SHARED_DIR] = strdup(tmp);
} else {
_searchpaths[SP_SHARED_DIR] = NULL;
}
#else
_searchpaths[SP_PERSONAL_DIR] = NULL;
_searchpaths[SP_SHARED_DIR] = NULL;
@ -726,8 +733,11 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
#else
# define W(x) x "A"
#endif
if (!LoadLibraryList((Function*)&SHGetFolderPath, "SHFolder.dll\0" W("SHGetFolderPath") "\0\0")) {
DEBUG(misc, 0, "Unable to load " W("SHGetFolderPath") "from SHFolder.dll");
/* The function lives in shell32.dll for all current Windows versions, but it first started to appear in SHFolder.dll. */
if (!LoadLibraryList((Function*)&SHGetFolderPath, "shell32.dll\0" W("SHGetFolderPath") "\0\0")) {
if (!LoadLibraryList((Function*)&SHGetFolderPath, "SHFolder.dll\0" W("SHGetFolderPath") "\0\0")) {
DEBUG(misc, 0, "Unable to load " W("SHGetFolderPath") "from either shell32.dll or SHFolder.dll");
}
}
#undef W
first_time = false;
@ -752,6 +762,17 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
return (HRESULT)0;
case CSIDL_PERSONAL:
case CSIDL_COMMON_DOCUMENTS: {
HKEY key;
if (RegOpenKeyEx(csidl == CSIDL_PERSONAL ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, REGSTR_PATH_SPECIAL_FOLDERS, 0, KEY_READ, &key) != ERROR_SUCCESS) break;
DWORD len = MAX_PATH;
ret = RegQueryValueEx(key, csidl == CSIDL_PERSONAL ? _T("Personal") : _T("Common Documents"), NULL, NULL, (LPBYTE)pszPath, &len);
RegCloseKey(key);
if (ret == ERROR_SUCCESS) return (HRESULT)0;
break;
}
/* XXX - other types to go here when needed... */
}
}

View File

@ -40,12 +40,6 @@ extern uint _codepage; // local code-page in the system @see win32_v.cpp:WM_INPU
# define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str)
#endif
/* Override SHGetFolderPath with our custom implementation */
#if defined(SHGetFolderPath)
#undef SHGetFolderPath
#endif
#define SHGetFolderPath OTTDSHGetFolderPath
HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR);
#if defined(__MINGW32__)

View File

@ -429,17 +429,17 @@ void RoadVehicle::UpdateDeltaXY(Direction direction)
*/
inline int RoadVehicle::GetCurrentMaxSpeed() const
{
if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) return min(this->vcache.cached_max_speed, this->current_order.max_speed * 2);
int max_speed = this->vcache.cached_max_speed;
/* Limit speed to 50% while reversing, 75% in curves. */
for (const RoadVehicle *u = this; u != NULL; u = u->Next()) {
if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)this->state)) {
max_speed = this->vcache.cached_max_speed / 2;
break;
} else if ((u->direction & 1) == 0) {
max_speed = this->vcache.cached_max_speed * 3 / 4;
if (_settings_game.vehicle.roadveh_acceleration_model == AM_REALISTIC) {
if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)this->state)) {
max_speed = this->vcache.cached_max_speed / 2;
break;
} else if ((u->direction & 1) == 0) {
max_speed = this->vcache.cached_max_speed * 3 / 4;
}
}
/* Vehicle is on the middle part of a bridge. */

View File

@ -2770,6 +2770,14 @@ bool AfterLoadGame()
v->acceleration = avi->acceleration;
}
}
/* Blocked tiles could be reserved due to a bug, which causes
* other places to assert upon e.g. station reconstruction. */
for (TileIndex t = 0; t < map_size; t++) {
if (HasStationTileRail(t) && IsStationTileBlocked(t)) {
SetRailStationReservation(t, false);
}
}
}
/* Road stops is 'only' updating some caches */

View File

@ -44,7 +44,7 @@
/* static */ bool ScriptBase::Chance(uint out, uint max)
{
EnforcePrecondition(false, out <= max);
return (uint16)Rand() <= (uint16)((65535 * out) / max);
return ScriptBase::RandRange(max) < out;
}
/* static */ bool ScriptBase::ChanceItem(int unused_param, uint out, uint max)

View File

@ -70,6 +70,7 @@ public:
* @param unused_param This parameter is not used, but is needed to work with lists.
* @param out How many times it should return true.
* @param max Out of this many times.
* @pre \a out is at most equal to \a max.
* @return True if the chance worked out.
*/
static bool ChanceItem(int unused_param, uint out, uint max);

View File

@ -371,10 +371,11 @@ int Train::GetCurveSpeedLimit() const
*/
int Train::GetCurrentMaxSpeed() const
{
if (_settings_game.vehicle.train_acceleration_model == AM_ORIGINAL) return min(this->gcache.cached_max_track_speed, this->current_order.max_speed);
int max_speed = _settings_game.vehicle.train_acceleration_model == AM_ORIGINAL ?
this->gcache.cached_max_track_speed :
this->tcache.cached_max_curve_speed;
int max_speed = this->tcache.cached_max_curve_speed;
if (IsRailStationTile(this->tile)) {
if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC && IsRailStationTile(this->tile)) {
StationID sid = GetStationIndex(this->tile);
if (this->current_order.ShouldStopAtStation(this, sid)) {
int station_ahead;
@ -400,7 +401,7 @@ int Train::GetCurrentMaxSpeed() const
}
for (const Train *u = this; u != NULL; u = u->Next()) {
if (u->track == TRACK_BIT_DEPOT) {
if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC && u->track == TRACK_BIT_DEPOT) {
max_speed = min(max_speed, 61);
break;
}
@ -2775,7 +2776,7 @@ int Train::UpdateSpeed()
switch (_settings_game.vehicle.train_acceleration_model) {
default: NOT_REACHED();
case AM_ORIGINAL:
return this->DoUpdateSpeed(this->acceleration * (this->GetAccelerationStatus() == AS_BRAKE ? -4 : 2), 0, min(this->gcache.cached_max_track_speed, this->current_order.max_speed));
return this->DoUpdateSpeed(this->acceleration * (this->GetAccelerationStatus() == AS_BRAKE ? -4 : 2), 0, this->GetCurrentMaxSpeed());
case AM_REALISTIC:
return this->DoUpdateSpeed(this->GetAcceleration(), this->GetAccelerationStatus() == AS_BRAKE ? 0 : 2, this->GetCurrentMaxSpeed());