diff --git a/macros.h b/macros.h --- a/macros.h +++ b/macros.h @@ -130,7 +130,14 @@ extern uint SafeTileAdd(uint x, int add, #define SPRITE_PALETTE(x) ((x) + 0x8000) extern const byte _ffb_64[128]; +/* Returns the position of the first bit that is not zero, counted from the + * left. Ie, 10110100 returns 2, 00000001 returns 0, etc. When x == 0 returns + * 0. + */ #define FIND_FIRST_BIT(x) _ffb_64[(x)] +/* Returns x with the first bit that is not zero, counted from the left, set + * to zero. So, 10110100 returns 10110000, 00000001 returns 00000000, etc. + */ #define KILL_FIRST_BIT(x) _ffb_64[(x)+64] static INLINE int FindFirstBit2x64(int value) @@ -212,4 +219,6 @@ static INLINE void WRITE_LE_UINT16(const ((byte*)b)[1] = (byte)(x >> 8); } +#define MAX_DETOUR 6 + #endif /* MACROS_H */ diff --git a/pathfind.c b/pathfind.c --- a/pathfind.c +++ b/pathfind.c @@ -187,6 +187,9 @@ continue_here:; static const int8 _get_tunlen_inc[5] = { -16, 0, 16, 0, -16 }; +/* Returns the end tile and the length of a tunnel. The length does not + * include the starting tile (entry), it does include the end tile (exit). + */ FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction, byte type) { FindLengthOfTunnelResult flotr; diff --git a/rail_cmd.c b/rail_cmd.c --- a/rail_cmd.c +++ b/rail_cmd.c @@ -8,7 +8,7 @@ void ShowTrainDepotWindow(uint tile); -enum { +enum { /* These values are bitmasks for the map5 byte */ RAIL_TYPE_NORMAL = 0, RAIL_TYPE_SIGNALS = 0x40, RAIL_TYPE_SPECIAL = 0x80, // If this bit is set, then it's not a regular track. @@ -40,6 +40,9 @@ enum { * 01 abcdef => Rail with signals * 10 ?????? => Unused * 11 ????dd => Depot + * + * abcdef is a bitmask, which contains ones for all present tracks. Below the + * value for each track is given. */ /* 4 @@ -77,8 +80,12 @@ enum RailMap2Lower4 { }; -/* MAP2 byte: abcd???? => Signal On? - * MAP3LO byte: abcd???? => Signal Exists? +/* MAP2 byte: abcd???? => Signal On? Same coding as map3lo + * MAP3LO byte: abcd???? => Signal Exists? + * a and b are for diagonals, upper and left, + * one for each direction. (ie a == NE->SW, b == + * SW->NE, or v.v., I don't know. b and c are + * similar for lower and right. * MAP2 byte: ????abcd => Type of ground. * MAP3LO byte: ????abcd => Type of rail. * MAP5: 00abcdef => rail @@ -1796,6 +1803,7 @@ static uint32 GetTileTrackStatus_Track(u ret = (m5 | (m5 << 8)) & 0x3F3F; if (!(m5 & RAIL_TYPE_SIGNALS)) { if ( (ret & 0xFF) == 3) + /* Diagonal crossing? */ ret |= 0x40; } else { /* has_signals */ @@ -1805,6 +1813,10 @@ static uint32 GetTileTrackStatus_Track(u b &= a; + /* When signals are not present (in neither + * direction), we pretend them to be green. (So if + * signals are only one way, the other way will + * implicitely become `red' */ if ((a & 0xC0) == 0) { b |= 0xC0; } if ((a & 0x30) == 0) { b |= 0x30; } diff --git a/road_cmd.c b/road_cmd.c --- a/road_cmd.c +++ b/road_cmd.c @@ -7,6 +7,10 @@ #include "town.h" #include "gfx.h" +/* When true, GetTrackStatus for roads will treat roads under reconstruction + * as normal roads instead of impassable. This is used when detecting whether + * a road can be removed. This is of course ugly, but I don't know a better + * solution just like that... */ static bool _road_special_gettrackstatus; void RoadVehEnterDepot(Vehicle *v); diff --git a/station_cmd.c b/station_cmd.c --- a/station_cmd.c +++ b/station_cmd.c @@ -2232,8 +2232,8 @@ uint MoveGoodsToStation(uint tile, int w st->blocked_months == 0 && st->goods[type].rating != 0 && (!_patches.selectgoods || st->goods[type].last_speed) && // if last_speed is 0, no vehicle has been there. - ((st->facilities & (byte)~FACIL_BUS_STOP)!=0 || type==CT_PASSENGERS) && - ((st->facilities & (byte)~FACIL_TRUCK_STOP)!=0 || type!=CT_PASSENGERS)) { + ((st->facilities & (byte)~FACIL_BUS_STOP)!=0 || type==CT_PASSENGERS) && // if we have other fac. than a bus stop, or the cargo is passengers + ((st->facilities & (byte)~FACIL_TRUCK_STOP)!=0 || type!=CT_PASSENGERS)) { // if we have other fac. than a cargo bay or the cargo is not passengers around[i] = st_index; around_ptr[i] = st; diff --git a/train_cmd.c b/train_cmd.c --- a/train_cmd.c +++ b/train_cmd.c @@ -1921,6 +1921,12 @@ static int CountPassengersInTrain(Vehicl return num; } +/* + * Checks whether the specified tried has a collision with another vehicle. If + * so, destroys this vehicle, and the other vehicle if its subtype is 0 (?). + * Reports the incident in a flashy news item, modifies station ratings and + * plays a sound. + */ static void CheckTrainCollision(Vehicle *v) { TrainCollideChecker tcc; @@ -1991,18 +1997,20 @@ static void TrainController(Vehicle *v) byte chosen_track; byte old_z; + /* For every vehicle after and including the given vehicle */ for(;;) { BeginVehicleMove(v); if (v->u.rail.track != 0x40) { + /* Not inside tunnel */ if (GetNewVehiclePos(v, &gp)) { - /* Statying in the old tile */ + /* Staying in the old tile */ if (v->u.rail.track == 0x80) { /* inside depot */ gp.x = v->x_pos; gp.y = v->y_pos; } else { - /* isnot inside depot */ + /* is not inside depot */ r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); if (r & 0x8) goto invalid_rail; @@ -2079,6 +2087,8 @@ static void TrainController(Vehicle *v) if (v->subtype == 0) TrainMovedChangeSignals(gp.new_tile, dir>>1); + /* Signals can only change when the first + * (above) or the last vehicle moves. */ if (v->next == NULL) TrainMovedChangeSignals(gp.old_tile, (dir>>1) ^ 2); @@ -2117,24 +2127,27 @@ common:; old_z = AfterSetTrainPos(v); if (prev == NULL) { + /* This is the first vehicle in the train */ AffectSpeedByZChange(v, old_z); CheckTrainCollision(v); } +next_vehicle:; /* continue with next vehicle */ -next_vehicle:; prev = v; if ((v=v->next) == NULL) return; } invalid_rail: + /* We've reached end of line?? */ if (prev != NULL) { error("!Disconnecting train"); } goto reverse_train_direction; red_light: { + /* We're in front of a red signal ?? */ /* find the first set bit in ts. need to do it in 2 steps, since * FIND_FIRST_BIT only handles 6 bits at a time. */ i = FindFirstBit2x64(ts); @@ -2307,14 +2320,17 @@ static void TrainCheckIfLineEnds(Vehicle if (IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile] & 0xFC) == 0xC0) return; - // determine the tracks on the next tile. + /* Determine the non-diagonal direction in which we will exit this tile */ t = v->direction >> 1; if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[t]) { t = (t - 1) & 3; } + /* Calculate next tile */ tile += _tileoffs_by_dir[t]; + // determine the track status on the next tile. ts = GetTileTrackStatus(tile, 0) & _reachable_tracks[t]; + /* Calc position within the current tile ?? */ x = v->x_pos & 0xF; y = v->y_pos & 0xF; diff --git a/train_gui.c b/train_gui.c --- a/train_gui.c +++ b/train_gui.c @@ -316,8 +316,10 @@ static void DrawTrainDepotWindow(Window --num < 0 && num >= -6) { DrawTrainImage(v, x+21, y, 10, w->hscroll.pos, WP(w,traindepot_d).sel); + /* Draw the train number */ SET_DPARAM16(0, v->unitnumber); DrawString(x, y, (v->max_age - 366 < v->age) ? STR_00E3 : STR_00E2, 0); + /* Draw the pretty flag */ DrawSprite(v->vehstatus&VS_STOPPED ? 0xC12 : 0xC13, x+15, y); y += 14; diff --git a/ttd.h b/ttd.h --- a/ttd.h +++ b/ttd.h @@ -236,6 +236,10 @@ typedef void ClickTileProc(uint tile); typedef void AnimateTileProc(uint tile); typedef void TileLoopProc(uint tile); typedef void ChangeTileOwnerProc(uint tile, byte old_player, byte new_player); +/* Return value has bit 0x2 set, when the vehicle enters a station. Then, + * result << 8 contains the id of the station entered. If the return value has + * bit 0x8 set, the vehicle could not and did not enter the tile. Are there + * other bits that can be set? */ typedef uint32 VehicleEnterTileProc(Vehicle *v, uint tile, int x, int y); typedef void VehicleLeaveTileProc(Vehicle *v, uint tile, int x, int y); diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -1388,6 +1388,7 @@ static uint32 VehicleEnter_TunnelBridge( } if (dir == (vdir^2) && fc == _tunnel_fractcoord_3[dir] && z == 0) { + /* We're at the tunnel exit ?? */ v->tile = tile; v->u.rail.track = _exit_tunnel_track[dir]; v->vehstatus &= ~VS_HIDDEN; @@ -1413,6 +1414,7 @@ static uint32 VehicleEnter_TunnelBridge( } if (dir == (vdir^2) && ( + /* We're at the tunnel exit ?? */ fc == _tunnel_fractcoord_6[dir] || fc == _tunnel_fractcoord_7[dir]) && z == 0) { diff --git a/vehicle.c b/vehicle.c --- a/vehicle.c +++ b/vehicle.c @@ -1458,11 +1458,18 @@ byte GetDirectionTowards(Vehicle *v, int return (dir+((dirdiff&7)<5?1:-1)) & 7; } +/* Return value has bit 0x2 set, when the vehicle enters a station. Then, + * result << 8 contains the id of the station entered. If the return value has + * bit 0x8 set, the vehicle could not and did not enter the tile. Are there + * other bits that can be set? */ uint32 VehicleEnterTile(Vehicle *v, uint tile, int x, int y) { uint old_tile = v->tile; uint32 result = _tile_type_procs[GET_TILETYPE(tile)]->vehicle_enter_tile_proc(v, tile, x, y); + /* When vehicle_enter_tile_proc returns 8, that apparently means that + * we cannot enter the tile at all. In that case, don't call + * leave_tile. */ if (!(result & 8) && old_tile != tile) { VehicleLeaveTileProc *proc = _tile_type_procs[GET_TILETYPE(old_tile)]->vehicle_leave_tile_proc; if (proc != NULL) diff --git a/vehicle.h b/vehicle.h --- a/vehicle.h +++ b/vehicle.h @@ -85,7 +85,7 @@ struct WorldSprite { struct Vehicle { byte type; // type, ie roadven,train,ship,aircraft,special - byte subtype; // subtype + byte subtype; // subtype (for trains, 0 == loco, 4 wagon ??) uint16 index; // NOSAVE: Index in vehicle array uint16 next_in_chain_old; // Next vehicle index for chained vehicles