1
0
Fork 0

(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)
release/1.3
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"); DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
goto folder_error; goto folder_error;
} }

View File

@ -17,6 +17,7 @@
#include "../../fios.h" #include "../../fios.h"
#include <windows.h> #include <windows.h>
#include <fcntl.h> #include <fcntl.h>
#include <regstr.h>
#include <shlobj.h> /* SHGetFolderPath */ #include <shlobj.h> /* SHGetFolderPath */
#include <Shellapi.h> #include <Shellapi.h>
#include "win32.h" #include "win32.h"
@ -505,19 +506,25 @@ void DetermineBasePaths(const char *exe)
char tmp[MAX_PATH]; char tmp[MAX_PATH];
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); if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) {
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(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);
} else {
_searchpaths[SP_PERSONAL_DIR] = NULL;
}
SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path); if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) {
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(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_SHARED_DIR] = strdup(tmp); _searchpaths[SP_SHARED_DIR] = strdup(tmp);
} else {
_searchpaths[SP_SHARED_DIR] = NULL;
}
#else #else
_searchpaths[SP_PERSONAL_DIR] = NULL; _searchpaths[SP_PERSONAL_DIR] = NULL;
_searchpaths[SP_SHARED_DIR] = NULL; _searchpaths[SP_SHARED_DIR] = NULL;
@ -726,8 +733,11 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
#else #else
# define W(x) x "A" # define W(x) x "A"
#endif #endif
/* 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")) { if (!LoadLibraryList((Function*)&SHGetFolderPath, "SHFolder.dll\0" W("SHGetFolderPath") "\0\0")) {
DEBUG(misc, 0, "Unable to load " W("SHGetFolderPath") "from SHFolder.dll"); DEBUG(misc, 0, "Unable to load " W("SHGetFolderPath") "from either shell32.dll or SHFolder.dll");
}
} }
#undef W #undef W
first_time = false; first_time = false;
@ -752,6 +762,17 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
return (HRESULT)0; 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... */ /* 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) # define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str)
#endif #endif
/* Override SHGetFolderPath with our custom implementation */
#if defined(SHGetFolderPath)
#undef SHGetFolderPath
#endif
#define SHGetFolderPath OTTDSHGetFolderPath
HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR); HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR);
#if defined(__MINGW32__) #if defined(__MINGW32__)

View File

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

View File

@ -2770,6 +2770,14 @@ bool AfterLoadGame()
v->acceleration = avi->acceleration; 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 */ /* Road stops is 'only' updating some caches */

View File

@ -44,7 +44,7 @@
/* static */ bool ScriptBase::Chance(uint out, uint max) /* static */ bool ScriptBase::Chance(uint out, uint max)
{ {
EnforcePrecondition(false, out <= 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) /* 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 unused_param This parameter is not used, but is needed to work with lists.
* @param out How many times it should return true. * @param out How many times it should return true.
* @param max Out of this many times. * @param max Out of this many times.
* @pre \a out is at most equal to \a max.
* @return True if the chance worked out. * @return True if the chance worked out.
*/ */
static bool ChanceItem(int unused_param, uint out, uint max); static bool ChanceItem(int unused_param, uint out, uint max);

View File

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