diff --git a/Makefile.bundle.in b/Makefile.bundle.in index 63edb62d97..a04a0a31e7 100644 --- a/Makefile.bundle.in +++ b/Makefile.bundle.in @@ -45,6 +45,7 @@ bundle: all $(Q)mkdir -p "$(BUNDLE_DIR)/docs" $(Q)mkdir -p "$(BUNDLE_DIR)/media" $(Q)mkdir -p "$(BUNDLE_DIR)/scripts" + $(Q)mkdir -p "$(BUNDLE_DIR)/data" $(Q)mkdir -p "$(TTD_DIR)" $(Q)mkdir -p "$(AI_DIR)" $(Q)mkdir -p "$(GAME_DIR)" @@ -82,6 +83,7 @@ endif $(Q)cp "$(ROOT_DIR)/media/openttd.32.xpm" "$(BUNDLE_DIR)/media/" $(Q)cp "$(ROOT_DIR)/media/openttd."*.png "$(BUNDLE_DIR)/media/" $(Q)cp "$(BIN_DIR)/scripts/"* "$(BUNDLE_DIR)/scripts/" + $(Q)cp "$(BIN_DIR)/data/"*.grf "$(BUNDLE_DIR)/data/" ifdef MENU_DIR $(Q)cp "$(ROOT_DIR)/media/openttd.desktop" "$(BUNDLE_DIR)/media/" $(Q)$(AWK) -f "$(ROOT_DIR)/media/openttd.desktop.translation.awk" "$(SRC_DIR)/lang/"*.txt | $(SORT) | $(AWK) -f "$(ROOT_DIR)/media/openttd.desktop.filter.awk" >> "$(BUNDLE_DIR)/media/openttd.desktop" diff --git a/bin/data/tracerestrict.grf b/bin/data/tracerestrict.grf new file mode 100644 index 0000000000..b71ee80c17 Binary files /dev/null and b/bin/data/tracerestrict.grf differ diff --git a/findversion.sh b/findversion.sh index 6be52b696f..639d2a0eeb 100755 --- a/findversion.sh +++ b/findversion.sh @@ -99,7 +99,7 @@ elif [ -d "$ROOT_DIR/.git" ]; then # No rev? Maybe it is a custom git-svn clone REV_NR=`LC_ALL=C git log --pretty=format:%b --grep="git-svn-id:.*@[0-9]*" -1 | sed "s@.*\@\([0-9]*\).*@\1@"` fi - TAG="`git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed 's@\^0$@@'`" + TAG="`git describe --tags 2>/dev/null`" if [ -n "$TAG" ]; then BRANCH="" REV="$TAG" diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 560f8282c4..cdb1de65ac 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -179,6 +179,9 @@ static void LoadSpriteTables() /* Progsignal sprites. */ LoadGrfFile("progsignals.grf", SPR_PROGSIGNAL_BASE, i++); + /* Tracerestrict sprites. */ + LoadGrfFile("tracerestrict.grf", SPR_TRACERESTRICT_BASE, i++); + /* * The second basic file always starts at the given location and does * contain a different amount of sprites depending on the "type"; DOS diff --git a/src/lang/english.txt b/src/lang/english.txt index 0d0e602c60..b81cec8f15 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1224,8 +1224,8 @@ STR_CONFIG_SETTING_STOP_LOCATION :New train order STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Place where a train will stop at the platform by default. The 'near end' means close to the entry point, 'middle' means in the middle of the platform, and 'far end' means far away from the entry point. Note, that this setting only defines a default value for new orders. Individual orders can be set explicitly to either behaviour nevertheless STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :near end STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :middle -STR_CONFIG_SETTING_IMPROVED_BREAKDOWNS :Enable improved breakdowns: {STRING2} STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :far end +STR_CONFIG_SETTING_IMPROVED_BREAKDOWNS :Enable improved breakdowns: {STRING2} STR_CONFIG_SETTING_AUTOSCROLL :Pan window when mouse is at the edge: {STRING2} STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :When enabled, viewports will start to scroll when the mouse is near the edge of the window STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Disabled diff --git a/src/programmable_signals_gui.cpp b/src/programmable_signals_gui.cpp index ed4c0049f7..29cba83c96 100644 --- a/src/programmable_signals_gui.cpp +++ b/src/programmable_signals_gui.cpp @@ -355,6 +355,7 @@ public: { uint64 p1 = 0; while(true) { + if(si == NULL) break; switch(si->Opcode()) { case PSO_SET_SIGNAL: { SB(p1, 0, 3, this->track); @@ -365,6 +366,7 @@ public: this->RebuildInstructionList(); si = ((SignalSet*)si)->next; } break; + case PSO_IF: { SB(p1, 0, 3, this->track); SB(p1, 3, 16, next); @@ -393,11 +395,15 @@ public: si = ((SignalIf*)si)->after; } break; + + case PSO_LAST: + case PSO_IF_ELSE: + case PSO_IF_ENDIF: + return; + + default: + NOT_REACHED(); } - if(si == NULL) break; - if(si->Opcode() == PSO_LAST) break; - if(si->Opcode() == PSO_IF_ELSE) break; - if(si->Opcode() == PSO_IF_ENDIF) break; } } diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 6cf8db4680..565b79bffd 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1019,7 +1019,9 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return CMD_ERROR; CommandCost ret = EnsureNoTrainOnTrack(GetOtherTunnelBridgeEnd(tile), track); - //if (ret.Failed()) return ret; + if (ret.Failed()) return ret; + ret = EnsureNoTrainOnTrack(tile, track); + if (ret.Failed()) return ret; } else if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); } @@ -1492,6 +1494,8 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 CommandCost ret = EnsureNoTrainOnTrack(GetOtherTunnelBridgeEnd(tile), track); if (ret.Failed()) return ret; + ret = EnsureNoTrainOnTrack(tile, track); + if (ret.Failed()) return ret; } else { if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); @@ -1958,6 +1962,7 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac SignalVariant variant = GetSignalVariant(tile, track); SpriteID sprite = GetCustomSignalSprite(rti, tile, type, variant, condition); + bool is_custom_sprite = (sprite != 0); if (sprite != 0) { sprite += image; } else { @@ -1968,10 +1973,25 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac if (type == SIGTYPE_PROG && variant == SIG_SEMAPHORE) { sprite = SPR_PROGSIGNAL_BASE + image * 2 + condition; + is_custom_sprite = false; } else if (type == SIGTYPE_PROG && variant == SIG_ELECTRIC) { sprite = SPR_PROGSIGNAL_BASE + 16 + image * 2 + condition; + is_custom_sprite = false; + } + + if (!is_custom_sprite && variant == SIG_ELECTRIC && IsRestrictedSignal(tile) && GetExistingTraceRestrictProgram(tile, track) != NULL) { + if (type == SIGTYPE_PBS || type == SIGTYPE_PBS_ONEWAY) { + static const SubSprite lower_part { -50, -10, 50, 50 }; + static const SubSprite upper_part { -50, -50, 50, -11 }; + + AddSortableSpriteToDraw(sprite, SPR_TRACERESTRICT_BASE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track), false, 0, 0, 0, &lower_part); + AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track), false, 0, 0, 0, &upper_part); + } else { + AddSortableSpriteToDraw(sprite, SPR_TRACERESTRICT_BASE + 1, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track)); + } + } else { + AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track)); } - AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track)); } static uint32 _drawtile_track_palette; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 711d9ac7ac..e34d4f3e9e 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -234,7 +234,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @note In general, it is better to use one of the SLE_* macros below. */ #define SLE_GENERAL_X(cmd, base, variable, type, length, from, to, extver) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable), cpp_sizeof(base, variable), extver} -#define SLE_GENERAL(cmd, base, variable, type, length, from, to) SLE_GENERAL_X(cmd, base, variable, type, length, from, to, {}) +#define SLE_GENERAL(cmd, base, variable, type, length, from, to) SLE_GENERAL_X(cmd, base, variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a variable in some savegame versions. @@ -246,7 +246,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLE_CONDVAR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_VAR, base, variable, type, 0, from, to, extver) -#define SLE_CONDVAR(base, variable, type, from, to) SLE_CONDVAR_X(base, variable, type, from, to, {}) +#define SLE_CONDVAR(base, variable, type, from, to) SLE_CONDVAR_X(base, variable, type, from, to, SlXvFeatureTest()) /** * Storage of a reference in some savegame versions. @@ -258,7 +258,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLE_CONDREF_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_REF, base, variable, type, 0, from, to, extver) -#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, {}) +#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, SlXvFeatureTest()) /** * Storage of an array in some savegame versions. @@ -271,7 +271,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLE_CONDARR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_ARR, base, variable, type, length, from, to, extver) -#define SLE_CONDARR(base, variable, type, length, from, to) SLE_CONDARR_X(base, variable, type, length, from, to, {}) +#define SLE_CONDARR(base, variable, type, length, from, to) SLE_CONDARR_X(base, variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a string in some savegame versions. @@ -284,7 +284,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver) -#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, {}) +#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a list in some savegame versions. @@ -296,7 +296,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLE_CONDLST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_LST, base, variable, type, 0, from, to, extver) -#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, {}) +#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, SlXvFeatureTest()) /** * Storage of a variable in every version of a savegame. @@ -354,16 +354,16 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space */ #define SLE_CONDNULL_X(length, from, to, extver) SLE_CONDARR_X(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, extver) -#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, {}) +#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, SlXvFeatureTest()) /** Translate values ingame to different values in the savegame and vv. */ #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value) -#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}} -#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}} +#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, SlXvFeatureTest()} +#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, SlXvFeatureTest()} /** End marker of a struct/class save or load. */ -#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0, {}} +#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0, SlXvFeatureTest()} /** * Storage of global simple variables, references (pointers), and arrays. @@ -376,7 +376,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @note In general, it is better to use one of the SLEG_* macros below. */ #define SLEG_GENERAL_X(cmd, variable, type, length, from, to, extver) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable), extver} -#define SLEG_GENERAL(cmd, variable, type, length, from, to) SLEG_GENERAL_X(cmd, variable, type, length, from, to, {}) +#define SLEG_GENERAL(cmd, variable, type, length, from, to) SLEG_GENERAL_X(cmd, variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a global variable in some savegame versions. @@ -387,7 +387,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLEG_CONDVAR_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_VAR, variable, type, 0, from, to, extver) -#define SLEG_CONDVAR(variable, type, from, to) SLEG_CONDVAR_X(variable, type, from, to, {}) +#define SLEG_CONDVAR(variable, type, from, to) SLEG_CONDVAR_X(variable, type, from, to, SlXvFeatureTest()) /** * Storage of a global reference in some savegame versions. @@ -398,7 +398,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLEG_CONDREF_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_REF, variable, type, 0, from, to, extver) -#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, {}) +#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, SlXvFeatureTest()) /** * Storage of a global array in some savegame versions. @@ -410,7 +410,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLEG_CONDARR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_ARR, variable, type, length, from, to, extver) -#define SLEG_CONDARR(variable, type, length, from, to) SLEG_CONDARR_X(variable, type, length, from, to, {}) +#define SLEG_CONDARR(variable, type, length, from, to) SLEG_CONDARR_X(variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a global string in some savegame versions. @@ -422,7 +422,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLEG_CONDSTR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_STR, variable, type, length, from, to, extver) -#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, {}) +#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, SlXvFeatureTest()) /** * Storage of a global list in some savegame versions. @@ -433,7 +433,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field */ #define SLEG_CONDLST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_LST, variable, type, 0, from, to, extver) -#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, {}) +#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, SlXvFeatureTest()) /** * Storage of a global variable in every savegame version. @@ -477,10 +477,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param to Last savegame version that has the empty space. * @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space */ -#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL, {}} +#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL, SlXvFeatureTest()} /** End marker of global variables save or load. */ -#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0, {}} +#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0, SlXvFeatureTest()} /** * Checks whether the savegame is below \a major.\a minor. diff --git a/src/saveload/signal_sl.cpp b/src/saveload/signal_sl.cpp index e0198b109d..173b484f9f 100644 --- a/src/saveload/signal_sl.cpp +++ b/src/saveload/signal_sl.cpp @@ -23,30 +23,30 @@ typedef std::vector Buffer; static void WriteVLI(Buffer &b, uint i) { - uint lsmask = 0x7F; - uint msmask = ~0x7F; - while(i & msmask) { - byte part = (i & lsmask) | 0x80; - b.push_back(part); - i >>= 7; - } - b.push_back((byte) i); + uint lsmask = 0x7F; + uint msmask = ~0x7F; + while(i & msmask) { + byte part = (i & lsmask) | 0x80; + b.push_back(part); + i >>= 7; + } + b.push_back((byte) i); } static uint ReadVLI() { - uint shift = 0; - uint val = 0; - byte b; + uint shift = 0; + uint val = 0; + byte b; - b = SlReadByte(); - while(b & 0x80) { - val |= uint(b & 0x7F) << shift; - shift += 7; - b = SlReadByte(); - } - val |= uint(b) << shift; - return val; + b = SlReadByte(); + while(b & 0x80) { + val |= uint(b & 0x7F) << shift; + shift += 7; + b = SlReadByte(); + } + val |= uint(b) << shift; + return val; } static void WriteCondition(Buffer &b, SignalCondition *c) @@ -59,13 +59,13 @@ static void WriteCondition(Buffer &b, SignalCondition *c) WriteVLI(b, vc->comparator); WriteVLI(b, vc->value); } break; - + case PSC_SIGNAL_STATE: { SignalStateCondition *sc = static_cast(c); WriteVLI(b, sc->sig_tile); WriteVLI(b, sc->sig_track); } break; - + default: break; } @@ -83,13 +83,13 @@ static SignalCondition *ReadCondition(SignalReference this_sig) c->value = ReadVLI(); return c; } - + case PSC_SIGNAL_STATE: { TileIndex ti = (TileIndex) ReadVLI(); Trackdir td = (Trackdir) ReadVLI(); return new SignalStateCondition(this_sig, ti, td); } - + default: return new SignalSimpleCondition(code); } @@ -111,17 +111,16 @@ static void Save_SPRG() if(i == e) break; } } - + // OK, we can now write out our programs Buffer b; WriteVLI(b, _signal_programs.size()); for(ProgramList::iterator i = _signal_programs.begin(), e = _signal_programs.end(); i != e; ++i) { - SignalReference ref = i->first; SignalProgram *prog = i->second; - + prog->DebugPrintProgram(); - + WriteVLI(b, prog->tile); WriteVLI(b, prog->track); WriteVLI(b, prog->instructions.Length()); @@ -137,44 +136,45 @@ static void Save_SPRG() WriteVLI(b, s->next->Id()); break; } - + case PSO_LAST: break; - + case PSO_IF: { SignalIf *i = static_cast(insn); WriteCondition(b, i->condition); - WriteVLI(b, i->if_true->Id()); + WriteVLI(b, i->if_true->Id()); WriteVLI(b, i->if_false->Id()); WriteVLI(b, i->after->Id()); break; } - + case PSO_IF_ELSE: case PSO_IF_ENDIF: { SignalIf::PseudoInstruction *p = static_cast(insn); WriteVLI(b, p->block->Id()); break; } - + case PSO_SET_SIGNAL: { SignalSet *s = static_cast(insn); WriteVLI(b, s->next->Id()); WriteVLI(b, s->to_state ? 1 : 0); break; } - + default: NOT_REACHED(); } } } - + uint size = b.size(); SlSetLength(size); - for(uint i = 0; i < size; i++) + for(uint i = 0; i < size; i++) { SlWriteByte(b[i]); // TODO Gotta be a better way + } } -// We don't know the pointer values that need to be stored in various +// We don't know the pointer values that need to be stored in various // instruction fields at load time, so we need to instead store the IDs and // then fix them up once all of the instructions have been loaded. // @@ -185,7 +185,7 @@ struct Fixup { Fixup(SignalInstruction **p, SignalOpcode type) : type(type), ptr(p) {} - + SignalOpcode type; SignalInstruction **ptr; }; @@ -205,9 +205,9 @@ static void DoFixups(FixupList &l, InstructionList &il) uint id = reinterpret_cast(*i->ptr); if(id >= il.Length()) NOT_REACHED(); - + *i->ptr = il[id]; - + if(i->type != PSO_INVALID && (*i->ptr)->Opcode() != i->type) { DEBUG(sl, 0, "Expected Id %d to be %d, but was in fact %d", id, i->type, (*i->ptr)->Opcode()); NOT_REACHED(); @@ -224,10 +224,10 @@ static void Load_SPRG() Track track = (Track) ReadVLI(); uint instructions = ReadVLI(); SignalReference ref(tile, track); - + SignalProgram *sp = new SignalProgram(tile, track, true); _signal_programs[ref] = sp; - + for(uint j = 0; j < instructions; j++) { SignalOpcode op = (SignalOpcode) ReadVLI(); switch(op) { @@ -237,24 +237,24 @@ static void Load_SPRG() MakeFixup(l, sp->first_instruction->next, ReadVLI()); break; } - + case PSO_LAST: { sp->last_instruction = new SignalSpecial(sp, PSO_LAST); sp->last_instruction->next = NULL; MakeFixup(l, sp->last_instruction->GetPrevHandle(), ReadVLI()); break; } - + case PSO_IF: { SignalIf *i = new SignalIf(sp, true); MakeFixup(l, i->GetPrevHandle(), ReadVLI()); i->condition = ReadCondition(ref); - MakeFixup(l, i->if_true, ReadVLI()); - MakeFixup(l, i->if_false, ReadVLI()); - MakeFixup(l, i->after, ReadVLI()); + MakeFixup(l, i->if_true, ReadVLI()); + MakeFixup(l, i->if_false, ReadVLI()); + MakeFixup(l, i->after, ReadVLI()); break; } - + case PSO_IF_ELSE: case PSO_IF_ENDIF: { SignalIf::PseudoInstruction *p = new SignalIf::PseudoInstruction(sp, op); @@ -262,7 +262,7 @@ static void Load_SPRG() MakeFixup(l, p->block, ReadVLI(), PSO_IF); break; } - + case PSO_SET_SIGNAL: { SignalSet *s = new SignalSet(sp); MakeFixup(l, s->GetPrevHandle(), ReadVLI()); @@ -271,11 +271,11 @@ static void Load_SPRG() if(s->to_state > SIGNAL_STATE_MAX) NOT_REACHED(); break; } - + default: NOT_REACHED(); } } - + DoFixups(l, sp->instructions); sp->DebugPrintProgram(); } diff --git a/src/table/company_settings.ini b/src/table/company_settings.ini index 463455c2c0..d15b07a76a 100644 --- a/src/table/company_settings.ini +++ b/src/table/company_settings.ini @@ -34,7 +34,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/table/currency_settings.ini b/src/table/currency_settings.ini index 3c476ee5df..6a8665379a 100644 --- a/src/table/currency_settings.ini +++ b/src/table/currency_settings.ini @@ -28,7 +28,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini index 9e5fa3d0ff..a5bc766ecb 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/gameopt_settings.ini @@ -62,7 +62,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini index b58d9a962c..c77eba5ad0 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -35,7 +35,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/table/settings.ini b/src/table/settings.ini index 124e8b68ba..ba200d5cab 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -96,7 +96,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() patxname = NULL xref = diff --git a/src/table/sprites.h b/src/table/sprites.h index 529b24635c..0d8a09a81c 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -318,8 +318,12 @@ static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_LIGHT_BLUE = SPR_ZONING_INNER_H static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_ORANGE = SPR_ZONING_INNER_HIGHLIGHT_BASE + 23; static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_WHITE = SPR_ZONING_INNER_HIGHLIGHT_BASE + 24; +/* Tracerestrict sprites */ +static const SpriteID SPR_TRACERESTRICT_BASE = SPR_ZONING_INNER_HIGHLIGHT_BASE + ZONING_INNER_HIGHLIGHT_SPRITE_COUNT; +static const uint16 TRACERESTRICT_SPRITE_COUNT = 2; + /* From where can we start putting NewGRFs? */ -static const SpriteID SPR_NEWGRFS_BASE = SPR_ZONING_INNER_HIGHLIGHT_BASE + ZONING_INNER_HIGHLIGHT_SPRITE_COUNT; +static const SpriteID SPR_NEWGRFS_BASE = SPR_TRACERESTRICT_BASE + TRACERESTRICT_SPRITE_COUNT; /* Manager face sprites */ static const SpriteID SPR_GRADIENT = 874; // background gradient behind manager face diff --git a/src/table/win32_settings.ini b/src/table/win32_settings.ini index 6f62db63f6..a22e1a54e7 100644 --- a/src/table/win32_settings.ini +++ b/src/table/win32_settings.ini @@ -33,7 +33,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/table/window_settings.ini b/src/table/window_settings.ini index 4565d9b35f..a7b1742040 100644 --- a/src/table/window_settings.ini +++ b/src/table/window_settings.ini @@ -29,7 +29,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED -extver = {} +extver = SlXvFeatureTest() diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 572df33851..567413dc00 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1314,7 +1314,7 @@ public: /* list house sets */ this->house_sets.Clear(); - const GRFFile *last_set; + const GRFFile *last_set = NULL; for (uint i = 0; i < this->Length(); i++) { const HouseSpec *hs = HouseSpec::Get((*this)[i]); /* add house set */ diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index edad87128f..10fa437e41 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -49,11 +49,10 @@ * This is not done for shared programs as this would delete the shared aspect whenever * the program became empty. * - * Empty programs with a refcount of 1 may still exist due to the edge case where: - * 1: There is an empty program with refcount 2 - * 2: One of the two mappings is deleted - * Finding the other mapping would entail a linear search of the mappings, and there is little - * to be gained by doing so. + * Special case: In the case where an empty program with refcount 2 has one of its + * mappings removed, the other mapping is left pointing to an empty unshared program. + * This other mapping is then removed by performing a linear search of the mappings, + * and removing the reference to that program ID. */ TraceRestrictProgramPool _tracerestrictprogram_pool("TraceRestrictProgram"); @@ -604,7 +603,13 @@ void TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) TraceRestrictMapping::iterator iter = _tracerestrictprogram_mapping.find(ref); if (iter != _tracerestrictprogram_mapping.end()) { // Found - _tracerestrictprogram_pool.Get(iter->second.program_id)->DecrementRefCount(); + TraceRestrictProgram *prog = _tracerestrictprogram_pool.Get(iter->second.program_id); + + // check to see if another mapping needs to be removed as well + // do this before decrementing the refcount + bool remove_other_mapping = prog->refcount == 2 && prog->items.empty(); + + prog->DecrementRefCount(); _tracerestrictprogram_mapping.erase(iter); TileIndex tile = GetTraceRestrictRefIdTileIndex(ref); @@ -612,6 +617,17 @@ void TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) TraceRestrictSetIsSignalRestrictedBit(tile); MarkTileDirtyByTile(tile); YapfNotifyTrackLayoutChange(tile, track); + + if (remove_other_mapping) { + TraceRestrictProgramID id = prog->index; + for (TraceRestrictMapping::iterator rm_iter = _tracerestrictprogram_mapping.begin(); + rm_iter != _tracerestrictprogram_mapping.end(); ++rm_iter) { + if (rm_iter->second.program_id == id) { + TraceRestrictRemoveProgramMapping(rm_iter->first); + break; + } + } + } } }