/** * (Re)allocates a map with the given dimension * @param size_x the width of the map along the NE/SW edge * @param size_y the 'height' of the map along the SE/NW edge */ void AllocateMap(uint size_x, uint size_y) { /* Make sure that the map size is within the limits and that * size of both axes is a power of 2. */ if (!IsInsideMM(size_x, MIN_MAP_SIZE, MAX_MAP_SIZE + 1) || !IsInsideMM(size_y, MIN_MAP_SIZE, MAX_MAP_SIZE + 1) || (size_x & (size_x - 1)) != 0 || (size_y & (size_y - 1)) != 0) { error("Invalid map size"); } DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); _map_log_x = FindFirstBit(size_x); _map_log_y = FindFirstBit(size_y); _map_size_x = size_x; _map_size_y = size_y; _map_size = size_x * size_y; _map_tile_mask = _map_size - 1; free(_m); free(_me); _m = CallocT<Tile>(_map_size); _me = CallocT<TileExtended>(_map_size); }
/** * (Re)allocates a map with the given dimension * @param size_x the width of the map along the NE/SW edge * @param size_y the 'height' of the map along the SE/NW edge */ void AllocateMap(uint size_x, uint size_y) { DEBUG(map, 2, "Min/max map size %d/%d, max map tiles %d", MIN_MAP_SIZE, MAX_MAP_SIZE, MAX_MAP_TILES); DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); /* Make sure that the map size is within the limits and that * size of both axes is a power of 2. */ if (size_x * size_y > MAX_MAP_TILES || size_x < MIN_MAP_SIZE || size_y < MIN_MAP_SIZE || (size_x & (size_x - 1)) != 0 || (size_y & (size_y - 1)) != 0) { error("Invalid map size"); } DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); _main_map.log_x = FindFirstBit(size_x); _main_map.log_y = FindFirstBit(size_y); _main_map.size_x = size_x; _main_map.size_y = size_y; _main_map.size = size_x * size_y; _main_map.tile_mask = _main_map.size - 1; free(_main_map.m); free(_main_map.me); _main_map.m = CallocT<Tile>(_main_map.size); _main_map.me = CallocT<TileExtended>(_main_map.size); }
/* * Clear out the hcache for this particular file * from all the client nodes' hcaches. * We ensure that the owner who issued the operation * is not called back. */ void cb_clear_hashes(char *fname, unsigned long bitmap, int owner_cb_id) { int i; if (fname == NULL) { return; } LOG(stderr, DEBUG_MSG, SUBSYS_META, "cb_clear_hashes called by owner %d for %s\n", owner_cb_id, fname); i = FindFirstBit((unsigned char *)&bitmap, sizeof(bitmap)); while (i >= 0) { CLIENT **pclnt; /* i is the cb_index using which we can now make RPC callbacks */ if (i == owner_cb_id) { LOG(stderr, DEBUG_MSG, SUBSYS_META, "skipping callback id %d\n", i); i = FindNextBit((unsigned char *)&bitmap, 4, i + 1); continue; } LOG(stderr, DEBUG_MSG, SUBSYS_META, "callback id %d\n", i); pclnt = get_cb_handle(i); if (*pclnt == NULL) { errno = ECONNREFUSED; } else { enum clnt_stat result; inv_args arg; inv_resp resp; arg.id.type = FILEBYNAME; arg.id.identify_u.name = fname; /* Special callback identifier to indicate entire file */ arg.begin_chunk = -1; arg.nchunks = 0; result = capfsd_invalidate_1(arg, &resp, *pclnt); if (result != RPC_SUCCESS) { LOG(stderr, DEBUG_MSG, SUBSYS_META, "capfsd_invalidate_1 [2] to %d returned %d\n", i, result); clnt_perror(*pclnt, "capfs_invalidate_1 [2] :"); /* make it reconnect */ put_cb_handle(pclnt, 1); } else { LOG(stderr, DEBUG_MSG, SUBSYS_META, "capfsd_invalidate_1 [2] to %d returned %d\n", i, resp.status); put_cb_handle(pclnt, 0); } } i = FindNextBit((unsigned char *)&bitmap, 4, i + 1); } return; }
/** * Search signal block * * @param owner owner whose signals we are updating * @return SigFlags */ static SigFlags ExploreSegment(Owner owner) { SigFlags flags = SF_NONE; TileIndex tile; DiagDirection enterdir; while (_tbdset.Get(&tile, &enterdir)) { TileIndex oldtile = tile; // tile we are leaving DiagDirection exitdir = enterdir == INVALID_DIAGDIR ? INVALID_DIAGDIR : ReverseDiagDir(enterdir); // expected new exit direction (for straight line) switch (GetTileType(tile)) { case MP_RAILWAY: { if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing) if (IsRailDepot(tile)) { if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; exitdir = GetRailDepotDirection(tile); tile += TileOffsByDiagDir(exitdir); enterdir = ReverseDiagDir(exitdir); break; } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; continue; } else { continue; } } TrackBits tracks = GetTrackBits(tile); // trackbits of tile TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits if (tracks == TRACK_BIT_HORZ || tracks == TRACK_BIT_VERT) { // there is exactly one incidating track, no need to check tracks = tracks_masked; /* If no train detected yet, and there is not no train -> there is a train -> set the flag */ if (!(flags & SF_TRAIN) && EnsureNoTrainOnTrackBits(tile, tracks).Failed()) flags |= SF_TRAIN; } else { if (tracks_masked == TRACK_BIT_NONE) continue; // no incidating track if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; } if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir SignalType sig = GetSignalType(tile, track); Trackdir trackdir = (Trackdir)FindFirstBit((tracks * 0x101) & _enterdir_to_trackdirbits[enterdir]); Trackdir reversedir = ReverseTrackdir(trackdir); /* add (tile, reversetrackdir) to 'to-be-updated' set when there is * ANY conventional signal in REVERSE direction * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */ if (HasSignalOnTrackdir(tile, reversedir)) { if (IsPbsSignal(sig)) { flags |= SF_PBS; } else if (!_tbuset.Add(tile, reversedir)) { return flags | SF_FULL; } } if (HasSignalOnTrackdir(tile, trackdir) && !IsOnewaySignal(tile, track)) flags |= SF_PBS; /* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */ if (!(flags & SF_GREEN2) && IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit if (flags & SF_EXIT) flags |= SF_EXIT2; // found two (or more) exits flags |= SF_EXIT; // found at least one exit - allow for compiler optimizations if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) { // found green presignal exit if (flags & SF_GREEN) flags |= SF_GREEN2; flags |= SF_GREEN; } } continue; } } for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { // test all possible exit directions if (dir != enterdir && (tracks & _enterdir_to_trackbits[dir])) { // any track incidating? TileIndex newtile = tile + TileOffsByDiagDir(dir); // new tile to check DiagDirection newdir = ReverseDiagDir(dir); // direction we are entering from if (!MaybeAddToTodoSet(newtile, newdir, tile, dir)) return flags | SF_FULL; } } continue; // continue the while() loop } case MP_STATION: if (!HasStationRail(tile)) continue; if (GetTileOwner(tile) != owner) continue; if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; tile += TileOffsByDiagDir(exitdir); break; case MP_ROAD: if (!IsLevelCrossing(tile)) continue; if (GetTileOwner(tile) != owner) continue; if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; tile += TileOffsByDiagDir(exitdir); break; case MP_TUNNELBRIDGE: { if (GetTileOwner(tile) != owner) continue; if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue; DiagDirection dir = GetTunnelBridgeDirection(tile); if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; enterdir = dir; exitdir = ReverseDiagDir(dir); tile += TileOffsByDiagDir(exitdir); // just skip to next tile } else { // NOT incoming from the wormhole! if (ReverseDiagDir(enterdir) != dir) continue; if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile enterdir = INVALID_DIAGDIR; exitdir = INVALID_DIAGDIR; } } break; default: continue; // continue the while() loop } if (!MaybeAddToTodoSet(tile, enterdir, oldtile, exitdir)) return flags | SF_FULL; } return flags; }
static void PollEvent() { poll_mouse(); bool mouse_action = false; /* Mouse buttons */ static int prev_button_state; if (prev_button_state != mouse_b) { uint diff = prev_button_state ^ mouse_b; while (diff != 0) { uint button = FindFirstBit(diff); ClrBit(diff, button); if (HasBit(mouse_b, button)) { /* Pressed mouse button */ if (_rightclick_emulate && (key_shifts & KB_CTRL_FLAG)) { button = RIGHT_BUTTON; ClrBit(diff, RIGHT_BUTTON); } switch (button) { case LEFT_BUTTON: _left_button_down = true; break; case RIGHT_BUTTON: _right_button_down = true; _right_button_clicked = true; break; default: /* ignore rest */ break; } } else { /* Released mouse button */ if (_rightclick_emulate) { _right_button_down = false; _left_button_down = false; _left_button_clicked = false; } else if (button == LEFT_BUTTON) { _left_button_down = false; _left_button_clicked = false; } else if (button == RIGHT_BUTTON) { _right_button_down = false; } } } prev_button_state = mouse_b; mouse_action = true; } /* Mouse movement */ int dx = mouse_x - _cursor.pos.x; int dy = mouse_y - _cursor.pos.y; if (dx != 0 || dy != 0) { if (_cursor.fix_at) { _cursor.delta.x = dx; _cursor.delta.y = dy; position_mouse(_cursor.pos.x, _cursor.pos.y); } else { _cursor.delta.x = dx; _cursor.delta.y = dy; _cursor.pos.x = mouse_x; _cursor.pos.y = mouse_y; _cursor.dirty = true; } mouse_action = true; } static int prev_mouse_z = 0; if (prev_mouse_z != mouse_z) { _cursor.wheel = (prev_mouse_z - mouse_z) < 0 ? -1 : 1; prev_mouse_z = mouse_z; mouse_action = true; } if (mouse_action) HandleMouseEvents(); poll_keyboard(); if ((key_shifts & KB_ALT_FLAG) && (key[KEY_ENTER] || key[KEY_F])) { ToggleFullScreen(!_fullscreen); } else if (keypressed()) { WChar character; uint keycode = ConvertAllegroKeyIntoMy(&character); HandleKeypress(keycode, character); } }