diff --git a/src/house.h b/src/house.h --- a/src/house.h +++ b/src/house.h @@ -122,14 +122,12 @@ struct HouseSpec { */ Money GetRemovalCost() const; + static FORCEINLINE HouseSpec *Get(size_t house_id) + { + assert(house_id < HOUSE_MAX); + extern HouseSpec _house_specs[]; + return &_house_specs[house_id]; + } }; -extern HouseSpec _house_specs[]; - -static inline HouseSpec *GetHouseSpecs(HouseID house_id) -{ - assert(house_id < HOUSE_MAX); - return &_house_specs[house_id]; -} - #endif /* HOUSE_H */ diff --git a/src/newgrf.cpp b/src/newgrf.cpp --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -41,6 +41,7 @@ #include "map_func.h" #include #include "core/alloc_type.hpp" +#include "core/mem_func.hpp" #include "table/strings.h" #include "table/build_industry.h" @@ -1473,7 +1474,7 @@ static ChangeInfoResult TownHouseChangeI if (subs_id == 0xFF) { /* Instead of defining a new house, a substitute house id * of 0xFF disables the old house with the current id. */ - _house_specs[hid + i].enabled = false; + HouseSpec::Get(hid + i)->enabled = false; continue; } else if (subs_id >= NEW_HOUSE_OFFSET) { /* The substitute id must be one of the original houses. */ @@ -1486,7 +1487,7 @@ static ChangeInfoResult TownHouseChangeI housespec = *house; - memcpy(housespec, &_house_specs[subs_id], sizeof(_house_specs[subs_id])); + MemCpyT(housespec, HouseSpec::Get(subs_id)); housespec->enabled = true; housespec->local_id = hid + i; @@ -5826,7 +5827,7 @@ static void FinaliseHouseArray() if (min_year != 0) { for (int i = 0; i < HOUSE_MAX; i++) { - HouseSpec *hs = GetHouseSpecs(i); + HouseSpec *hs = HouseSpec::Get(i); if (hs->enabled && hs->min_year == min_year) hs->min_year = 0; } diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -12,6 +12,7 @@ #include "newgrf_commons.h" #include "station_map.h" #include "tree_map.h" +#include "core/mem_func.hpp" /** Constructor of generic class * @param offset end of original data for this entity. i.e: houses = 110 @@ -146,11 +147,11 @@ void HouseOverrideManager::SetEntitySpec return; } - memcpy(&_house_specs[house_id], hs, sizeof(*hs)); + MemCpyT(HouseSpec::Get(house_id), hs); /* Now add the overrides. */ for (int i = 0; i != max_offset; i++) { - HouseSpec *overridden_hs = GetHouseSpecs(i); + HouseSpec *overridden_hs = HouseSpec::Get(i); if (entity_overrides[i] != hs->local_id || grfid_overrides[i] != hs->grffile->grfid) continue; diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -58,7 +58,7 @@ void InitializeBuildingCounts() */ void IncreaseBuildingCount(Town *t, HouseID house_id) { - HouseClassID class_id = GetHouseSpecs(house_id)->class_id; + HouseClassID class_id = HouseSpec::Get(house_id)->class_id; if (!_loaded_newgrf_features.has_newhouses) return; @@ -79,7 +79,7 @@ void IncreaseBuildingCount(Town *t, Hous */ void DecreaseBuildingCount(Town *t, HouseID house_id) { - HouseClassID class_id = GetHouseSpecs(house_id)->class_id; + HouseClassID class_id = HouseSpec::Get(house_id)->class_id; if (!_loaded_newgrf_features.has_newhouses) return; @@ -113,7 +113,7 @@ static void HouseSetTriggers(const Resol static uint32 GetNumHouses(HouseID house_id, const Town *town) { uint8 map_id_count, town_id_count, map_class_count, town_class_count; - HouseClassID class_id = GetHouseSpecs(house_id)->class_id; + HouseClassID class_id = HouseSpec::Get(house_id)->class_id; map_id_count = ClampU(_building_counts.id_count[house_id], 0, 255); map_class_count = ClampU(_building_counts.class_count[class_id], 0, 255); @@ -144,7 +144,7 @@ static bool SearchNearbyHouseID(TileInde { if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); if (hs->grffile != NULL) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; @@ -167,7 +167,7 @@ static bool SearchNearbyHouseClass(TileI { if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); if (hs->grffile != NULL) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; @@ -190,7 +190,7 @@ static bool SearchNearbyHouseGRFID(TileI { if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); if (hs->grffile != NULL) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; @@ -226,7 +226,7 @@ static uint32 GetDistanceFromNearbyHouse if (searchradius < 1) return 0; // do not use a too low radius SearchNearbyHouseData nbhd; - nbhd.hs = GetHouseSpecs(house); + nbhd.hs = HouseSpec::Get(house); nbhd.north_tile = tile + GetHouseNorthPart(house); // modifies 'house'! /* Use a pointer for the tile to start the search. Will be required for calculating the distance*/ @@ -281,7 +281,7 @@ static uint32 HouseGetVariable(const Res /* Building counts for new houses with id = parameter. */ case 0x61: { - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); if (hs->grffile == NULL) return 0; HouseID new_house = _house_mngr.GetID(parameter, hs->grffile->grfid); @@ -341,7 +341,7 @@ static void NewHouseResolver(ResolverObj res->reseed = 0; res->count = 0; - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); res->grffile = (hs != NULL ? hs->grffile : NULL); } @@ -355,7 +355,7 @@ uint16 GetHouseCallback(CallbackID callb object.callback_param1 = param1; object.callback_param2 = param2; - group = SpriteGroup::Resolve(GetHouseSpecs(house_id)->spritegroup, &object); + group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->spritegroup, &object); if (group == NULL) return CALLBACK_FAILED; return group->GetCallbackResult(); @@ -366,7 +366,7 @@ static void DrawTileLayout(const TileInf const DrawTileSprites *dts = group->dts; const DrawTileSeqStruct *dtss; - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); SpriteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START; if (HasBit(hs->callback_mask, CBM_HOUSE_COLOUR)) { uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile); @@ -415,7 +415,7 @@ static void DrawTileLayout(const TileInf void DrawNewHouseTile(TileInfo *ti, HouseID house_id) { - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); const SpriteGroup *group; ResolverObject object; @@ -438,7 +438,7 @@ void DrawNewHouseTile(TileInfo *ti, Hous void AnimateNewHouseTile(TileIndex tile) { - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); byte animation_speed = hs->animation_speed; bool frame_set_by_callback = false; @@ -516,7 +516,7 @@ void ChangeHouseAnimationFrame(const GRF bool CanDeleteHouse(TileIndex tile) { - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); /* Humans are always allowed to remove buildings, as is water and * anyone using the scenario editor. */ @@ -534,7 +534,7 @@ bool CanDeleteHouse(TileIndex tile) static void AnimationControl(TileIndex tile, uint16 random_bits) { - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) { uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random(); @@ -546,7 +546,7 @@ static void AnimationControl(TileIndex t bool NewHouseTileLoop(TileIndex tile) { - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); if (GetHouseProcessingTime(tile) > 0) { DecHouseProcessingTime(tile); @@ -594,7 +594,7 @@ static void DoTriggerHouse(TileIndex til assert(IsTileType(tile, MP_HOUSE)); HouseID hid = GetHouseType(tile); - HouseSpec *hs = GetHouseSpecs(hid); + HouseSpec *hs = HouseSpec::Get(hid); if (hs->spritegroup == NULL) return; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -35,7 +35,7 @@ void UpdateHousesAndTowns() if (!IsTileType(t, MP_HOUSE)) continue; house_id = GetHouseType(t); - if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { + if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { /* The specs for this type of house are not available any more, so * replace it with the substitute original house type. */ house_id = _house_mngr.GetSubstituteID(house_id); @@ -44,7 +44,7 @@ void UpdateHousesAndTowns() town = Town::GetByTile(t); IncreaseBuildingCount(town, house_id); - if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population; + if (IsHouseCompleted(t)) town->population += HouseSpec::Get(house_id)->population; /* Increase the number of houses for every house, but only once. */ if (GetHouseNorthPart(house_id) == 0) town->num_houses++; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -48,8 +48,6 @@ #include "table/strings.h" #include "table/town_land.h" -HouseSpec _house_specs[HOUSE_MAX]; - Town *_cleared_town; int _cleared_town_rating; @@ -171,11 +169,11 @@ static void DrawTile_Town(TileInfo *ti) /* Houses don't necessarily need new graphics. If they don't have a * spritegroup associated with them, then the sprite for the substitute * house id is drawn instead. */ - if (GetHouseSpecs(house_id)->spritegroup != NULL) { + if (HouseSpec::Get(house_id)->spritegroup != NULL) { DrawNewHouseTile(ti, house_id); return; } else { - house_id = GetHouseSpecs(house_id)->substitute_id; + house_id = HouseSpec::Get(house_id)->substitute_id; } } @@ -242,7 +240,7 @@ static void AnimateTile_Town(TileIndex t * Not exactly sure when this happens, but probably when a house changes. * Before this was just a return...so it'd leak animated tiles.. * That bug seems to have been here since day 1?? */ - if (!(GetHouseSpecs(GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) { + if (!(HouseSpec::Get(GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) { DeleteAnimatedTile(tile); return; } @@ -376,7 +374,7 @@ static void MakeSingleHouseBigger(TileIn IncHouseConstructionTick(tile); if (GetHouseConstructionTick(tile) != 0) return; - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); /* Check and/or */ if (HasBit(hs->callback_mask, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE)) { @@ -398,7 +396,7 @@ static void MakeSingleHouseBigger(TileIn */ static void MakeTownHouseBigger(TileIndex tile) { - uint flags = GetHouseSpecs(GetHouseType(tile))->building_flags; + uint flags = HouseSpec::Get(GetHouseType(tile))->building_flags; if (flags & BUILDING_HAS_1_TILE) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0)); if (flags & BUILDING_2_TILES_Y) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1)); if (flags & BUILDING_2_TILES_X) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0)); @@ -425,7 +423,7 @@ static void TileLoop_Town(TileIndex tile return; } - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); /* If the lift has a destination, it is already an animated tile. */ if ((hs->building_flags & BUILDING_IS_ANIMATED) && @@ -509,7 +507,7 @@ static CommandCost ClearTile_Town(TileIn if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED); if (!CanDeleteHouse(tile)) return CMD_ERROR; - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); CommandCost cost(EXPENSES_CONSTRUCTION); cost.AddCost(hs->GetRemovalCost()); @@ -536,7 +534,7 @@ static CommandCost ClearTile_Town(TileIn static void GetProducedCargo_Town(TileIndex tile, CargoID *b) { HouseID house_id = GetHouseType(tile); - const HouseSpec *hs = GetHouseSpecs(house_id); + const HouseSpec *hs = HouseSpec::Get(house_id); Town *t = Town::GetByTile(tile); if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) { @@ -562,7 +560,7 @@ static void GetProducedCargo_Town(TileIn static void AddAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac) { - const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); CargoID accepts[3]; /* Set the initial accepted cargo types */ @@ -606,7 +604,7 @@ static void AddAcceptedCargo_Town(TileIn static void GetTileDesc_Town(TileIndex tile, TileDesc *td) { const HouseID house = GetHouseType(tile); - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); bool house_completed = IsHouseCompleted(tile); td->str = hs->building_name; @@ -1803,7 +1801,7 @@ static inline void ClearMakeHouseTile(Ti IncreaseBuildingCount(t, type); MakeHouseTile(tile, t->index, counter, stage, type, random_bits); - if (GetHouseSpecs(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(tile); + if (HouseSpec::Get(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(tile); MarkTileDirtyByTile(tile); } @@ -1821,7 +1819,7 @@ static inline void ClearMakeHouseTile(Ti */ static void MakeTownHouse(TileIndex t, Town *town, byte counter, byte stage, HouseID type, byte random_bits) { - BuildingFlags size = GetHouseSpecs(type)->building_flags; + BuildingFlags size = HouseSpec::Get(type)->building_flags; ClearMakeHouseTile(t, town, counter, stage, type, random_bits); if (size & BUILDING_2_TILES_Y) ClearMakeHouseTile(t + TileDiffXY(0, 1), town, counter, stage, ++type, random_bits); @@ -2051,7 +2049,7 @@ static bool BuildTownHouse(Town *t, Tile /* Generate a list of all possible houses that can be built. */ for (uint i = 0; i < HOUSE_MAX; i++) { - const HouseSpec *hs = GetHouseSpecs(i); + const HouseSpec *hs = HouseSpec::Get(i); /* Verify that the candidate house spec matches the current tile status */ if ((~hs->building_availability & bitmask) != 0 || !hs->enabled) continue; @@ -2090,12 +2088,12 @@ static bool BuildTownHouse(Town *t, Tile houses[i] = houses[num]; probs[i] = probs[num]; - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); if (_loaded_newgrf_features.has_newhouses) { if (hs->override != 0) { house = hs->override; - hs = GetHouseSpecs(house); + hs = HouseSpec::Get(house); } if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world && _game_mode != GM_EDITOR) continue; @@ -2187,16 +2185,16 @@ static void DoClearTownHouseHelper(TileI TileIndexDiff GetHouseNorthPart(HouseID &house) { if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks. - if (GetHouseSpecs(house - 1)->building_flags & TILE_SIZE_2x1) { + if (HouseSpec::Get(house - 1)->building_flags & TILE_SIZE_2x1) { house--; return TileDiffXY(-1, 0); - } else if (GetHouseSpecs(house - 1)->building_flags & BUILDING_2_TILES_Y) { + } else if (HouseSpec::Get(house - 1)->building_flags & BUILDING_2_TILES_Y) { house--; return TileDiffXY(0, -1); - } else if (GetHouseSpecs(house - 2)->building_flags & BUILDING_HAS_4_TILES) { + } else if (HouseSpec::Get(house - 2)->building_flags & BUILDING_HAS_4_TILES) { house -= 2; return TileDiffXY(-1, 0); - } else if (GetHouseSpecs(house - 3)->building_flags & BUILDING_HAS_4_TILES) { + } else if (HouseSpec::Get(house - 3)->building_flags & BUILDING_HAS_4_TILES) { house -= 3; return TileDiffXY(-1, -1); } @@ -2213,7 +2211,7 @@ void ClearTownHouse(Town *t, TileIndex t /* need to align the tile to point to the upper left corner of the house */ tile += GetHouseNorthPart(house); // modifies house to the ID of the north tile - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); /* Remove population from the town if the house is finished. */ if (IsHouseCompleted(tile)) { @@ -2859,7 +2857,7 @@ static CommandCost TerraformTile_Town(Ti if (AutoslopeEnabled()) { HouseID house = GetHouseType(tile); GetHouseNorthPart(house); // modifies house to the ID of the north tile - const HouseSpec *hs = GetHouseSpecs(house); + const HouseSpec *hs = HouseSpec::Get(house); /* Here we differ from TTDP by checking TILE_NOT_SLOPED */ if (((hs->building_flags & TILE_NOT_SLOPED) == 0) && !IsSteepSlope(tileh_new) && @@ -2887,6 +2885,9 @@ extern const TileTypeProcs _tile_type_to TerraformTile_Town, // terraform_tile_proc }; + +HouseSpec _house_specs[HOUSE_MAX]; + void ResetHouses() { memset(&_house_specs, 0, sizeof(_house_specs)); diff --git a/src/town_map.h b/src/town_map.h --- a/src/town_map.h +++ b/src/town_map.h @@ -193,7 +193,7 @@ static inline void MakeHouseTile(TileInd SetHouseCompleted(t, stage == TOWN_HOUSE_COMPLETED); _m[t].m5 = IsHouseCompleted(t) ? 0 : (stage << 3 | counter); SetHouseAnimationFrame(t, 0); - _me[t].m7 = GetHouseSpecs(type)->processing_time; + _me[t].m7 = HouseSpec::Get(type)->processing_time; } /**