diff --git a/Makefile.bundle.in b/Makefile.bundle.in index 446890a522..08e7a33dc5 100644 --- a/Makefile.bundle.in +++ b/Makefile.bundle.in @@ -156,7 +156,7 @@ bundle_dmg: bundle bundle_exe: all @echo '[BUNDLE] Creating $(BUNDLE_NAME).exe' $(Q)mkdir -p "$(BUNDLES_DIR)" - $(Q)unix2dos "$(ROOT_DIR)/docs/"* "$(ROOT_DIR)/readme.txt" "$(ROOT_DIR)/COPYING" "$(ROOT_DIR)/changelog.txt" "$(ROOT_DIR)/known-bugs.txt" + $(Q)unix2dos "$(ROOT_DIR)/docs/"*.txt "$(ROOT_DIR)/readme.txt" "$(ROOT_DIR)/COPYING" "$(ROOT_DIR)/changelog.txt" "$(ROOT_DIR)/known-bugs.txt" $(Q)cd $(ROOT_DIR)/os/windows/installer && makensis.exe //DVERSION_INCLUDE=version_$(PLATFORM).txt install.nsi $(Q)mv $(ROOT_DIR)/os/windows/installer/*$(PLATFORM).exe "$(BUNDLES_DIR)/$(BUNDLE_NAME).exe" diff --git a/Makefile.grf.in b/Makefile.grf.in index a223bd5962..b3f1e3ae56 100644 --- a/Makefile.grf.in +++ b/Makefile.grf.in @@ -23,6 +23,7 @@ GRF_DIR = $(ROOT_DIR)/media/extra_grf BIN_DIR = !!BIN_DIR!!/data OBJS_DIR = !!GRF_OBJS_DIR!! OS = !!OS!! +STAGE = !!STAGE!! # Check if we want to show what we are doing ifdef VERBOSE @@ -34,8 +35,10 @@ else endif # Some configurational settings for your environment. -GRFCODEC := grfcodec -NFORENUM := $(shell [ `which nforenum 2>/dev/null` ] && echo "nforenum" || echo "renum") +# If GRFCodec doesn't know a command, it'll exit with a non-zero exit code. +GRFCODEC := $(shell grfcodec -s -v >/dev/null 2>/dev/null && echo "grfcodec -s" || echo "grfcodec") +# Old NFORenums don't give an error code when a parameter isn't known, so we have to work around that. +NFORENUM := $(shell [ `nforenum -s -v 2>/dev/null | wc -l ` -eq 1 ] && echo "nforenum -s" || echo "nforenum") MD5SUM := $(shell [ "$(OS)" = "OSX" ] && echo "md5 -r" || echo "md5sum") # Some "should not be changed" settings. @@ -55,11 +58,14 @@ $(BIN_DIR)/openttdd.grf: $(PCX_FILES) $(NFO_FILES) $(OBJS_DIR)/sprites # Yeah, we'd like to use -i in the sed, but Mac OS X's sed and GNU sed just can't agree on the usage of -i. In any case either one of them fails. $(OBJS_DIR)/openttdd.grf: $(PCX_FILES) $(NFO_FILES) $(OBJS_DIR)/sprites + $(E) '$(STAGE) Assembling openttdd.nfo' $(Q)-cp $(PCX_FILES) $(OBJS_DIR)/sprites 2> /dev/null $(Q) gcc -DDOS -I$(GRF_DIR) -C -E - < "$(GRF_DIR)/openttd.nfo" | sed -e '/^#/d' -e '/^$$/d' > $(OBJS_DIR)/sprites/openttdd.nfo $(Q) $(NFORENUM) $(OBJS_DIR)/sprites/openttdd.nfo + $(E) '$(STAGE) Compiling openttdd.grf' $(Q) $(GRFCODEC) -e -m1 $(OBJS_DIR)/openttdd.grf $(Q) cp $(OBJS_DIR)/openttdd.grf $(BIN_DIR)/openttdd.grf + $(E) '$(STAGE) Updating base graphics sets for DOS graphics' $(Q) for grf in $(BIN_DIR)/orig_dos*.obg; do sed 's/^OPENTTDD.GRF = [0-9a-f]*$$/OPENTTDD.GRF = '`$(MD5SUM) $(BIN_DIR)/openttdd.grf | sed 's@ .*@@'`'/' $$grf > $$grf.tmp && mv $$grf.tmp $$grf; done $(BIN_DIR)/openttdw.grf: $(PCX_FILES) $(NFO_FILES) $(OBJS_DIR)/sprites @@ -67,11 +73,14 @@ $(BIN_DIR)/openttdw.grf: $(PCX_FILES) $(NFO_FILES) $(OBJS_DIR)/sprites $(Q) ($(NFORENUM) -? > /dev/null 2>&1 && $(MAKE) $(OBJS_DIR)/openttdw.grf && cp $(OBJS_DIR)/openttdw.grf $(BIN_DIR)/openttdw.grf) || ([ -e $(BIN_DIR)/openttdw.grf ] && touch $(BIN_DIR)/openttdw.grf && echo "no NFORenum and GRFCodec found, skipping rebuild of openttdw.grf...") || (echo "no NFORenum and GRFCodec found, but no openttdw.grf either. Install NFORenum and GRFCodec." && exit 1) $(OBJS_DIR)/openttdw.grf: $(PCX_FILES) $(NFO_FILES) $(OBJS_DIR)/sprites + $(E) '$(STAGE) Assembling openttdw.nfo' $(Q)-cp $(PCX_FILES) $(OBJS_DIR)/sprites 2> /dev/null $(Q) gcc -I$(GRF_DIR) -C -E - < "$(GRF_DIR)/openttd.nfo" | sed -e '/^#/d' -e '/^$$/d' > $(OBJS_DIR)/sprites/openttdw.nfo $(Q) $(NFORENUM) $(OBJS_DIR)/sprites/openttdw.nfo + $(E) '$(STAGE) Compiling openttdw.grf' $(Q) $(GRFCODEC) -e -p2 $(OBJS_DIR)/openttdw.grf $(Q) cp $(OBJS_DIR)/openttdw.grf $(BIN_DIR)/openttdw.grf + $(E) '$(STAGE) Updating base graphics sets for Windows graphics' $(Q) for grf in $(BIN_DIR)/orig_win.obg; do sed 's/^OPENTTDW.GRF = [0-9a-f]*$$/OPENTTDW.GRF = '`$(MD5SUM) $(BIN_DIR)/openttdw.grf | sed 's@ .*@@'`'/' $$grf > $$grf.tmp && mv $$grf.tmp $$grf; done # Clean up temporary files. diff --git a/known-bugs.txt b/known-bugs.txt index 28d981a7df..ae898b1802 100644 --- a/known-bugs.txt +++ b/known-bugs.txt @@ -117,6 +117,14 @@ Clipping problems [FS#119] leave the Transport Tycoon graphics, which in effect means OpenTTD will not be a Transport Tycoon clone anymore. +Mouse scrolling not possible at the edges of the screen [FS#383] [FS#3966] + Scrolling the viewport with the mouse cursor at the edges of the screen + in the same direction of the edge will fail. If the cursor is near the + edge the scrolling will be very slow. + OpenTTD only receives cursor position updates when the cursor is inside + OpenTTD's window. It is not told how far you have moved the cursor + outside of OpenTTD's window. + Lost trains ignore (block) exit signals [FS#1473] If trains are lost they ignore block exit signals, blocking junctions with presignals. This is caused because the path finders cannot tell @@ -211,6 +219,19 @@ OpenTTD not properly resizing with SDL on X [FS#3305] and GNOME's. With the XFCE's and LXDE's window managers the resize event is sent when the user releases the mouse. +Train crashes entering same junction from block and path signals [FS#3928] + When a train has reserved a path from a path signal to a two way + block signal and the reservation passes a path signal through the + back another train can enter the reserved path (only) via that same + two way block signal. + The reason for this has to do with optimisation; to fix this issue + the signal update has to pass all path signals until it finds either + a train or a backwards facing signal. This is a very expensive task. + The (signal) setups that allow these crashes can furthermore be + considered incorrectly signalled; one extra safe waiting point for + the train entering from path signal just after the backwards facing + signal (from the path signal train) resolves the issue. + Crashes when playing music [FS#3941] Mac OS X's QuickTime (default music driver) and Windows' MCI (win32 music driver) crash on some songs from OpenMSX. OpenTTD cannot do diff --git a/src/base_media_base.h b/src/base_media_base.h index 4cf5ed8ede..273739cb9e 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -147,6 +147,7 @@ template class BaseMedia : FileScanner { protected: static Tbase_set *available_sets; ///< All available sets + static Tbase_set *duplicate_sets; ///< All sets that aren't available, but needed for not downloading base sets when a newer version than the one on BaNaNaS is loaded. static const Tbase_set *used_set; ///< The currently used set /* virtual */ bool AddFile(const char *filename, size_t basepath_length); diff --git a/src/base_media_func.h b/src/base_media_func.h index a6071f4f04..c7b3a471f9 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -17,6 +17,7 @@ template /* static */ const char *BaseMedia::ini_set; template /* static */ const Tbase_set *BaseMedia::used_set; template /* static */ Tbase_set *BaseMedia::available_sets; +template /* static */ Tbase_set *BaseMedia::duplicate_sets; /** * Try to read a single piece of metadata and return false if it doesn't exist. @@ -169,15 +170,14 @@ bool BaseMedia::AddFile(const char *filename, size_t basepath_length) if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) || duplicate->valid_files > set->valid_files) { DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate)", set->name, set->version); - delete set; + set->next = BaseMedia::duplicate_sets; + BaseMedia::duplicate_sets = set; } else { Tbase_set **prev = &BaseMedia::available_sets; while (*prev != duplicate) prev = &(*prev)->next; *prev = set; set->next = duplicate->next; - /* don't allow recursive delete of all remaining items */ - duplicate->next = NULL; /* If the duplicate set is currently used (due to rescanning this can happen) * update the currently used set to the new one. This will 'lie' about the @@ -185,7 +185,8 @@ bool BaseMedia::AddFile(const char *filename, size_t basepath_length) if (BaseMedia::used_set == duplicate) BaseMedia::used_set = set; DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate)", duplicate->name, duplicate->version); - delete duplicate; + duplicate->next = BaseMedia::duplicate_sets; + BaseMedia::duplicate_sets = duplicate; ret = true; } } else { @@ -254,10 +255,9 @@ template #if defined(ENABLE_NETWORK) #include "network/network_content.h" -template -/* static */ bool BaseMedia::HasSet(const ContentInfo *ci, bool md5sum) +template bool HasBaseSet(const ContentInfo *ci, bool md5sum, const Tbase_set *s) { - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (; s != NULL; s = s->next) { if (s->GetNumMissing() != 0) continue; if (s->shortname != ci->unique_id) continue; @@ -276,6 +276,13 @@ template return false; } +template +/* static */ bool BaseMedia::HasSet(const ContentInfo *ci, bool md5sum) +{ + return HasBaseSet(ci, md5sum, BaseMedia::available_sets) || + HasBaseSet(ci, md5sum, BaseMedia::duplicate_sets); +} + #else template diff --git a/src/livery.h b/src/livery.h index 5688efd21d..489e7b0082 100644 --- a/src/livery.h +++ b/src/livery.h @@ -14,6 +14,10 @@ #include "company_type.h" +static const byte LIT_NONE = 0; ///< Don't show the liveries at all +static const byte LIT_COMPANY = 1; ///< Show the liveries of your own company +static const byte LIT_ALL = 2; ///< Show the liveries of all companies + /* List of different livery schemes. */ enum LiveryScheme { LS_BEGIN = 0, diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 78b1567bd5..6e7d9e01e6 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -825,7 +825,7 @@ struct TooltipsWindow : public Window * go below window, flip it so it is shown above the cursor */ pt.y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, scr_top, scr_bot); if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.offs.y - 5, scr_bot) - sm_height; - pt.x = Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width); + pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width); return pt; } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 34abf99fc8..cc34ad088d 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -449,13 +449,13 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v) if (v == NULL) { if (!Company::IsValidID(_current_company)) return 0; - l = GetEngineLivery(engine, _current_company, INVALID_ENGINE, NULL); + l = GetEngineLivery(engine, _current_company, INVALID_ENGINE, NULL, LIT_ALL); } else if (v->type == VEH_TRAIN) { - l = GetEngineLivery(v->engine_type, v->owner, Train::From(v)->tcache.first_engine, v); + l = GetEngineLivery(v->engine_type, v->owner, Train::From(v)->tcache.first_engine, v, LIT_ALL); } else if (v->type == VEH_ROAD) { - l = GetEngineLivery(v->engine_type, v->owner, RoadVehicle::From(v)->rcache.first_engine, v); + l = GetEngineLivery(v->engine_type, v->owner, RoadVehicle::From(v)->rcache.first_engine, v, LIT_ALL); } else { - l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v); + l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v, LIT_ALL); } return l->colour1 + l->colour2 * 16; diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 025bc40430..93363e513b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -752,6 +752,9 @@ CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 * on his order list or not */ if (sel_ord == u->cur_order_index && u->current_order.IsType(OT_LOADING)) { u->current_order.SetNonStopType(ONSF_STOP_EVERYWHERE); + /* When full loading, "cancel" that order so the vehicle doesn't + * stay indefinitely at this station anymore. */ + if (u->current_order.GetLoadType() & OLFB_FULL_LOAD) u->current_order.SetLoadType(OLF_LOAD_IF_POSSIBLE); } /* Update any possible open window of the vehicle */ diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 0bd963e011..fece94bcd5 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -559,6 +559,9 @@ bool AfterLoadGame() default: break; } + /* The value of _date_fract got divided, so make sure that old games are converted correctly. */ + if (CheckSavegameVersionOldStyle(11, 1)) _date_fract /= 885; + /* Update current year * must be done before loading sprites as some newgrfs check it */ SetDate(_date); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 26058c44e6..fccd8b9844 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1334,9 +1334,10 @@ bool CanBuildVehicleInfrastructure(VehicleType type) * @param company Owner of the vehicle * @param parent_engine_type EngineID of the front vehicle. INVALID_VEHICLE if vehicle is at front itself. * @param v the vehicle. NULL if in purchase list etc. + * @param livery_setting The livery settings to use for acquiring the livery information. * @return livery to use */ -const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v) +const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting) { const Company *c = Company::Get(company); LiveryScheme scheme = LS_DEFAULT; @@ -1344,7 +1345,7 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID /* The default livery is always available for use, but its in_use flag determines * whether any _other_ liveries are in use. */ - if (c->livery[LS_DEFAULT].in_use && (_settings_client.gui.liveries == 2 || (_settings_client.gui.liveries == 1 && company == _local_company))) { + if (c->livery[LS_DEFAULT].in_use && (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company))) { /* Determine the livery scheme to use */ const Engine *e = Engine::Get(engine_type); switch (e->type) { @@ -1471,7 +1472,7 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */ if (!Company::IsValidID(company)) return map; - const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v); + const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries); map += livery->colour1; if (twocc) map += livery->colour2 * 16; diff --git a/src/vehicle_func.h b/src/vehicle_func.h index efb217b993..8615c36be2 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -92,7 +92,7 @@ static inline bool IsCompanyBuildableVehicleType(const BaseVehicle *v) return IsCompanyBuildableVehicleType(v->type); } -const struct Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v); +const struct Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting); /** * Get the colour map for an engine. This used for unbuilt engines in the user interface.